MVC 5 EF6 unit of work and repository pattern - c#

How do you implement the unit of work and repository pattern in MVC 5 and EF6? Previously I've avoided any need for unit of work by using a single repository which was injected into my controller as follows:
public class ProductController : BaseController
{
private IShopRepository _repository;
public ClassController()
: this(new ShopRepository())
{
}
public ClassController(IShopRepository repository)
{
_repository = repository;
}
....
}
But now I want to refactor the code so that I have a separate repository for each entity type eg. ProductRepository, CustomerRepository etc and be able to inject multiple repositories into a controller whilst ensuring the same dbcontext is used.
Reading through the microsoft tutorial on http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application, the architects now advise the repository and unit of work pattern are no longer needed but they don't provide any example of how to implement or structure repositories in their examples?
Some people have even started renaming repositories to services?
How do you structure your repositories and implement unit of work in MVC5 using EF6 perhaps using an IOC such as Unity? Or what is another solution?
I'm working along the following lines but not sure if it is best solution and how do i add unit of work?
public class ShopContext : DbContext
{
public ShopContext() : base("name=ShopContext")
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Customer> Customers { get; set; }
...
}
public interface IProductRepository
{
IEnumerable<Product> GetAll();
...
}
public interface ICustomerRepository
{
IEnumerable<Customer> GetAll();
...
}
public class ProductRepository : IDisposable, IProductRepository
{
private ShopContext _context;
public ProductRepository()
{
_context = new ShopContext();
}
public IEnumerable<Product> GetAll()
{
return _context.Products;
}
// Other methods not displayed
protected void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
public class CustomerRepository : IDisposable, ICustomerRepository
{
private ShopContext _context;
public CustomerRepository()
{
_context = new ShopContext();
}
public IEnumerable<Customer> GetAll()
{
return _context.Customers;
}
// Other methods not displayed
protected void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
public class ProductsController : BaseController
{
private IProductRepository _productRepository;
private ICustomerRepository _customerRepository;
public ProductsController()
: this(new ProductRepository(), new CustomerRepository())
{
}
public ProductsController(IProductRepository productRepository, ICustomerRepository customerRepository)
{
_productRepository = productRepository;
_customerRepository = customerRepository;
}
// Other controller methods not shown.
}
Example code would be helpful.

The best working example one can find is the series of Mr Mittal at codeproject
he is using Entity Framework, Generic Repository pattern and Unit of Work.
keep up with him you'll get to know how this all works
here is the link Mittal Series

As #Thomas has already stated in the comments, I think what you're after here is a service layer rather than a repository. The two terms are often used very interchangeably, but they are not the same thing.
The repository pattern is intended to provide an abstraction of the database so that the database can change without impacting on the rest of the code. The DBContext in EF6 is already doing that for you as you can have, for example, a table called one thing, but mapped to a class with a different name. The DBContext also already implements the Unit of Work pattern, as it will perform all actions inside a single transaction up until you call SaveChanges/SaveChangesAsync on the context.
The service layer then provides methods to the user interface layer. It calls the methods from the repository to do this.
With a simple model it seems like the service layer and the repository are the same thing, but your repository would typically map to one business object (e.g. a Contact) where as your service layer might encapsulate a number of objects (e.g. a Customer business entity, which when saved stores data to the Contact and CustomerProfile repositories), using a unit of work to ensure that both changes are committed or rolled back together.
This excellent existing stack overflow answer by #ken2k goes into this in much more detail.

Related

Proper Separation of Concerns When Using UnitOfWork?

I followed an online tutorial of the UnitOfWork pattern with Entity Framework as it has been awhile since I have used it. I am confused as to why in the tutorial the DataContext is a parameter of the public UnitOfWork constructor. This means if I use the UnitOfWork in another layer of the application, the other layer must be aware of the DataContext. This does not seem like a good separation of concerns. Am I missing something?
UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly PurchasingDataContext _context;
public UnitOfWork(PurchasingDataContext context)
{
_context = context;
Items = new ItemRepository(_context);
Manufacturers = new LabelerRepository(_context);
Quotes = new QuoteRepository(_context);
Vendors = new VendorRepository(_context);
Contacts = new ContactRepository(_context);
}
public IItemRepository Items { get; private set; }
public ILabelerRepository Manufacturers { get; private set; }
public IQuoteRepository Quotes { get; private set; }
public IVendorRepository Vendors { get; private set; }
public IContactRepository Contacts { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
Interface:
public interface IUnitOfWork : IDisposable
{
IContactRepository Contacts { get; }
IItemRepository Items { get; }
ILabelerRepository Manufacturers { get; }
IQuoteRepository Quotes { get; }
IVendorRepository Vendors { get; }
int Complete();
}
I am confused as to why in the tutorial the DataContext is a parameter of the public UnitOfWork constructor.
This is to make injecting the dependency into the UoW possible. By doing this, you can honor SRP easily.
With it, you can manage the scope of DataContext separately outside the UoW. This gives you much flexibility while using same UoW in different scenario (windows application vs web application for example). With this, you can expand database transactions the way you want.
This means if I use the UnitOfWork in another layer of the application, the other layer must be aware of the DataContext.
Yes; but not entirely true. Yes, the instance of DataContext should be managed (create, inject and dispose) by calling layer. That's it. That layer does not need to interact with with this instance in any way.
This does not seem like a good separation of concerns.
In continuation to earlier point, calling layer does not need to know how that instance work. All that part is abstracted in your UoW class. This is clean separation of concerns.
Am I missing something?
Hope you know that now.
I would start by asking why you are creating and exposing these repositories in your UnitOfWork. Having a single class that is responsible for a unit of work and the ownership of all of your repositories violates the Single Responsibility Principle. Your IUnitOfWork exposing every single repository that may or may not be needed by a caller violates the Interface Segregation Principle.
Instead of this approach, you should be using a dependency injection framework to manage the lifetimes of the context, repositories, and unit of work. The framework should ensure that one instance is created per request and shared across dependencies where needed.
A typical EntityFramework UnitOfWork would look similar to:
public interface IUnitOfWork
{
void SaveChanges();
}
with an implementation like:
public class UnitOfWork : IUnitOfWork
{
private readonly PurchasingDataContext _context;
public UnitOfWork(PurchasingDataContext context)
{
_context = context;
}
public void SaveChanges()
{
return _context.SaveChanges();
}
}

UnitOfWork with Repository and Entity Framework

I am working on a project with Entity Framework where i have implemented Repository pattern and DI (Microsoft Unity), now to maintain the database transactions i want to implement the UnitOfWork pattern, but i am totally confused about how shall i implement it in my current project, i google around few posts, but could not find anything doable with my existing project.
Below is the EF and Repository structure along with DI (Microsoft Unity).
Entities:
public class GenericDo
{
public DateTime CreatedDate {get;set;}
public string CreatedBy {get;set;}
}
public class UsersDo : GenericDo
{
public int UserId {get;set;}
public string Username {get;set;}
....
}
public class UserProfileDo : GenericDo
{
public int Id {get;set}
public int UserId {get;set;}
public string Address {get;set;}
....
}
Interface:
public interface IGenericDao : IGenericDao<GenericDo> {}
public interface IGenericDao<T>
{
void Add(T entity);
T Get(object Id);
....
}
public interface IUsersDao : IUsersDao<UsersDo> {}
public interface IUserProfileDao : IUserProfileDao<UserProfileDo>{}
Interface Implementation:
public class GenericDao<T> : IGenericDao<T> where T : class
{
private readonly DataContext context;
public GenericDao(DataContext _context)
{
this.context = _context;
}
public void Add(T entity)
{
context.Set<T>().Add(entity);
}
public T Get(object Id)
{
return context.Set<T>().Find(Id);
}
}
public class UsersDao : GenericDao<UsersDo>, IUsersDao
{
public UsersDao(DataContext context) : base (context){}
}
public class UserPorfileDao : GenericDao<UserProfileDo>, IUserProfileDao
{
public UserPorfileDao(DataContext context) : base (context){}
}
Dependency Injection Setup in Global.asax.
var container = this.AddUnity();
container.RegisterType<IUsersDao, UsersDao>();
container.RegisterType<IUserProfileDao, UserProfileDao>();
Now in my main webpage(ASP.Net)
public partial class Default : System.Web.UI.Page
{
private readonly IUsersDao usersDao;
private readonly IUserProfileDao userProfileDao;
public Default(IUsersDao _userDao, IUserProfileDao _userProfileDao)
{
this.usersDao = _userDao;
this.userProfileDao = _userProfileDao;
}
// Now for testing purpose, i update record.
protected void Page_Load(object sender, EventArgs e)
{
UsersDo user = usersDao.Get(1);
user.Username = "new system";
UserProfileDo userProfile = userProfileDao.Get(1);
userProfile.Address = "new address";
// Now here i am confused about setting up common Save method to update database with transaction.
}
}
EntityFramework's DbContext already implements Unit of Work, so it is not necessary to add yet another layer of abstraction to implement this.
One could even doubt if creating a Repository pattern is actually helpful if you're using Entity Framework. Instead of using a layered architecture and using a Repository, you could investigate whether it is not better to use a more sliced architecture and use the DbContext directly.
Also, what is the benefit of having a 'Generic Dao' that just delegates calls to Entity Frameworks DbContext ? It's just yet another level of abstraction which adds extra complexity but doesn't give you any added value.
Unit of work ecapsulates the database operations in a single object and keeps track of them. In Entity Framework DbContext implements this behaviour and DbSet<> implements the repository. The reason why people create their own wrappers around is to be able to swap Entity Framework for another ORM, if needed or to mock Entity Framework for testing,.
UnitOfWork pattern is used with Entity Framework.
The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store and can facilitate automated unit testing or test-driven development (TDD).
First step is to create repositories. Repository is a class which exposes methods to business layer
Second step: You can create UnitOfWork implementation as shown below. There are properties corresponding to every repository. Then you inject Unit of Work in your business layer to use the repository methods.
public class UnitOfWork : IDisposable
{
private SchoolContext context = new SchoolContext();
private GenericRepository<Department> departmentRepository;
private GenericRepository<Course> courseRepository;
public GenericRepository<Department> DepartmentRepository
{
get
{
if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository<Department>(context);
}
return departmentRepository;
}
}
}
refer documentation at: https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

EF without implementing UoW or repository would be correct? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have seen many tutorials that implement with EF a repository pattern and UoW, but I do not see it necessary since DbSet and DbContext already are.
So I decided to simplify it without the implementation but adding services such as that.
public class HomeController : Controller
{
private IdbContext _dbContextUoW;
private IClientService _clientService;
public HomeController (IDbContext dbContextUoW,IClientService clientService){//IoC
this._dbContextUoW = dbContextUoW;
this._clientService = clientService;
}
public ActionResult Index()
{
List<Client> clients;
clients = List<Client>this._clientService(this._dbContextUoW).GetAll();
//this._dbContextUoW.SaveChanges()
return View();
}
}
public interface IClientService
{
List<Client> GetAll();
}
public class ClientService: IClientService
{
private IdbContextUoW _dbContextUoW;
public ClientService(IDbContext dbContextUoW){
this._dbContextUoW = dbContextUoW;
}
public List<Client> GetAll(){
return ...
}
}
Is this implementation correct? am'I on the right track?
Edit:
I have finally decided to do the following, I do not know if it is a good solution but to me it seems that yes, creating a generic repository for each service. My serice will have basics CRUD operations(repository) + logic operations(service)
public abstract class GenericRepository<T> : IGenericRepository<T>
where T : EntityBase
{
protected IContext _entities;
protected readonly IDbSet<T> _dbset;
public GenericRepository(IContext context)
{
_entities = context;
_dbset = context.Set<T>();
}
public virtual IEnumerable<T> GetAll()
{
...
}
public IEnumerable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
...
}
public virtual T Add(T entity)
{
...
}
public virtual T Delete(T entity)
{
...
}
public virtual void Edit(T entity)
{
...
}
public virtual void Save()
{
...
}
}
public class ClienteService : GenericRepository<Cliente>
{
IContext _context;
public ClienteService(IContext context)
:base(context)
{
_context = context;
}
public Cliente GetById(int Id)
{
return _dbset.FirstOrDefault(x => x.Id == Id);
}
}
You want a dbcontext per request/response.
So create a property on in global.asax for the CurrentContext.
public static YourDbContext CurrentContext
{
get { return (YourDbContext) HttpContext.Current.Items[Sessionkey]; }
private set { HttpContext.Current.Items[Sessionkey] = value; }
}
In application_beginrequest you want to instantiate your dbcontext and store it in the HttpContext
protected void Application_BeginRequest() { CurrentContext = new YourDbContext(); }
protected void Application_EndRequest()
{
if (CurrentContext != null)
CurrentContext.Dispose();
}
Then you can wire up your IoC container. This is castle windsor
public class SessionInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container
.Register(Component.For<YourDbContext>().UsingFactoryMethod(() => MvcApplication.CurrentContext)
.LifeStyle
.PerWebRequest);
}
}
I also create a Transaction attribute that handles the creating a committing the transaction. This attribute can then be applied to the controller method.
My first thought has been that your domain service looks like a repository. A GetAll() method (which from my point of view is harmful) isn't the kind of method you want to find in the service layer, which usually has more complex ones to implement actual domain operations (business operations in other paradigms).
If you're going to end up with same methods as a repository messed with more convenient service methods, probably you should go back to the absolutely abstract approach. In order to avoid messing up too much things, you can implement extra methods as extension methods to a particular IDbSet<T> (i.e. IDbSet<Client>, IDbSet<Product>, IDbSet<Whatever>...). That is, they'll be callable as part of the regular IDbSet<T> and you focus your domain services on what they are really mean to do based on their responsibility.
A sample extension method as I've suggested you on the previous paragraph would look as follows:
public static IImmutableList<SupportRequest> GetSupportRequestsByClientId(this IDbSet<SupportRequest> dbSet, Guid clientId)
{
// Do stuff here
return ...;
}
About the thing of not implementing full abstractions of repository and unit of work patterns, I would find this ok if you're dealing with a small project and a limited bucket on which you don't need to think in a long-term basis or you can't ever hope that you'll own the resources to implement an unit testing suite and you need to stay with some integration tests.
Another drawback of getting too coupled to specific unit of work or repository-ish implementations like ones provided by Entity Framework is that Microsoft might evolve it producing breaking changes that can completely destroy your solution. Obviously, you'll also find other well-known issues like not being able to consume NoSQL data sources and having a hard time to implement unit tests.
In summary, if you're going to implement a small project, there should be no hassle on going with your proposed approach...
the repository partern is better, because your service will rely in a interface and not in implementation.
if you want to use DbConnection with sql you can have a implementation using DbConnection.
if you want to have mongodb repository you can have a implementation using it.
another benefit you separate better the responsibilities using repository pattern.

