我有时使用Caliburn.Micro创建应用程序。
使用最简单的BootStrapper,我可以像这样使用IoC容器(SimpleContainer):
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);
}
所以在
Configure
方法中,我可以像这样添加和注册我的ViewModels:container.PerRequest<MyMainViewModel>();
当请求时,我的ViewModel的构造函数可以有一个由IoC容器注入的参数:
public MyMainViewModel(IWindowManager windowManager)
{
//do the init
}
当我调用DisplayRootViewFor<MyMainViewModel>()
时,它按预期工作。
但是,如果我想创建一些更多的逻辑并使用Conductor会发生什么?
在示例中,作者使用了一个简单的、无IoC实现的“方便”方式:
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()); } }
因此,他们实例化ViewModels,而不是从IoC容器请求实例。
在这种情况下,依赖注入的正确使用方式是什么?
我有另一个具有以下构造函数的ViewModel:
public MySecondViewModel(MyParamClass input)
{
//do the work
}
我应该像这样修改代码吗?
在 Configure 方法中:
simpleContainer.PerRequest<MyParamClass>(); //How could it be different every time?
在导体中:
public void ShowPageOne()
{
ActivateItem(IoC.Get<MySecondViewModel>());
}
此外,这种做法是否被允许或违反DI规则:
protected override object GetInstance(Type serviceType, string key)
{
if(serviceType==typeof(MySecondViewModel))
return new MySecondViewModel(new MyParamClass(2));
return _container.GetInstance(serviceType, key);
}
我可以看到使用DI,ViewModels应该由IoC容器提供而不是手动创建(更不用说所需的参数 - 它在容器内部)。
那么你能给一些提示如何使用conductor实现IoC模式吗?
T
已注册的情况下依赖于Func<T>
。如果您的容器是这种情况,您可以将其用于DI,但仍然只有在实际需要时才实例化视图模型。 - Dirk