我正在寻找一种方法,在具有Entity Framework的MVC4应用程序中拥有单独的业务逻辑层,而无需在其中注入我的(真实或虚假)数据库上下文 . 现在我们有一个虚假和真实的数据库上下文,它来自 IContext
,一个存储库 Repository
和一个控制器 MyController
. 使用以下模式将 IContext
注入到控制器和存储库中:
public class MyController : Controller
{
readonly Repository _repo;
/// <summary>
/// Initializes a new instance of the <see cref="Controllers.MyController"/> class which
/// makes use of the real Entity Framework context that connects with the database.
/// </summary>
public MyController()
{
_repo = new Repository();
}
/// <summary>
/// Initializes a new instance of the <see cref="Controllers.MyController"/> class which
/// can make use of a "Fake" Entity Framework context for unit testing purposes.
/// </summary>
/// <param name="db">Database context.</param>
public MyController(IContext db)
{
_repo = new Repository(db);
}
(...)
}
这是这样设置的,因为它是具有访问数据库并需要伪上下文的方法的存储库,而单元测试针对控制器并且需要实例化 .
现在我正在寻找一种方法来向项目添加业务逻辑类,其中将放置具有业务逻辑的方法 . 这些方法也需要从数据访问层( Repository
)获得的信息 .
使用上述模式在此业务逻辑层中为 Repository
注入 IContext
感觉有点奇怪 . 例如 . ,
BusinessLogic(IContext db)
{
_repo = new Repository(db);
}
我看到两种方法来避免这个问题:
-
调用控制器中的存储库,并将作为参数获取的数据用于业务逻辑层中的方法 .
-
无论如何都要注入 .
我正在寻找一个好主意, Build 与数据访问相关的业务逻辑层,并提供单元可测试性,最好不必在每个类中注入数据库上下文 .
希望有人能为我提供一些见解 . 谢谢 .
2 回答
如果要使用EF6,则具有继承自IContext或DbContext的EF上下文
您不希望将上下文直接注入Controler .
使用Service / DAO / Repository,它在构造函数中获取IContext / DbContext实例并处理数据访问 . 在我的示例中,我使用IUserService接受上下文并按ID返回用户 .
然后通过接口将服务注入控制器 .
另外,请考虑使用模拟框架来模拟您的上下文,例如起订量
我同意GMich . 同样......你的图层之间应该存在硬边界 . 它可能看起来像这样:
IUserController < - IUserProcessor < - IUserRepository < - IContext
您的DI和构造函数可以是:
创建将业务逻辑和存储库封装为属性的容器也很方便 . 例如:
并且澄清一下,使用这种方法时,也可能有IBusinessLogicContainer . 我们不希望在同一容器中加入BL和Repo对象 .