EF6, Unit of Work and Repository Pattern - Is this the wrong pattern for a sync service?

I'm writing a sync service between our Salesforce environment and our local environment. My use of the Salesforce API is purely on a batch level due to limitations on # of API requests per day, although I do have details on failures at the atomic level. However, I would like to save changes on a atomic level in my local environment as I don't want an entire transaction to fail if one entity fails.
I am using Entity Framework 6 with a Unit of Work and Repository pattern. Here is my relevant code (Implementation Details Below):
IUnitOfWork
public interface IUnitOfWork: IDisposable
{
IReadUpdateRepository<EntityType1> EntityType1Repository { get; }
ISyncRepository<EntityType2> EntityType2Repository { get; }
ISyncRepository<EntityType3> EntityType3Repository { get; }
...other repos
void SaveChanges();
}
Implementation of IUnitOfWork
public class UnitOfWork : IUnitOfWork
{
private bool _isDisposed;
private DbContext _context;
private ISyncRepository<Entity> _entityRepo;
...other private repos
public UnitOfWork(DbContext context)
{
_context = context;
}
public ISyncRepository<Entity> EntityRepository
{
get
{
if (_entityRepo == null)
_entityRepo = new GenericSyncRepository<Entity>(_context);
return _entityRepo ;
}
}
...other getters for other repos
public void SaveChanges()
{
//client classes handle all errors here
_context.SaveChanges();
}
private void dispose(bool isDisposing)
{
if (!_isDisposed)
{
if (isDisposing)
_context.Dispose();
}
_isDisposed = true;
}
public void Dispose()
{
dispose(true);
}
}
ISyncRepository
public interface ISyncRepository<T> where T : BaseEntity
{
void DeleteItems(IEnumerable<T> items);
void DeleteItemsById(IEnumerable<int> ids);
void DeleteItem(T item);
void InsertItems(IEnumerable<T> items);
void Insert(T item);
T GetItemById(int id);
List<T> GetItems(Expression<Func<T, bool>> predicate = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "");
}
Implementation of ISyncRepository
public class GenericSyncRepository<T> : ISyncRepository<T> where T : BaseEntity
{
private readonly DbContext _context;
private readonly DbSet<T> _set;
public GenericSyncRepository(DbContext context)
{
_context = context;
_set = _context.Set<T>();
}
public T GetItemById(int id)
{
var result = _set.Find(id);
return result;
}
public List<T> GetItems(Expression<Func<T, bool>> predicate = null, Func<IQueryable<T>,IOrderedQueryable<T>> orderBy = null ,string includeProperties = "")
{
IQueryable<T> query = _set.AsExpandable();
if (predicate != null)
{
query = query.Where(predicate);
}
if (!String.IsNullOrEmpty(includeProperties))
{
var splitProps = includeProperties.Split(',');
foreach (var prop in splitProps)
{
query = query.Include(prop);
}
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
return query.ToList();
}
public void DeleteItemsById(IEnumerable<int> ids)
{
var items = ids.Select(i => _set.Find(i));
DeleteItems(items);
}
public void DeleteItem(T item)
{
_set.Remove(item);
}
public void DeleteItems(IEnumerable<T> items)
{
_context.Set<T>().RemoveRange(items);
}
public void Insert(T item)
{
_set.Add(item);
}
public void InsertItems(IEnumerable<T> items)
{
_set.AddRange(items);
}
public List<T> GetViewItems(Expression<Func<T, bool>> predicate)
{
IQueryable<T> query = _set.AsExpandable();
return query.Where(predicate).ToList();
}
}
I am using this repository in services that relate to each object group involved in the sync, into which I inject the IUnitOfWork via the constructor:
private readonly IUnitOfWork _uow;
public EntityDataService(IUnitOfWork uow, ICamsSfDTOMapper mapper)
{
_uow = uow;
}
Then use the UoW to fetch repositories to performs queries:
var repo = _unitOfWork.PartyRepository;
var p = repo.GetItems(p => Ids.Contains(someValue));
And when inserts or updates are made, I can call SaveChanges:
_unitOfWork.SaveChanges();
This works great for data retrieval, however for data persistence, I run into a snag. On the local domain side, I want to iterate through objects one by one, saving changes or inserting and calling SaveChanges to persist. If an error occurs, I store it in a result object that I log at the end of each sync step and continue onto the next object to do work on.
However, as my app is currently structured, if a database exception occurs on SaveChanges, that validation error remains in the context until it is disposed. Since this context is injected into each repository in the UoW class, it sticks around for what I presume is the life of the entire sync process.
I am using Autofac for DI in a WindowsService hosted using TopShelf and I'm registering my UoW as such:
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().WithParameter("context", new EntityModel());
Here are my questions:
Should this question be posted to Code Review :)
I feel like I should invert my repository with UoW, with UoW being passed into each repository and my repositories being passed into each service (a service can make use of more than one repository)
Does it make sense to spin up a new DbContext for each SaveChanges and to have one DbContext (the one passed into UoW) as my read context and all other contexts new'ed up when SavingChanges?
Any help would be appreciated.
Doesn't bother me, I only use SO and don't intend to go anywhere else, and don't mind having questions like these on SO.
I would highly recommend that your service as for IRepository and your repository ask for IUoW. I even like to think of IRepository as more than just a barrier to EF. I normally only use a repository if either
I know for a fact in advance I will be implementing a non EF repository as well otherwise
I want to implement some actual logic which I want abstracted from my service and would not make it generic. E.g. I would make a UserProfileRepository, which would have methods such as SyncCurrentUserProfile rather than exposing Add/Insert/Update. Exposing Add/Insert/Update adds nothing to the equation if I don't plan to use a non EF based model.
It depends. If you don't use tracking, and have a lot of unrelated changes over time. Than yes, as each time you add/update something it will add it to the context, which causes future additions/modifications become slower. But if you are adding/modifying 10 things here and there, probably wouldn't worry about it not unless you need a fresh context each time.
I am actually writing a blog post about this. Will try to post a link later.

