ASP.NET 核心和 ViewModelFactory

ASP.NET Core and ViewModelFactory

您好,我正在尝试实现一个 ViewModelFactory "pattern",考虑到当前 IoC 容器的限制,我想知道实现它的最佳方法是什么。

public class UserCreateViewModelFactory
{
     private readonly DbContext db;

     public UserCreateViewModelFactory(DbContext db){ this.db = db;}

     public void Create(CreateUserViewModel viewModel)
     {
          //Creates the user
     }
}

我已将上述 class 轻松注入到我的控制器 ctor 中。当我需要更多的 ViewModelBuilder 时会很头疼,所以我想避免两件事:

  1. 通过注射使 ctor 膨胀
  2. 带有注册的膨胀容器

我希望能够在我的控制器上注入一个 IViewModelFactory,然后像这样使用它:

[HttpGet]
public IActionResult GetUsers(int id)
{
    return View(viewModelFactory.Build<GetUserViewModel>(id));
}

请注意,在调用 Build(T) 时,它必须调用正确的 IViewModelFactory 实现。

我知道 StructureMap 容器支持将具体实现绑定到相应的接口,但我正在尝试提出一个解决方案,而不必向项目添加另一个依赖项。

我认为如果你有构建视图模型的构建器,那么工厂就是额外的抽象层,可以简单地删除。
因为你在编译时知道创建的视图模型的类型,所以你可以将你需要的构建器注入到控制器构造函数中。

如果您的控制器创建了很多视图模型并且您最终需要注入很多构建器 - 这可以被视为违反单一职责原则的标志。在那种情况下,您需要将控制器的逻辑分离到不同的控制器。

So I want to avoid two things:

Bloat ctor with injections

  • 将 class 与臃肿的构造函数分离到另一个 class 具有更具体职责的 es,这需要更少的依赖性。
  • 或者根据它们的关系
  • 用一个或两个、三个class包裹依赖关系

Bloat container with registrations

  • 这不是问题,因为依赖容器通常设计用于注册应用程序的整个“对象图”

经过一段时间的研究,我终于想出了解决这个问题的好方法。

解决方案基本上是通过 IServiceCollection.ConnectImplementations() 扩展方法扩展默认的 IoC 功能。

在注册过程中,我将搜索我的具体 classes 并将它们与其各自的接口(如其他容器)连接起来。然后我使用一个 Mediator/Proxy 注入了 IServiceCollection 并且知道哪个具体 class 应该构建视图模型。

我创建的 this gist 更好地解释了完整的解决方案。