Wpf 为什么要使用依赖项注入容器?
我已经完成了Karl Shiffet的测试,并且发现它是学习WPF的一个极好的资源。它提到的一件事是依赖注入和Unity容器的使用。下面是代码中向我提出一些问题的部分:Wpf 为什么要使用依赖项注入容器?,wpf,design-patterns,dependency-injection,composition,Wpf,Design Patterns,Dependency Injection,Composition,我已经完成了Karl Shiffet的测试,并且发现它是学习WPF的一个极好的资源。它提到的一件事是依赖注入和Unity容器的使用。下面是代码中向我提出一些问题的部分: 公共部分类应用程序:应用程序{ 启动时受保护的覆盖无效(StartupEventArgs e){ IUnityContainer容器=新的UnityContainer(); container.RegisterType( 新的ContainerControlled LifetimeManager()); container.Re
公共部分类应用程序:应用程序{
启动时受保护的覆盖无效(StartupEventArgs e){
IUnityContainer容器=新的UnityContainer();
container.RegisterType(
新的ContainerControlled LifetimeManager());
container.RegisterType(
新的ContainerControlled LifetimeManager());
MainWindow窗口=container.Resolve();
window.DataContext=container.Resolve();
window.Show();
}
}
这些依赖项正在注册到UnityContainer中,然后由UnityContainer注入到MainWindowViewModel中。我的问题是为什么要使用这个容器?就依赖项注入而言,为什么不使用以下代码段来实现相同的功能:
启动时受保护的覆盖无效(StartupEventArgs e)
{
IDialogService dialogService=新的ModalDialogService();
IEventRepository eventRepository=新的eventRepository();
主窗口=新的主窗口();
window.DataContext=
新的MainWindowViewModel(eventRepository,dialogService);
window.Show();
}
我仍在将依赖项从组合根注入构造函数,因此在这种情况下,使用UnityContainer没有任何好处
我明白它的存在显然是有原因的,但有人能解释一下,在这种情况下,它是否增加了什么?另外,还有没有其他情况下像这样使用容器真的是一件很容易的事呢?你说得很好。您的第二个示例是使用Mark Seemann可能称为“穷人的DI”的内容。它仍然是DI,但你自己在做 当您开始管理许多不同类型和功能的注入时,IoC容器就有了自己的功能,例如生活方式管理和按惯例注册类型成为大量的劳动力节省者 正如您所建议的那样,对于依赖关系管理最少的较小任务,它们可能有些过分
如果你想了解更多,我强烈推荐希曼的书和博客。嗯,他比任何人都能更好地解释这个主题。在这样一个简单的案例中使用DI容器对您来说并没有多大帮助。当事情变得更复杂时,它开始变得更有意义,并且它还最小化了依赖关系更改的影响 比如说,您有一个ILoggingService,您的所有依赖项现在都在使用它。当使用Unity这样的DI容器时,只需添加一行代码
protected override void OnStartup(StartupEventArgs e)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IDialogService, ModalDialogService>();
container.RegisterType<IEventRepository, EventRepository>();
container.RegisterType<ILoggingService, LoggingService>(); // added
MainWindow window = container.Resolve<MainWindow>();
window.DataContext = container.Resolve<MainWindowViewModel>();
window.Show();
}
当使用可以扫描要注册的类型的更高级容器时,您可能不需要更改组合根中的任何代码。下面是一个使用AutoFac的示例
protected override void OnStartup(StartupEventArgs e)
{
var builder = new ContainerBuilder();
var assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.AsSelf()
.AsImplementedInterfaces();
var container = builder.Build();
MainWindow window = container.Resolve<MainWindow>();
window.DataContext = container.Resolve<MainWindowViewModel>();
window.Show();
}
启动时受保护的覆盖无效(StartupEventArgs e)
{
var builder=new ContainerBuilder();
var assembly=assembly.getExecutionGassembly();
builder.RegisterAssemblyTypes(程序集)
.AsSelf()
.a实现接口();
var container=builder.Build();
MainWindow窗口=container.Resolve();
window.DataContext=container.Resolve();
window.Show();
}
感谢您提供的附加示例,该示例演示了容器在引入新依赖项时如何不允许代码更改。感谢您花时间回答,在考虑扩展依赖项注入方法时,我将阅读Seemann的书。我还推荐这本书。我还没有完成,但我读过的部分很有帮助。
protected override void OnStartup(StartupEventArgs e)
{
var builder = new ContainerBuilder();
var assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.AsSelf()
.AsImplementedInterfaces();
var container = builder.Build();
MainWindow window = container.Resolve<MainWindow>();
window.DataContext = container.Resolve<MainWindowViewModel>();
window.Show();
}