在ViewModel主要的设计缺陷中引入了对DI容器的引用吗?

时间:2013-07-05 18:27:34

标签: c# mvvm dependency-injection

我有以下

  • ViewModels: MainWindowViewModelBaseProjectViewModelTextFileProjectViewModelSpreadsheetProjectViewModel (TextFileProjectViewModel,SpreadsheetProjectViewModel继承自BaseProjectViewModel)

  • 服务:

    FileDIalogService : IFileDialogService
    MessageBoxService : IMessageBoxService
    ModalDialogFactory : IModalDialogFactory
    ModalDialogService : IModalDialogservice

MainWindowViewModel具有以下构造函数:

public MainWindowViewModel( IModalDialogService     modalDialogService,
                            IModalDialogFactory     modalDialogFactory,
                            IMessageBoxService      messageBoxService,
                            IFileDialogService      fileDialogService)
{
    _modalDialogService = modalDialogService;
    _modalDialogFactory = modalDialogFactory;
    _messageBoxService = messageBoxService;
    _fileDialogService = fileDialogService;
}
在App.xaml中

我不使用StartupUri。

目前在App.xaml.cs中我手动执行引导:

    MainWindow mainWindow = new MainWindow();
    mainWindow.DataContext = new MainWindowViewModel(new ModalDialogService(), new ModalDialogFactory(), new MessageBoxService(), new FileDialogService());
    mainWindow.Show();

我知道我可以使用容器(如Unity)来执行:

IUnityContainer container = new UnityContainer();

container.RegisterType<IModalDialogService, ModalDialogService>(new ContainerControlledLifetimeManager());
/* ... and so on for each service interface and its appropriate implementation... */

MainWindow mainWindow = new MainWindow();
mainWindow.DataContext = container.Resolve<MainWindowViewModel>();
mainWindow.Show();

在另一个问题中,我了解到我可以更进一步,将IModalDialogFactory实现为自动工厂并注入......

但是我意识到我错过了一件重要的事情:

当我需要TextFileProjectViewModelSpreadsheetProjectViewModel中正在MainWindowViewModel创建的服务时,我需要手动将引用注入其中。
我从某个地方读到,从设计的角度来看,将容器引入MainWindowViewModel会是一件坏事,因为它会产生不必要的依赖。 但是,我不知道如何使用DI容器(任何,而不仅仅是Unity)来解析MainWindowViewModel内的其他视图模型而不在MainWindowViewModel中保留引用。

我是否遗漏了某些内容,或者我是否犯了设计/架构错误?

1 个答案:

答案 0 :(得分:1)

我提前道歉,因为对xaml空间了解不多,但希望这会有所帮助。

在极端情况下,您必须选择正确DI以外的其他东西。最好的情况通常是构造函数注入。

“严格遵守构造函数注入可以很容易地查看何时违反SRP并且应该重构为Facade服务。” - http://blog.ploeh.dk/2010/02/02/RefactoringtoAggregateServices

对于那些抽象工厂,对DI容器或Service Locator的引用是我能想到的最接近去耦的东西。

Service locator an anti pattern?

那就是说,构建你的ViewModel是什么,你可以将这种依赖性提升到足以使你的DI composition root可用吗?