Closed FaustPipeDream closed 3 years ago
How are you instantiating TerminalControlViewModel?
On 2 November 2020 07:53:59 GMT, FaustPipeDream notifications@github.com wrote:
I have a service named TerminalModelService and registere it in Bootstrapper.cs in method ConfigureIoC:
public class Bootstrapper : Bootstrapper<RootViewModel>{ ... protected override void ConfigureIoC(IStyletIoCBuilder builder) { builder.Bind<TerminalModelService>().ToSelf(); } ... }
and user it in :
public class TerminalControlViewModel : Screen { [Inject] TerminalModelService TerminalModelService { get; set; } .... public void DoConfirm() { TerminalModelService.SaveTerminalModel.dosomething(); } }
But TerminalModelService not inject and return null,I think I user it wrong way, How to inject Service ? Is there any StyletIoC sample ?
-- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/canton7/Stylet/issues/164
How are you instantiating TerminalControlViewModel? … On 2 November 2020 07:53:59 GMT, FaustPipeDream @.***> wrote: I have a service named TerminalModelService and registere it in Bootstrapper.cs in method ConfigureIoC:
public class Bootstrapper : Bootstrapper<RootViewModel>{ ... protected override void ConfigureIoC(IStyletIoCBuilder builder) { builder.Bind<TerminalModelService>().ToSelf(); } ... }
and user it in :public class TerminalControlViewModel : Screen { [Inject] TerminalModelService TerminalModelService { get; set; } .... public void DoConfirm() { TerminalModelService.SaveTerminalModel.dosomething(); } }
But TerminalModelService not inject and return null,I think I user it wrong way, How to inject Service ? Is there any StyletIoC sample ? -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: #164
I instantiated TerminalControlViewModel in RootViewModel by a command
public class RootViewModel : Conductor<IScreen>.Collection.OneActive
{
...
public void DoShowTerminalControl()
{
TerminalControlViewModel TerminalControlViewModel = new TerminalControlViewModel();
WindowManager.ShowWindow(TerminalControlViewModel);
}
}
and bind it to a button:
<Button Header="new Terminal" Command="{s:Action DoShowTerminalControl}"/>
IoC containers aren't magic -- there's no way for it to insert itself into your code and populate properties on TerminalControlViewModel
after you instantiate it.
The normal pattern is to let the IoC container create TerminalControlViewModel
as well:
public class RootViewModel : Conductor<IScreen>.Collection.OneActive
{
private readonly Func<TerminalControlViewModel> factory;
public RootViewMode(Func<TerminalControlViewModel> factory) => this.factory = factory;
...
public void DoShowTerminalControl()
{
TerminalControlViewModel TerminalControlViewModel = factory();
WindowManager.ShowWindow(TerminalControlViewModel);
}
}
You can also use IContainer.BuildUp
, but that's less common.
a Thank you,It works, So the normal pattern to instantiate a viewModel is getting it by Func.I see.
That's the case where you need to be able to create multiple instances of it. If you just need 1 instance, you can do:
public class RootViewModel : Conductor<IScreen>.Collection.OneActive
{
private readonly TerminalControlViewModel terminalControlVm;
public RootViewMode(TerminalControlViewModel terminalControlVm) => this.terminalControlVm= terminalControlVm;
...
public void DoShowTerminalControl()
{
WindowManager.ShowWindow(terminalControlVm);
}
}
This is the case in almost every IoC container
I’m sorry but i have another problem,In TerminalViewModel
,there is a BindableCollection<TerminalTreeNode>TerminalTreeNodes
,and I want to share it with TerminalControlViewModel
,so that I can change the TerminalTreeNodes in TerminalControlViewModel
.
Usually,it can be realized by share one TerminalTreeNodes instance like
public class TerminalControlViewModel : Screen
{
public BindableCollection<TerminalTreeNode> TerminalTreeNodes { get; set; } = new BindableCollection<TerminalTreeNode>();
public TerminalControlViewModel(BindableCollection<TerminalTreeNode> terminalTreeNodes)
{
TerminalTreeNodes = terminalTreeNodes;
}
}
public class TerminalViewModel : Screen
{
public BindableCollection<TerminalTreeNode> TerminalTreeNodes { get; set; } = new BindableCollection<TerminalTreeNode>();
public TerminalViewModel()
{
TerminalTreeNodes.addsomething();
}
}
public class RootViewModel : Conductor<IScreen>.Collection.OneActive
{
private readonly Func<BindableCollection<TerminalTreeNode>,TerminalControlViewModel> Factory;
private TerminalViewModel TerminalViewModel { get; set; }
.....
public RootViewMode(TerminalViewModel terminalViewModel,Func<BindableCollection<TerminalTreeNode>,TerminalControlViewModel> factory)
{
TerminalViewModel = terminalViewModel;
Factory = factory;
}
...
public void DoShowTerminalControl()
{
TerminalControlViewModel TerminalControlViewModel = factory(TerminalViewModel.TerminalTreeNodes);
WindowManager.ShowWindow(TerminalControlViewModel);
}
}
But it doesn't work,and I found /issues/153 ,StyletIoC can't create factories which take arbitrary parameters. So how one viewModel sharing one TerminalTreeNodes with another? Should I use other IOC Container?
You can use another ioc container which does support auto-generating factories which take arbitrary parameters, or you can write your own factory class. I tend to write my own factory class.
I have a service named TerminalModelService and registere it in Bootstrapper.cs in method ConfigureIoC:
and user it in :
But TerminalModelService not inject and return null,I think I use it wrong way, How to inject Service ? Is there any StyletIoC sample ?