Asp.net mvc MVCDDD:在控制器中与服务一起使用存储库可以吗?
大多数情况下,在服务代码中,我会有如下内容:Asp.net mvc MVCDDD:在控制器中与服务一起使用存储库可以吗?,asp.net-mvc,model-view-controller,architecture,domain-driven-design,Asp.net Mvc,Model View Controller,Architecture,Domain Driven Design,大多数情况下,在服务代码中,我会有如下内容: public SomeService : ISomeService { ISomeRepository someRepository; public Do(int id) { someRepository.Do(id); } } public ActionResult ChangeCustomerAddress (Customer c, ChangeCustomerAddressInput inp)
public SomeService : ISomeService
{
ISomeRepository someRepository;
public Do(int id)
{
someRepository.Do(id);
}
}
public ActionResult ChangeCustomerAddress
(Customer c, ChangeCustomerAddressInput inp){
c.ChangeCustomerAddress(inp.NewAddress);
return RedirectToAction("Details", new{inp.Id});
}
所以它有点多余
所以我开始直接在控制器中使用存储库
这样行吗?是否存在这样的体系结构?如果在控制器中使用存储库,则直接从数据层转到表示层。您将失去将业务逻辑置于两者之间的能力 现在,如果您说您只在需要业务逻辑时使用服务,并且在其他地方使用存储库,那么您的代码将成为一场噩梦。表示层现在正在调用业务层和数据层,并且您没有很好的关注点分离 我总是这样做:
存储库->服务->用户界面
。一旦您认为不需要业务层,需求就会发生变化,您将不得不重写所有内容
您将失去将业务逻辑置于两者之间的能力
我不同意这一点
若业务逻辑应该在域模型中,那个么在控制器中调用repo(或者更好地使用modelbinder)来获取聚合根并调用它的方法对我来说似乎非常好
当涉及太多技术细节时,应该使用应用程序服务,因为这些细节会使控制器陷入混乱
最近,我看到一些人提到使用模型绑定器进行回购。这个疯狂的想法是从哪里来的 我相信我们在这里谈论的是两件不同的事情。我怀疑您的“模型绑定器”意味着同时使用模型作为视图模型,并将更改的值从UI直接绑定回它(这本身并不是一件坏事,在某些情况下,我会这样做) 我的“模型绑定器”是一个实现“”的类,它在构造函数中接受存储库(它被注入,因此,如果我们需要一些基本组合的缓存,它可以被扩展)并在调用action之前使用它来检索聚合根并用实域对象替换
int-id
或Guid-id
或string-slug
或任何
操作参数。结合输入视图模型参数,我们可以编写更少的代码。大概是这样的:
public SomeService : ISomeService
{
ISomeRepository someRepository;
public Do(int id)
{
someRepository.Do(id);
}
}
public ActionResult ChangeCustomerAddress
(Customer c, ChangeCustomerAddressInput inp){
c.ChangeCustomerAddress(inp.NewAddress);
return RedirectToAction("Details", new{inp.Id});
}
在我的实际代码中,它有点复杂,因为它包括ModelState验证和一些可能从域模型内部抛出的异常处理(提取到控制器扩展方法中以供重用)。但没有更多。到目前为止,最长的控制器动作约10行
您可以看到工作实现(非常复杂,而且(对我来说)不必要的复杂)
你只是在用LINQtoSQL做CRUD应用,还是在用真正的域逻辑做一些尝试
正如您(希望)看到的,这种方法实际上几乎迫使我们转向应用程序,而不是基于CRUD的应用程序
通过在服务层中进行所有数据访问并使用IOC,您可以获得AOP的许多好处,如不可见缓存、事务管理和组件的轻松组合,这些是我无法想象的,您可以通过模型绑定获得这些好处
…并且有了新的抽象层,邀请我们将基础架构与域逻辑混合,并失去域模型的隔离
请开导我
我不确定我是否做到了。我不认为我自己开悟了。:)
是我当前的模型绑定器基类。我当前项目中的一个控制器操作。“缺少”业务逻辑。即使使用“富域模型”,您仍然需要一个域服务来处理涉及多个实体的业务逻辑。我还从来没有见过没有一些业务逻辑的CRUD,只是在简单的示例代码中。我总是希望遵循Martin的路线来保持代码的简洁。我自己的DDD/MVC的粗略实践:
- 控制器是特定于应用程序的,因此它们应该只包含特定于应用程序的方法和调用服务方法
- 所有公共服务方法通常都是原子事务或查询
- 仅服务实例化和调用存储库
- my Domain定义了一个IContextFactory和一个IContext(由于IContext成员是IDBSet,所以存在大量泄漏的抽象)
- 每个应用程序都有一种类型,主要是实例化一个上下文工厂以传递给服务(您可以使用DI容器,但不是什么大问题)