【问题标题】:ASP.NET service vs repository layersASP.NET 服务与存储库层
【发布时间】:2011-05-21 01:38:11
【问题描述】:

服务层和存储库有什么区别?我已经完成了很多演示 ASP.NET MVC 应用程序,其中大多数只有存储库。有些人两者兼而有之。你什么时候只使用存储库,什么时候使用服务/或两者兼而有之? ASP.NET Web 应用程序也是如此。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-3 repository


    【解决方案1】:

    存储库充当您的数据存储(sql 数据库、xml 文件等)的网关,而服务通常在通过存储库发送要保存在数据库中的数据之前对您的数据实施一些业务规则。

    考虑这个例子:

    class UserRepository : IUserRepository
    {
       public void Create(User userToCreate)
       {
           //update tracking and save to repository
           _userToCreate.DateCreated = DateTime.Now;
           _dataContext.AddNew(userToCreate);
       }
    }
    
    
    class UserService : IUserService 
    {
       private IUserRepository _repository;
    
       public UserService(IUserRepository repository)
       {
            _repository = repository;
       }
    
       public void Create(User createdByUser, User userToCreate)
       {
           //implement some business rules
           if(!createdByUser.HasRights(UserRights.CanCreateNewUser))
               throw new Exception("This user '"+createdByUser.Name+"' does not have the rights to create a new user");
    
           //update rules auditing
           _userToCreate.CreatedByUserId = createdByUser.Id;
    
           //save entity to repository
           _repository.Create(userToCreate);
       }
    }
    

    然后在您的控制器操作中,您将直接使用可以应用所有业务规则的服务。这样您就可以使用 mock 分别/独立地测试您的控制器、业务规则(服务)和持久性(存储库)。

        public ActionResult CreateUser(User newUser)
        {
            if(ModelState.IsValid)
            {
               _userService.Create(this.CurrentUser, newUser);
               if(newUser.Id > 0)
                   return RedirectToAction("UserCreated");
            }
            return View(newUser);
        }
    

    【讨论】:

    • 不一定。将存储库视为一堆查询。例如,存储库层可能有 IQueryable GetUsers,但服务层可以有更多只使用相同查询的方法。例如IList GetUsers(int companyId, int pageNo), User FindUser(int companyId, string name), bool HasUsers(companyId) 等.
    • 我喜欢服务层将处理业务逻辑从而将其从操作方法/控制器中删除的概念。感谢塔瓦尼的建议。
    • 你完全错过了服务的角色。它不是任何类型的业务逻辑的容器。服务仅用于不属于单个聚合的业务逻辑,因此需要来自不同存储库的多个实体进行交互。因此,如果您的服务只使用一个存储库,那么这表明您正在使您的域模型变得贫乏。
    • @Pein:很好的评论,但是处理一个存储库聚合的业务逻辑应该去哪里?
    • 将业务逻辑放入服务中,任何处理数据访问到存储库中的东西似乎更清晰,更容易理解。
    【解决方案2】:

    存储库通常只处理数据访问。服务层将使用存储库,并应用任何其他业务逻辑。将存储库视为一个可重用的层,任何想要访问您的数据的东西都可以使用它。不同的应用程序可能有不同的业务规则(将进入服务层),但都可以使用相同的存储库层实现

    【讨论】:

    • 您将存储库和服务放在哪里?你的项目结构是什么样的?我有 MyProject.BusinessObjects 和 MyProject.DataObjects。我目前在 MyProject.BusinessObjects 中有我的存储库。
    • 我喜欢将我的领域模型(例如实体框架 edmx)和存储库类放在一个单独的项目 MyProject.Data 中。通常我的服务位于 MVC Web App 项目中的 /Services 文件夹中(但我不一定认为这是最佳实践 - 只是个人喜好)
    • @qntmfred:数据业务逻辑应该与 MyProject.Data 在同一个项目中,否则您最终会在依赖 MyProject.Data 项目的 Web 应用程序中复制业务逻辑。跨度>
    【解决方案3】:

    作为qntmfred 答案的概要,请查看以下资源:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多