如何处理MVVM应用程序中的构造函数过度注入问题

3
我一直在阅读有关构造函数过度注入的问题。 很明显这是SRP没有正确遵循的信号等。(顺便说一下,我正在使用Ninject!)
然而,在我的情况下,我很难理解如何解决这个问题。 最大的问题在于我的ViewModel中,我注入了DTO映射器和Repository以用于我的属性。
以下是我的视图模型构造函数的示例:
public MainViewModel(
        IGenericRepository<MainDbContext, Product> productRepository,
        IGenericRepository<MainDbContext, Person> personRepository,
        IGenericRepository<MainDbContext, Order> orderRepository,
        ProductMapper productMapper,
        PersonMapper personMapper,
        OrderMapper orderMapper,
        IViewModelLoader viewModelLoader, 
        IEventAggregator eventAggregator)
    {
        _productRepository = productRepository;
        _personRepository = personRepository;
        _orderRepository = orderRepository;
        _productMapper = productMapper;
        _personMapper = personMapper;
        _orderMapper = orderMapper;
        _viewModelLoader = viewModelLoader;
        _eventAggregator = eventAggregator;

        _eventAggregator.Subscribe(this);

    }

我猜测我没有正确使用repositories/mappers,它们应该从viewmodel中移出...但我不确定具体在哪里或如何操作。这就是我的问题所在。

应用程序的架构如下:

Company.Product.Core
Company.Product.DataAccess
Company.Product.Domain
Company.Product.Presentation

通用仓储(GenericRepository)位于Company.Product.DataAccess.Repositories中,映射器(mappers)位于Company.Product.Domain.Mappers中。

3
你不能将你的视图分成多个视图,然后将你的ViewModel分成多个视图模型吗? - Yacoub Massad
1
@zatixiz 关于帖子编辑的附注:如果可能的话,避免使用“EDIT:”/“UPDATE:”,尽量以一致的方式更新帖子,而不是历史记录的集合。 - Alexei Levenkov
1
为了跟进@YacoubMassad的点赞评论,即使不分割视图(例如MainViewModel(Person[Main]ViewModel, Product[Main]ViewModel...)),您也可以组合ViewModels,内部ViewModels可以直接绑定,并最终在其他地方重复使用(尽管要重复使用通常需要可重用的视图组件)。 - Gluck
@YacoubMassad 我会尽力更好地解释一下。视图的主要部分提供了用户对5个以上表格的概述,这些表格都相互关联。对于每个表格,我都必须创建一个新的IGenericRepository,然后将其注入到构造函数中。我正在构建一个更好的基础视图模型,希望它可以帮助解决构造函数混乱的问题。 - Joakim Hansson
@Gluck。啊,好的,谢谢你的评论!那很有道理。我想到目前为止我一直将它保留在一个视图模型中的唯一原因是因为我正在使用Caliburn.micro,并认为这样做会更容易让我遵循约定,将其保留在一个视图模型中。我将尝试将其拆分为不同的视图模型,并更新帖子的进展情况! - Joakim Hansson
显示剩余10条评论
1个回答

4

看一下构造函数列表,似乎每个东西都是成对出现的:

  • productRepository/productMapper
  • personRepository/personMapper
  • orderRepository/orderMapper

这似乎表明MainViewModel组成了与产品、人员和订单相关的内容。

您能否将其建模为由三个其他视图模型组成的ProductViewModelPersonViewModelOrderViewModel类?

甚至它必须完全是这三个类吗?MainViewModel是否可以组合任意数量的其他视图模型?

这将把构造函数简化为以下内容:

public MainViewModel(
    IReadOnlyCollection<IViewModel> viewModels,
    IViewModelLoader viewModelLoader, 
    IEventAggregator eventAggregator)

这看起来更加合理。

这本质上是一个 组合模式(Composite pattern) 的实现,在 UI 建模方面通常会有天然的适应性,这种情况下通常被称为 组合型 UI(Composite UIs)


另一件让我感到困惑的事情是那个 IVewModelLoader 是做什么用的?


太棒了,马克!你说的关于仓库和映射器成对出现是正确的。除了一些不需要映射数据的例外情况,我添加的每个仓库都是如此。很高兴你回答了我的问题,因为我实际上正在阅读你关于facade服务的文章以及你上面链接的相关答案。我会尝试实现你在这里建议的内容,并让你知道进展情况!关于IViewModelLoader...它负责打开我的视图和验证(目前还没做哈哈)。该类看起来像这样:http://pastebin.com/hbCEc41s - Joakim Hansson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接