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
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();