Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 为什么要使用依赖项注入容器?_Wpf_Design Patterns_Dependency Injection_Composition - Fatal编程技术网

Wpf 为什么要使用依赖项注入容器?

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

我已经完成了Karl Shiffet的测试,并且发现它是学习WPF的一个极好的资源。它提到的一件事是依赖注入和Unity容器的使用。下面是代码中向我提出一些问题的部分:

公共部分类应用程序:应用程序{
启动时受保护的覆盖无效(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();
    }