MVC DDD:将存储库与控制器中的服务一起使用是否可以?

Omu*_*Omu 9 architecture model-view-controller asp.net-mvc domain-driven-design

大部分时间在服务代码中我会有这样的事情:

public SomeService : ISomeService
{
    ISomeRepository someRepository;
    public Do(int id)
    {
        someRepository.Do(id);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以这有点多余

所以我开始直接在控制器中使用存储库

这个可以吗 ?是否有一些架构正在这样做?

Arn*_*psa 5

您失去了介于两者之间的业务逻辑的能力.

我不同意这一点.

如果业务逻辑应该在哪里 - 在域模型中,那么在控制器中调用repo(或者更好 - 使用模型绑定器)来获取聚合根和调用方法对我来说似乎完全没问题.

当涉及太多技术细节而导致控制器陷入困境时,应该使用应用程序服务.


我见过几个人提到最近使用模型绑定器调用回购.这个疯狂的想法来自哪里?

我相信我们在这里谈论两件不同的事情.我怀疑你的'模型绑定器'意味着同时使用模型作为视图模型,并将UI中的更改值直接绑定到它(这本身并不是坏事,在某些情况下我会走这条路).

我的'模型绑定器'是一个实现' IModelBinder ' 的类,它在构造函数中占用存储库(因为我们需要使用一些基本组合进行缓存,因此可以扩展)并在调用操作之前使用它来检索聚合根和用真实域对象替换int idGuid idstring slugwhatever动作参数.将它与输入视图模型参数相结合,可以让我们编写更少的代码.像这样的东西:

public ActionResult ChangeCustomerAddress
 (Customer c, ChangeCustomerAddressInput inp){
  c.ChangeCustomerAddress(inp.NewAddress);
  return RedirectToAction("Details", new{inp.Id});
}
Run Code Online (Sandbox Code Playgroud)

在我的实际代码中,它有点复杂,因为它包含ModelState验证和一些可能从域模型内部抛出的异常处理(提取到Controller扩展方法中以便重用).但不多.到目前为止 - 最长的控制器动作是~10行长.

你可以看到工作实现(相当复杂,(对我来说)不必要的复杂)在这里.

你是在用Linq To Sql做CRUD应用程序还是尝试使用真正的域逻辑?

正如您所希望的那样,这种方法实际上几乎迫使我们转向基于任务的应用而不是基于CRUD的应用.

通过在服务层中进行所有数据访问并使用IOC,您可以获得AOP的许多好处,例如无形缓存,事务管理以及我​​无法想象您使用模型绑定器的组件的简单组合.

...并且有一个新的抽象层,它邀请我们将基础设施与域逻辑混合在一起并失去域模型的隔离.

请赐教.

我不确定我是否这样做过.我不认为我自己开悟了.:)


是我目前的模型绑定器基类.这是我当前项目中的控制器操作之一.而这里的商业逻辑的"缺".