我已经完成了'InTheBox' WPF Training Karl Shiffet 发现它是学习 WPF 的绝佳资源。它确实带来的一件事是使用依赖注入(inject)和 Unity 容器。这是向我提出一些问题的代码部分:
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
IUnityContainer container = new UnityContainer();
container.RegisterType<IDialogService, ModalDialogService>(
new ContainerControlledLifetimeManager());
container.RegisterType<IEventRepository, EventRepository>(
new ContainerControlledLifetimeManager());
MainWindow window = container.Resolve<MainWindow>();
window.DataContext = container.Resolve<MainWindowViewModel>();
window.Show();
}
}
依赖项被注册到 UnityContainer 中,然后由 UnityContainer 注入(inject)到 MainWindowViewModel 中。我的问题是为什么要使用容器?就依赖注入(inject)而言,为什么不直接使用以下实现相同目的的代码:
protected override void OnStartup(StartupEventArgs e)
{
IDialogService dialogService = new ModalDialogService();
IEventRepository eventRepository = new EventRepository();
MainWindow window = new MainWindow();
window.DataContext =
new MainWindowViewModel(eventRepository, dialogService);
window.Show();
}
我仍在将依赖项从组合根注入(inject)到构造函数中,因此在这种情况下我认为使用 UnityContainer 没有任何好处。
我很欣赏它的存在显然是有原因的,但是有人可以解释在这种情况下它是否会增加任何东西吗?另外,是否还有另一种情况,使用这样的容器真的很容易?
最佳答案
在像这样的简单情况下使用 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();
}
自己做的时候,要加一行代码,修改3行代码。
protected override void OnStartup(StartupEventArgs e)
{
ILoggingService loggingService = new LoggingService(); // added
IDialogService dialogService = new ModalDialogService(loggingService); // modified
IEventRepository eventRepository = new EventRepository(loggingService); // modified
MainWindow window = new MainWindow();
window.DataContext = new MainWindowViewModel(eventRepository, dialogService, loggingService); // modified
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();
}
关于wpf - 为什么要使用依赖注入(inject)容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16958013/