如何做到好莱坞原则+ DI + WPF +统一
我目前正在开始开发一个新的 WPF 应用程序,其中我使用 Unity 作为 DI 容器。截至目前,我在 App.xaml.cs 中进行像这样的 DI
protected override void OnStartup(StartupEventArgs e)
{
var container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
container = (UnityContainer)section.Configure(container);
WPFUnityContainer.Instance = container;
var mainwindow = new MainWindow();
var mainmodel = container.Resolve<ViewModel.MainWindowViewModel>();
mainwindow.DataContext = mainmodel;
mainwindow.Show();
base.OnStartup(e);
}
MainWindowViewModel 的 ctr 如下所示:
public MainWindowViewModel(IUserRepository userRepository, IGroupRepository groupRepository)
{
this._ManagementWorkSpaces = new ObservableCollection<WorkspaceViewModel>();
this._ManagementWorkSpaces.Add(new ManageApplicationsViewModel());
this._ManagementWorkSpaces.Add(new ManageUserViewModel(userRepository, groupRepository));
}
现在让我们看一下 ManageUserViewModel:
public ManageUserViewModel(IUserRepository userRepository, IGroupRepository groupRepository)
{...
this._ManageGroupsCommand = new DelegateCommand(() =>
{
LookupGroupDialogViewModel vm=new LookupGroupDialogViewModel(groupRepository);
View.LookupGroupDialogWindow vw=new View.LookupGroupDialogWindow();
ModalDialogService.Service.ShowDialog(vw, vm, returnedVM =>
{
if (returnedVM.SelectedGroup!=null)
this.SelectedUser.Groups.Add(returnedVM.SelectedGroup);
});
});
}
如您所见,我注入 groupRepository 只是为了将其传递给LookUpGroupDialogViewModel。我可以将 IGroupRepository 排除在 ManageUserViewModel 的 ctr 之外,并直接通过容器解析它,但我认为这违反了好莱坞原则。在 WPF 中,如何解析所有依赖项以便容器调用我? :)
I'm currently starting with the development of a new WPF application where I use Unity as a DI container. As of now, I'm doing DI like this in the App.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
var container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
container = (UnityContainer)section.Configure(container);
WPFUnityContainer.Instance = container;
var mainwindow = new MainWindow();
var mainmodel = container.Resolve<ViewModel.MainWindowViewModel>();
mainwindow.DataContext = mainmodel;
mainwindow.Show();
base.OnStartup(e);
}
The MainWindowViewModel's ctr looks like this:
public MainWindowViewModel(IUserRepository userRepository, IGroupRepository groupRepository)
{
this._ManagementWorkSpaces = new ObservableCollection<WorkspaceViewModel>();
this._ManagementWorkSpaces.Add(new ManageApplicationsViewModel());
this._ManagementWorkSpaces.Add(new ManageUserViewModel(userRepository, groupRepository));
}
Now let's have a look at the ManageUserViewModel:
public ManageUserViewModel(IUserRepository userRepository, IGroupRepository groupRepository)
{...
this._ManageGroupsCommand = new DelegateCommand(() =>
{
LookupGroupDialogViewModel vm=new LookupGroupDialogViewModel(groupRepository);
View.LookupGroupDialogWindow vw=new View.LookupGroupDialogWindow();
ModalDialogService.Service.ShowDialog(vw, vm, returnedVM =>
{
if (returnedVM.SelectedGroup!=null)
this.SelectedUser.Groups.Add(returnedVM.SelectedGroup);
});
});
}
As you can see I'm injecting the groupRepository only to pass it on to the LookUpGroupDialogViewModel. I could leave the IGroupRepository out of the ManageUserViewModel's ctr and resolve it directly through the container but I think that violates the hollywood principle. How can I, in WPF, resolve all my dependencies so that the container calls me ? :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在我看来,您添加到
_ManagementWorkSpaces
的视图模型必须具有某种通用抽象(除非该集合完全无类型并且仅接受任何对象
) -我假设这是WorkspaceViewModel
类型。这意味着您可以通过将构造函数更改为如下所示来巧妙地解决您的问题:
让您的 Composition Root 关心
ObservableCollection
实例如何解析。It looks to me as if the View Models you are adding to the
_ManagementWorkSpaces
must have some sort of common abstraction (unless the collection is completely untyped and simply accepts anyobject
) - I'm assuming that this is theWorkspaceViewModel
type.This means that you can neatly solve your problem by changing the constructor to look like this:
Let your Composition Root worry about how the
ObservableCollection<WorkspaceViewModel>
instance is resolved.