【发布时间】:2016-04-27 19:58:38
【问题描述】:
我有时使用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 方法中,我可以像这样添加和注册我的 ViewModel:
container.PerRequest<MyMainViewModel>();
我的 ViewModel 的构造函数可以有一个在请求时由 IoC 容器注入的参数:
public MyMainViewModel(IWindowManager windowManager)
{
//do the init
}
当我打电话给DisplayRootViewFor<MyMainViewModel>()时,它按预期工作
但是,如果我打算创建更多逻辑并使用Conductor,会发生什么?
在示例中,作者使用一个简单的、无 IoC 的实现来“方便”:
为了让这个示例尽可能简单,我什至没有使用 带有引导程序的 IoC 容器。让我们看看 首先是 ShellViewModel。它继承自 Conductor 并实现为 如下:
public class ShellViewModel : Conductor<object> { public ShellViewModel() { ShowPageOne(); } public void ShowPageOne() { ActivateItem(new PageOneViewModel()); } public void ShowPageTwo() { ActivateItem(new PageTwoViewModel()); } }
因此他们实例化 ViewModel,而不是从 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,ViewModel 应该由 IoC 容器提供,而不是手动创建(更不用说所需的参数 - 它在容器内)。
那么您能否提供一些提示如何使用导体实现 IoC 模式?
【问题讨论】:
-
我也在寻找解决这个问题的最佳实践......我只能说直接从 IoC 启动 ViewModel 并不好......而且我想它也不太好手动实例化它们(参见:stackoverflow.com/a/17373957/2830676)。我想最好的方法是从构造函数中获取它,但是它的问题是它被实例化得太快了=[
-
如果
T已注册,某些 IoC 容器使您能够依赖Func<T>。如果您的容器是这种情况,您可以将 is 用于 DI,但仍仅在实际需要时实例化视图模型。 -
@Yitzchak 注入工厂委托,允许延迟依赖实例化。查看提交的答案以获取更多详细信息。
标签: c# dependency-injection caliburn.micro