我正在使用Entity Framework 6学习ASP.NET MVC 5应用程序中的存储库和工作单元模式 .
我已经阅读了很多教程和文章,但几乎所有教程和文章都是相同的 . 其他人说,存储库和工作单元模式是好的,其他人说DbContext已经是一个存储库和工作单元,其他人说类似的东西,但提供了一种完全不同的方法 . 我尝试了所有这些不同的方法(好吧,也许不是全部)并且仍然在努力确定哪种方法是最正确的方法 .
我现在拥有的是:
-
实现IRepository的IRepository和GenericRepository
-
IUnitOfWork和UnitOfWork实现IUnitOfWork
-
IDbContext和MyDbContext继承自IdentityDbContext并实现IDbContext
不确定我是否需要粘贴它的代码,我认为这是非常通用的,问题实际上不是Repository / UnitOfWork . 我遇到的问题是将ASP.NET Identity类与我的存储库和工作单元结合使用 . 我正在为成员资格和所有其他数据共享相同的数据库 - 我认为这是一种常见的情况 . 我找不到好的解决方案如何使用我的存储库实例化ASP.NET Identity类 .
UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(_DBCONTEXT_);
this.UserManager = new UserManager<ApplicationUser>(store);
我应该用什么代替DBCONTEXT,以便它与我的UnitOfWork共享相同的DbContext?或者如何以其他方式完成使ASP.NET身份与UnitOfWork一起工作?
我尝试将DbContext暴露为UnitOfWork类的公共属性,如:
UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(this.unitOfWork.MyDbContext);
但是我不认为它是正确的 - 它不适用于自定义IDbContext接口,并使代码不适合单元测试 .
我也试图实现CustomUserStore和CustomRoleStore - 通常它可以工作,但是当我测试它时,它需要实现越来越多的方法 . 这个解决方案看起来太复杂了 - 我真的希望应该有更简单的方法 .
4 回答
我发现使用ASP.Net Identity 2.0和EF6有点挑战性 . 最大的缺点是缺乏文档或文档冲突 .
我使用的是WebApi 2.0,EF6和ASP.Net Identity 2.0 . 起初它很难开始,但一旦它正在工作,它一直很好 .
我创建了自己的Identity类 . 目前我不关心扩展身份类我只想生成表并登录系统 .
CustomRole
CustomUserClaim
CustomUserLogin
CustomUserRole
User
我不喜欢Identity表的命名,所以我更改了名称 .
DataContext
我发现让UserManager有点痛苦 .
我创建了一个静态类来处理它 . UserStore确实处理DataContext的生命周期,但您必须调用dispose才能实现此目的 . 如果您在其他地方使用此DataContext引用,这可能会导致问题 . 我最终将它连接到我的DI容器中,但是现在这就是我所拥有的:
我使用工作单元模式进行大多数数据访问 . 它运作良好 . 在某些情况下,我提供的数据需要比我暴露DataContext的这些情况所公开的工作单元更多的控制 . 如果这仍然不适合我,我将回退使用存储库 .
以下是它的一些实例 . 我有一个nHibernate背景,就像在
using
范围内定义一个事务所以我在我的工作单元中实现了 .使用工作单元“查找”的另一个例子:
User Creation and User Sign-In
我使用ASP.NET Identity进行登录和用户创建,使用我的工作单元进行其他操作 .
Testing
我不会尝试测试ASP.NET身份 . 首先,我确信微软在测试方面做得非常好 . 我相信他们做得比你或我做得更好 . 如果你真的想要测试ASP.NET身份代码,请将它放在接口后面并模拟接口 .
找到某种解决方案,看起来很通用,但我仍然不确定它是否真的很好并且不会破坏Repository / UnitOfWork模式原则 .
我在我的IUnitOfWork中添加了通用的GetDbContext()方法:
它在UnitOfWork类中的实现:
如何在Controller中使用,初始化UserManager:
我怀疑GetDbContext()将仅用于解决ASP.Identity的一些困难,所以可能不是那么糟糕..
“需要注意的一个问题是使用工作单元设计模式时,UserStore类不能很好地运行 . 具体来说,默认情况下,UserStore几乎在每个方法调用中调用SaveChanges,这使得过早提交工作单元变得容易 . 若要更改此行为,请更改UserStore上的AutoSaveChanges标志 . “
来自Scott Allen:http://odetocode.com/blogs/scott/archive/2014/01/03/asp-net-identity-with-the-entity-framework.aspx
如果您正在使用Repository和UnitofWork模式,那么您可能正在使用DDD(域驱动设计),您可以在 Core project 中声明IRepository或IUnitofWork以及所有其他域模型和抽象类 .
现在,您使用具体数据访问对象为此实例实体框架生成 Infrastructure project ,它在Core项目中实现这些接口 . 所以DbContext在那里很好,但是不要将它暴露给表示层 . 因此,在某些时候,如果您想将EF更改为任何其他ORM,那么在不触及表示层的情况下将更容易,您将Identity类与Data Access或Infrastructure项目分开 . 当然,您可以使用IOC容器从Presentation层的控制器中的基础架构实例化那些具体的存储库 .