I sometimes use Caliburn.Micro to create applications.
Using the simplest BootStrapper, I can use IoC container (SimpleContainer) like this:
private SimpleContainer _container = new SimpleContainer();
protected override object GetInstance(Type serviceType, string key) {
return _container.GetInstance(serviceType, key);
}
protected override IEnumerable<object> GetAllInstances(Type serviceType) {
return _container.GetAllInstances(serviceType);
}
protected override void BuildUp(object instance) {
_container.BuildUp(instance);
}
So in the Configure
method I can add and register my ViewModels like this:
container.PerRequest<MyMainViewModel>();
My ViewModel's constructor can have a parameter that is injected by the IoC container when requested:
public MyMainViewModel(IWindowManager windowManager)
{
//do the init
}
It works as expected, when I call DisplayRootViewFor<MyMainViewModel>()
But what happens, if I intend to create some more logic and use a Conductor?
In the examples, the authors use a simple, IoC-free implementation for "convenience":
In order to keep this sample as simple as possible, I’m not even using an IoC container with the Bootstrapper. Let’s look at the ShellViewModel first. It inherits from Conductor and is implemented as follows:
public class ShellViewModel : Conductor<object> { public ShellViewModel() { ShowPageOne(); } public void ShowPageOne() { ActivateItem(new PageOneViewModel()); } public void ShowPageTwo() { ActivateItem(new PageTwoViewModel()); } }
So they instantiate the ViewModels, instead of requesting an instance from the IoC container.
What would be the proper use of Dependency Injection in this case?
I have another ViewModel that has a constructor like this:
public MySecondViewModel(MyParamClass input)
{
//do the work
}
Should I modify the code like this:
In the Configure
method:
simpleContainer.PerRequest<MyParamClass>(); //How could it be different every time?
In the conductor:
public void ShowPageOne()
{
ActivateItem(IoC.Get<MySecondViewModel>());
}
Also, is this allowed or it violates the rules of DI:
protected override object GetInstance(Type serviceType, string key)
{
if(serviceType==typeof(MySecondViewModel))
return new MySecondViewModel(new MyParamClass(2));
return _container.GetInstance(serviceType, key);
}
I can see that using DI, the ViewModels should be provided by the IoC container and not created manually (not to mention the required parameter - which is inside the container).
So can you give some hint how to implement the IoC pattern with conductors?
Func<T>
ifT
is registered. If that's the case with your container, you could use is for DI yet still only instantiate the viewmodel when it's actually required. – Chickadee