【问题标题】:Where to put the method. Service layer ( BL ) over repository?方法放在哪里。存储库上的服务层( BL )?
【发布时间】:2015-02-14 16:57:44
【问题描述】:

我对一件事感到困惑。我在以前的 mvc 应用程序中使用了存储库模式(不是通用的),并且我曾经在其中包含某种业务逻辑。此刻我读到了应该包含 BL 的服务层模式。但是现在不知道是否有更多的抽象和额外的代码,而不是清晰/可读和高效的代码。

我想实现这样的方法

public void ChangeActiveField(bool isActive, int id)
{
  var objectToUpdate = _context.FirstOrDefault(x=>x.id==id);
  objectToUpdate.IsActive - isActive;
  _context.Entry(objectToUpdate).State = System.Data.Entity.EntityState.Modified;
  _context.Save();
}

在这段代码中有一些业务逻辑,我在其中更改一个字段的状态,然后更新它。 我应该在服务层制作它,然后使用简单的存储库更新方法,例如:?

public class MyService
{
  private readonly IMyRepository = _myRepo;

  MyService(IMyRepository myRepo) //it's injectable
  {
    _myRepo = myRepo;
  }

  public void ChangeActiveField(bool isActive, int id) 
  {
     var myObject = _myRepo.GetMyObject(id);
     myObject.IsActive = isActive;
    _myRepo.Update(myObject);
  }

}

这是更好的方法吗?分离效果更好吗?或者它太复杂和覆盖? 感谢您的帮助。 最好的问候。

【问题讨论】:

  • 有了这样一个小例子 IMO 它只是让它......可测试。

标签: c# asp.net-mvc architecture repository-pattern service-layer


【解决方案1】:

一般存储库应该封装访问数据库的逻辑(上下文初始化、事务、连接等)。创建通用 CRUD 存储库并将其重用于所有业务实体是很常见的。 所有与业务相关的逻辑都应该放在业务层(服务层)中。 这种方法的主要好处是:

  1. 可测试性 - 您可以通过注入虚假存储库(存根)来测试业务逻辑,而无需依赖具体的存储库实现。
  2. 解耦 - 您的业务层和 UI 都没有与特定数据库耦合,如果明天您决定将数据库从 SQL 服务器迁移到 Redis(NoSQL 数据库),您的更改将仅包含在存储库层中。
  3. 可维护性 - 每一层都有明确的关注点分离:UI - 与用户的交互,BL - 业务逻辑的实现,存储库 - 与 DB 的交互。

根据我的经验,拥有一个业务层(无论一开始多么简单 - 它通常与您的项目一起发展)总是一个好主意。

顺便说一句,如果您使用 EF,一些开发人员将存储库视为不必要的抽象层(在某种程度上,EF 数据库上下文是存储库...)。

我学到的一件事是,主要的工作不是项目的开发阶段,而是维护和升级 - 这里有一个业务层会产生重大影响。

免责声明:这是我根据我的经验得出的主观意见

【讨论】:

  • 感谢您的回答。当我想要获取 Active 或 InActive 对象时怎么办?我应该在存储库中实现它吗? (它只会获取必要的项目,但我不能使用通用回购)或将所有项目放入内存然后过滤它们并通过服务返回?
  • 通用存储库的方法之一可能是返回 IQueriable 的 GetCollection。因此,将要生成并稍后执行的实际查询将包含所有应用的过滤器。该查询将仅在集合枚举上执行(例如,当您调用 ToList() 方法时)。因此,如果您的服务从存储库中获取 IQueriable 应用所有过滤器,然后调用 ToList() - 所有过滤都将在 DB 中执行。
  • 你的意思是这样的:IEnumerable GetAll(Expression> expression); ?我已经读过,当您想要对服务层进行单元测试时,将 IQueryable 暴露在 repo 层之外是不好的方法。 (我想在我的应用程序中标识)
  • 我不认为将 IQueryable 暴露在存储库之外是不好的方法。而且它绝对不会干扰服务测试。假设您有一个与内存数据库一起使用并将您的对象存储在 List 中的假存储库。你总是可以使用 AsQueriable() 方法
猜你喜欢
  • 2012-07-25
  • 2012-01-29
  • 1970-01-01
  • 2013-11-18
  • 2017-02-02
  • 2011-04-22
  • 1970-01-01
  • 2014-03-31
  • 1970-01-01
相关资源
最近更新 更多