2

我正在开发一个应用程序使用asp.net mvc,NHibernate和DDD。我有我的应用程序的控制器使用的服务层。一切都在使用Unity来注入依赖关系(ISessionFactory存储库中,服务器和服务器中的服务器存储库)并且工作正常。服务层重复我的存储库

但是,这是很常见的,我需要在服务的方法来获得唯一对象在我的仓库,像这样(服务类):

public class ProductService { 

    private readonly IUnitOfWork _uow; 
    private readonly IProductRepository _productRepository; 

    public ProductService(IUnitOfWork unitOfWork, IProductRepository productRepository) { 
     this._uow = unitOfWork; 
     this._productRepository = productRepository; 
    } 

    /* this method should be exists in DDD ??? It's very common */ 
    public Domain.Product Get(long key) { 
     return _productRepository.Get(key); 
    } 

    /* other common method... is correct by DDD ? */ 
    public bool Delete(long key) { 
     usign (var tx = _uow.BeginTransaction()) { 
     try 
     { 
      _productRepository.Delete(key); 
      tx.Commit(); 
      return true; 
     } catch { 
      tx.RollBack(); 
      return false; 
     }   
     } 
    } 

    /* ... others methods ... */ 

} 

此代码是正确的DDD?对于每个服务类,我有一个存储库,并且对于每个服务类需要我为一个实体做一个“获取”方法?

谢谢你们

干杯

回答

1

这看起来是正确的,从我的角度来看。我真的不喜欢在我的asp.net MVC项目中重复使用服务和存储库方法名称,所以我选择了一个通用的存储库方法/模式。这意味着我真的只需要一个或两个Get()方法在我的存储库中检索我的对象。这对我来说是可能的,因为我使用的是实体框架,而我只是让我的存储库的get()方法返回一个IQueryable。然后,我就可以做到以下几点:

Product product = from p in _productRepository.Get() where p.Id == Id select p; 

你或许可以使用LINQ复制此NHibernate的 - > NHibernate的。


编辑:这适用于DDD,因为这仍然允许作为数据库我使用(NHibernate的,EF,等..),只要我交换我的DAL /仓库支持IQueryable的。

我不知道如何做一个没有IQueryable的通用存储库,但是您可能可以使用委托/ lambda函数来并入它。


EDIT2:以防万一我没有正确地回答你的问题,如果你是问你是否应该打电话给你的资料库的get()从服务方法,然后是的,这是正确的DDD设计也是如此。原因是服务层应该处理所有的业务逻辑,所以它决定如何以及检索什么数据(例如,你想按字母顺序,无序等等)。这也意味着它可以在删除和/或保存前在需要时进行验证或验证。

这意味着服务层并不关心数据的存储和检索方式,它只决定存储和检索哪些数据。然后它会调用存储库以正确处理请求,并以服务层告诉它的方式检索/存储数据。因此你有正确的关注点分离。

9

您的ProductService看起来并不像遵循域驱动设计原则。如果我理解正确,它是介绍和域之间应用层的一部分。如果是这样,ProductService上的方法应该对产品有商业意义。

让我们来谈谈删除产品。它是否像在数据库上执行删除操作一样简单(NHibernate,或其他?)我认为它不是。那些引用即将被删除的产品的订单呢?等等等等。顺便说一句,Udi Dahan在删除实体上写了一个great article。底线是,如果你的应用程序如此简单以至于服务确实复制了你的存储库并且只包含CRUD操作,那么你可能不应该做DDD,扔掉你的存储库并让服务在实体上运行(这将是简单的数据容器在这种情况下)。另一方面,如果存在复杂的行为(例如处理“已删除”产品的行为),那么在DDD路径中有一点意义,我强烈建议这样做。

PS。尽管采用了哪种方法(不管是否DDD),您最终还是会鼓励您使用一些面向方面编程来处理事务和异常相关的问题。您最终将获得许多方法,例如具有相同TX和异常处理代码的DeleteProduct。