I'm learning Repository and Unit of Work patterns in ASP.NET MVC 5 application with Entity Framework 6.
I had already read a lot of tutorials and articles, but almost all of them are condradictory. Ones say that Repository and Unit of Work patterns are good, others say DbContext is already a repository and unit of work, others say something similar, but offer a completely different approach. I tried all these different approaches (well, maybe not all of them) and still struggling regarding which approach is the most correct one.
What I currently have is:
- IRepository and GenericRepository implementing IRepository
- IUnitOfWork and UnitOfWork implementing IUnitOfWork
- IDbContext and MyDbContext inherited from IdentityDbContext and implementing IDbContext
Not sure if I need to paste the code for it, I think it's pretty generic and the problem actually is not with Repository/UnitOfWork as such. The issue I have is with using ASP.NET Identity classes in combination with my Repositories and Unit of Work.
I'm sharing same database for membership and for all other data – and I think it's a common scenario. I cannot find the good solution how can I instantiate ASP.NET Identity classes using my repositories.
UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(_DBCONTEXT_);
this.UserManager = new UserManager<ApplicationUser>(store);
What should I put in place of DBCONTEXT, so that it would share same DbContext with my UnitOfWork? Or how it can be done in some other way to make ASP.NET Identity to work with UnitOfWork?
I tried exposing DbContext as public property of UnitOfWork class, something like:
UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(this.unitOfWork.MyDbContext);
However I don't think it's right – it doesn't work with custom IDbContext interface, and makes the code not good for unit testing.
I also tried to implement CustomUserStore and CustomRoleStore – in general it worked, but as I was testing it, it was requiring to implement more and more methods. This solution looks too complicated – I really hope there should more simple way.
Best Answer
I have found working with ASP.Net Identity 2.0 and EF6 a bit challenging. The biggest drawback is the lack of documentation or conflicting documentation.
I am using WebApi 2.0, EF6 and ASP.Net Identity 2.0. At first it was tough to get going but once it's working, it's been good.
I created my own Identity classes. At the moment I don't care about extending the identity classes I just want to generate the tables and log into the system.
CustomRole
CustomUserClaim
CustomUserLogin
CustomUserRole
User
I don't like the naming of the Identity tables, so I changed the names.
DataContext
I found getting the UserManager a bit of a pain.
I created a static class to handle it. The UserStore does handle the lifecycle of the DataContext, but you'll have to call dispose for this to happen. This could cause problems if you are using this DataContext reference elsewhere. I'll eventually wire it into my DI container, but for now this is what I have:
I use the Unit of Work pattern for most my data access. It works good. There are some cases where I have data that needs more control than the unit of work exposes for these cases I exposed the DataContext. If that still does not work for me, I'll fallback to using a repository.
Here are a few examples of it in action. I have an nHibernate background and like defining a transaction in the scope of a
using
so I implemented in my unit of work.Another example of using the "Find" off of the Unit of Work:
User Creation and User Sign-In
I use ASP.NET Identity for the sign-In and user creation and my Unit of Work for everything else.
Testing
I would not try to test ASP.NET Identity. For one I'm sure Microsoft did a pretty good job testing it. I'm sure they did a better job than you or I could do. If you really want to test around the ASP.NET Identity code put it behind an interface and mock out the interface.