如何做好莱坞原则+ DI + WPF + Unity

hoe*_*etz 5 wpf dependency-injection unity-container

我现在开始开发一个新的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);
    }
Run Code Online (Sandbox Code Playgroud)

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

    }
Run Code Online (Sandbox Code Playgroud)

现在让我们看一下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);
                });
        });

     }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我只注入了groupRepository以将其传递给LookUpGroupDialogViewModel.我可以将IGroupRepository从ManageUserViewModel的ctr中取出并直接通过容器解析,但我认为这违反了好莱坞原则.我如何在WPF中解析所有依赖项,以便容器调用我?:)

Mar*_*ann 5

它看起来好像你要添加的视图模型_ManagementWorkSpaces必须具有某种常见的抽象(除非集合完全无类型并且只接受任何object) - 我假设这是WorkspaceViewModel类型.

这意味着您可以通过将构造函数更改为如下所示来巧妙地解决您的问题:

public MainWindowViewModel(ObservableCollection<WorkspaceViewModel> workSpaces)
{
    this._ManagementWorkSpaces = workSpaces;
}
Run Code Online (Sandbox Code Playgroud)

让您的Composition Root担心ObservableCollection<WorkspaceViewModel>实例的解析方式.