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

时间:2011-08-31 08:09:55

标签: 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);
    }

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中解析所有依赖项,以便容器调用我? :)

1 个答案:

答案 0 :(得分:5)

在我看来,您添加到_ManagementWorkSpaces的视图模型必须具有某种通用抽象(除非集合完全无类型且只接受任何object) - 我是假设这是WorkspaceViewModel类型。

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

public MainWindowViewModel(ObservableCollection<WorkspaceViewModel> workSpaces)
{
    this._ManagementWorkSpaces = workSpaces;
}

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