我之前的问题让我再次思考层,存储库,依赖注入和这样的架构.
我的架构现在看起来像这样:
我首先使用EF代码,所以我只创建了POCO类和上下文.这创建了db和model.
级别更高的是业务层类(提供者).我为每个域使用不同的提供程序...比如MemberProvider,RoleProvider,TaskProvider等.我在每个提供程序中创建我的DbContext的新实例.
然后我在我的控制器中实例化这些提供程序,获取数据并将它们发送到Views.
我的初始架构包括存储库,我之所以摆脱它是因为我被告知它只会增加复杂性,所以为什么我不仅仅使用EF.我想这样做..直接从控制器使用EF,但我必须编写测试,它与真正的数据库有点复杂.我不得不假装 - 以某种方式模拟数据.因此,我为每个提供商创建了一个接口,并使列表中的硬编码数据成为假提供者.有了这个,我回到了一些东西,我不知道如何正确地进行.
这些事情开始过于复杂化......许多方法和"模式"......它产生了太多的噪音和无用的代码.
是否有任何SIMPLE和可测试的体系结构用于使用Entity Framework创建和ASP.NET MVC3应用程序?
architecture asp.net-mvc unit-testing entity-framework code-first
我研究了一些关于我可以用来对DbContext进行单元测试的技术的信息.我想在上下文中添加一些内存数据,以便我的测试可以针对它运行.我正在使用Database-First方法.
我发现最有用的两篇文章是这个和这个.该方法依赖于创建一个MyContext和FakeContext都将实现的IContext接口,允许模拟上下文.
但是,正如某些人所指出 的 那样,我试图避免使用存储库来抽象EF,因为EF 4.1已经通过DbSet和DbContext实现了存储库和工作单元模式,我真的想保留EF实现的所有功能.团队无需使用通用存储库维护它们,正如我在其他项目中所做的那样(这有点痛苦).
使用IContext会引导我走同一条路(或者不是吗?).
我考虑创建一个继承自主MyContext的FakeContext,从而利用它下面的DbContext来运行我的测试,而不需要访问数据库.我找不到类似的实现,所以我希望有人可以帮助我.
我做错了什么,或者这会导致我遇到一些我没想到的问题?
我已经阅读了几十篇关于试图在业务逻辑中模拟\假EF的PRO和CON的帖子.我还没有决定做什么 - 但我知道的一件事是 - 我必须将查询与业务逻辑分开.在这篇文章中我看到拉迪斯拉夫回答说有两种好方法:
- 让它们成为它们的位置,并使用自定义扩展方法,查询视图,映射数据库视图或自定义定义查询来定义可重用部分.
- 将每个查询作为方法公开在某个单独的类上.该方法不得暴露IQueryable,也不得接受Expression作为参数=整个查询逻辑必须包含在方法中.但这将使您的类覆盖相关方法很像存储库(唯一可以被模拟或伪造的).此实现与存储过程使用的实现很接近.
我是否必须封装最简单的查询,例如:
using (MyDbContext entities = new MyDbContext)
{
User user = entities.Users.Find(userId); // ENCAPSULATE THIS ?
// Some BL Code here
}
Run Code Online (Sandbox Code Playgroud)architecture extension-methods unit-testing entity-framework
在Asp.Net Core项目中,我正在注入Entity Framework DbContext:
public MessageRepository(MyDbContext context) {
}
Run Code Online (Sandbox Code Playgroud)
且配置为:
services
.AddEntityFramework()
.AddSqlServer()
.AddDbContext<Context>(x => x.UseSqlServer(connectionString);
Run Code Online (Sandbox Code Playgroud)
我应该创建一个接口IMyDbContext并注入它吗?
public class MyDbContext : DbContext, IMyDbContext { }
public MessageRepository(IMyDbContext context) {
}
Run Code Online (Sandbox Code Playgroud)
在所有ASP.NET Core示例中,我都看到了具体类型MyDbContext的注入,而不是接口。
我应该选择什么选项?