如何做到好莱坞原则+ DI + WPF +统一

发布于 2024-12-02 09:14:55 字数 1966 浏览 0 评论 0原文

我目前正在开始开发一个新的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

゛清羽墨安 2024-12-09 09:14:55

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

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

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

让您的 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 any object) - I'm assuming that this is the WorkspaceViewModel type.

This means that you can neatly solve your problem by changing the constructor to look like this:

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

Let your Composition Root worry about how the ObservableCollection<WorkspaceViewModel> instance is resolved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文