Как сделать голливудский принцип + DI + WPF + Unity - PullRequest
5 голосов
/ 31 августа 2011

В настоящее время я начинаю разработку нового приложения WPF, в котором я использую Unity в качестве DI-контейнера. На данный момент я делаю DI, как это в 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);
    }

Ctr MainWindowViewModel выглядит следующим образом:

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 вне ctr ManageUserViewModel и разрешить его напрямую через контейнер, но я думаю, что это нарушает принцип Голливуда. Как я могу в WPF разрешить все мои зависимости, чтобы контейнер вызывал меня? :)

1 Ответ

5 голосов
/ 31 августа 2011

Мне кажется, что модели представлений, которые вы добавляете в _ManagementWorkSpaces, должны иметь какую-то общую абстракцию (если коллекция не является полностью нетипизированной и просто принимает любые object) - я предполагаю, что этотип WorkspaceViewModel.

Это означает, что вы можете аккуратно решить свою проблему, изменив конструктор так:

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

Пусть ваш Корень композиции беспокоитсяо том, как разрешается экземпляр ObservableCollection<WorkspaceViewModel>.

...