C# 在主视图模型中引入对DI容器的引用是设计缺陷吗?

C# 在主视图模型中引入对DI容器的引用是设计缺陷吗?,c#,mvvm,dependency-injection,C#,Mvvm,Dependency Injection,我有以下几点 视图模型:主窗口视图模型,基本项目视图模型,文本文件项目视图模型,电子表格项目视图模型 (TextFileProjectViewModel、SpreadsheetProjectViewModel继承自BaseProjectViewModel) 服务: FileDIalogService:IFileDialogService MessageBoxService:IMessageBoxService ModalDialogFactory:IModalDialogFactory Mod

我有以下几点

  • 视图模型:
    主窗口视图模型
    基本项目视图模型
    文本文件项目视图模型
    电子表格项目视图模型
    (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=newunitycontainer();
RegisterType(新的ContainerControlledLifetimeManager());
/* ... 等等,以了解每个服务接口及其相应的实现*/
MainWindow MainWindow=新的MainWindow();
mainWindow.DataContext=container.Resolve();
mainWindow.Show();
在另一个问题中,我了解到我可以更进一步,将IModalDialogFactory实现为一个汽车工厂并注入

然而,我意识到我错过了一件重要的事情:

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


我是否遗漏了什么,或者我是否犯了设计/架构错误

我为自己对xaml空间了解不多而提前道歉,但希望这能有所帮助

在某些情况下,您必须选择适当的DI以外的内容。最好的情况通常是构造函数注入

“严格遵守构造函数注入可以很容易地看出何时违反了SRP,何时应该重构为Facade服务。”

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


也就是说,是什么构造了您的
ViewModel
,您能否将依赖关系提升到足够高的程度,从而使您的视图可用?

依赖关系注入总是存在一些极端情况。我们通常使用静态属性,可以从库/应用程序访问,并引用容器。否则,您的ViewModelA将需要在其自己的类中包含其引用的视图模型的可注入属性(等等),这将导致更复杂的情况。要么就是这样,要么就是有一种
ViewModelLocator
服务,您可以将它传递给类型,并负责创建带有所有注入依赖项的ViewModel。我的ViewModels是在MainWindowViewModel中构建的(我有一个可固定的“MDI”)。MainWindowVM是在OnStartup()方法的App.xaml.cs中构造的(如OP中所述)。App.OnStartup()方法也是我的合成根我认为构建我的ViewModels(MainWindowVM)的依赖关系已经被推到了合成根中我不知道你所说的DI组合根可用是什么意思我需要更多的时间来思考你的答案,因为我有点困惑,我正在处理应用程序atm的不同部分。也许你的编辑会澄清一些事情,如果不是,我会更新或评论。
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();