查看模型和dependency injection

在使用PRISM和Enterprise Library进行大量CRUD操作的LOB桌面应用程序时,我注意到一种反复出现的模式似乎很烦人。 对于每个域模型实体(例如,Contact),我发现我用视图模型(例如ContactVM)自我包装然后我引入一个新的ContactsVM (注意’s’),其中后一个类接受一个存储库接口,用于填充一个ObservableCollection ,对于我从存储库中读取的每个Contact实体,我将它包装在ContactVM ,我将实体传递给构造函数以及我的ViewModel所需的其他企业库服务。

问题是我的所有视图模型构造函数都开始采用这样的模式:

ViewModel(EntityToWrap e, DependencyFromEntLib, OtherDependencies ...)

现在这是一个问题,因为大多数工具和库需要默认的无参数构造函数(例如,某些商业数据网格需要提供过滤支持),而且您不能使用设计数据来实现实体可视化,因为它们也需要无参数构造函数。 最后一个问题:构建视图模型的正确方法是什么?应该通过构造函数还是通过ServiceLocator提供Entlib服务?

以下是解决问题的众多不同方法之一。

我更喜欢更轻巧的视图模型。 然后我添加一个类,其职责是从一个或多个源(例如存储库)组成视图模型。 这并没有消除级联依赖的问题,但它确实释放了视图模型构造函数。

它还保留了控制器之外的逻辑,并允许重用视图模型(当然,适当时)。

  • 轻量级视图模型

  • 轻量级控制器知道如何定位组装视图模型的composer php(您可以使用DI框架来设置具有所有依赖关系的composer php)。 控制器可能在设置过程中起次要作用,但应保持简单。

  • Controller知道如何组装视图模型,并与composer类共享。 例如,该操作可能会请求一个摘要视图,该摘要视图仍然可以利用相同的视图模型而不会填充子项。

  • Composer汇集了完成视图模型所需的信息。 composer php可以使用其他composer php来收集不直接负责的信息。 同样,这里可以使用DI框架,以便为这些composer php提供他们所需的依赖关系。

  • 控制器像往常一样使用完成的视图模型呈现视图。

在我看来,这也提供了更好的抽象级别。 仅仅因为视图模型通常看起来像特定的域模型,这并不意味着它总是如此。

最终结果:

  • 很多类(一个缺点,被授予),但代码重复最少(即DRY)

  • 可测试的薄视图模型(如果需要……它们可能无需测试)

  • 薄,可测试的控制器。

  • 可测试的composer php对象,可以重复用于不同的场景,因为他们(可能)知道如何为各种目的组装视图模型。

  • 灵活地混合和匹配视图模型,控制器和编辑器,以支持不同的场景。