4

我有一个ASP.NET MVC应用程序,我正在使用存储库模式以及服务特定的存储库。我发现我的设置开始感觉非常重复。服务层重复存储库层中的函数

我的层是这样的: UserController中> UserService> UserRepository(库然后使用实体框架)

控制器接受服务在构造为可测性: public UserController(IUserService userService)

该服务接受存储库: public UserService(IUserRepository)

用户可能能够更新他们的商业信息,更改他们的名字,电子邮件,删除联系地址等。

所以我结束了在服务这样的事情:

public class UserService { 
    User CreateUser(....); 
    User GetUserById(int id); 
    void UpdateUser(User user); 
    void DeleteUser(User user); 
    Business CreateBusiness(...); 
    Business GetBusinessById(int businessId); 
    void UpdateBusiness(Business business); 
    void DeleteBusiness(Business business); 
    IEnumerable<Business> GetBusinessesByUserId(); 
    IEnumerable<BusinessType> GetBusinessTypes(); 
    ... 
    ... 
    ... 

在仓库层每个函数调用的函数是这样的:

public class UserRepository { 
    User CreateUser(....); 
    User GetUserById(int id); 
    void UpdateUser(User user); 
    void DeleteUser(User user); 
    Business CreateBusiness(...); 
    Business GetBusinessById(int businessId); 
    void UpdateBusiness(Business business); 
    void DeleteBusiness(Business business); 
    IEnumerable<Business> GetBusinessesByUserId(); 
    IEnumerable<BusinessType> GetBusinessTypes(); 
    ... 
    ... 
    ... 

任何时候,我需要做任何类型的CRUD /数据访问操作,我发现自己正在执行以下操作:

  • 将操作添加到存储库的接口
  • 实现和代码库函数
  • 添加操作到业务层的接口
  • 实现和代码的服务功能调用上述库函数

这是越来越繁琐,尤其是当有与特定服务/存储库相关的多个实体。在整个应用程序中乘以多个存储库和服务...

为了背景,我不再使用通用存储库,以避免将多个存储库左右注入服务和/或控制器构造函数(或单个服务函数)的复杂性。

看来我违反DRY,并不断重复自己。这是尽可能接近,或者是否有更有效的方法来做到这一点?谢谢。

+0

我也问过这样的事情在过去,看看我的awser:http://stackoverflow.com/questions/2884011/service-layer-are - 重复我的库 –

+0

@felipeoriani - 谢谢,我看到了,但我希望避免一个通用的存储库模式,由于上述原因。我想知道如果我是尽可能以最好的方式做到这一点,那么给定服务特定的存储库。 – Josh

+0

阅读这篇文章。改变了我的体系结构:http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92完成后,请回头阅读以下内容:http://www.cuttingedge .it/blogs/steven/pivot/entry.php?id = 91 – danludwig

回答

4

首先。服务层不应重复存储库功能。而不是UserService.UpdateUser功能,应该有UserService.UpdateBasicData,UserService.UpdatePassword对象字段的子集的User。你通常不应该公开服务中的ORM层对象。 User对象肯定有很多属性,并且UpdateUser函数不应该改变它们,所以它不应该错误服务使用者,它可能会改变它们。

二。您仍然可以使用通用存储库并为注入进行存储库聚合。例如:

public class UserRelatedRepositories : IUserRelatedRepositories { 
    IRepository<User> User { get; set; } 
    IRepository<Business> Business { get; set; } 
} 

然后用

UserRelatedRepositories.User.Create() 
+0

谢谢。如果我不向服务公开ORM对象,那么在获取用户时服务会返回什么?另外,如果我有一个需要连接多个表并返回一个DTO的复杂查询,那么这个函数是否会直接在这个更高级别的聚合存储库上实现(在你的例子中为“UserRelatedRepositories”)? – Josh

+0

此外,为了可测试性,我不会将所有通用的IRepository对象传入我的聚合存储库的构造函数中,因此我的控制器的构造函数? – Josh

+0

@Josh:服务返回DTOs,所以它会返回包含用户属性子集的对象。对我而言,存储库是对象,仅用于简单的CRUD操作,因此必须在服务中进行复杂的查询。这就是为什么我的项目中的存储库返回'IQueryable'。为了可测试性,聚合存储库必须在构造函数中使用存储库。 – LukLed