EF DbContext and Ninject

I asked a question a while back about why the default equality comparer didn't seem to work when I was union two collections of entities.
EF Code First - Linq to Entities Union EqualityComparer
The answer was due to the fact that I was using two difference instances of my DbContext hence different references.
So now I am trying to share my DbContent across the request. I see a few "complicated" examples but I thought I'd try for a more simple solution.
So I created a IDbContext interface which simply outlines my Entities
public interface IDbContext {
int SaveChanges();
DbSet<News> News { get; set; }
DbSet<Category> Categories { get; set; }
}
My DbContext is then implement like this:
public class SiteContext : DbContext, IDbContext {
public DbSet<News> News { get; set; }
public DbSet<Category> Categories { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
...
}
}
Then in my two repositories (NewsRepository and CategoryRespository) I have the IDbContext as a constructor parameter
IDbContext _db;
public NewsRepository(IDbContext db) {
_db = db;
}
So now I assume that if I bind IDbContext to SiteContext in the request scope my repositories will share the same context?
kernel.Bind<IDbContext>().To<SiteContext>().InRequestScope();
However, when I try my union again from the previous question I still receive duplicate entities! What I am doing wrong? How can I tell if I am definitely using the same context in one request?
Because when each repository is constructed Ninject will is providing you with a new instance of SiteContext per repository. Thats why its not working. Its a good idea to use a unitofwork implementation which means all repositories use the same context.
The UnitOfWork would take in a IDbContext on construction.
Some thing like this would work
private IDbContext _context;
public UnitOfWork(IDbContext context)
{
_context = context
}
private _INewsRepository;
public INewsRepoitory
{
get{
if(_INewsRepository == null)
{
_INewsRepository = new NewsREpository(_context);
return _INewsRepository;
}
else
{
return _INewsRepository;
}
}
To improve the solution of feanz I would still do property injection of the INewsRepository with Ninject:
[Inject]
public INewsRepository NewsRepo {get;set;}
Every time an IUnitOfWork is created there is also an INewsRepository created. This must still be added to your ninject bindings.

Categories