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();
}
}
Related
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
I'm having some problems with getting unity to provide dependencies for my MVC controllers.
I want my ApplicationUser data and my business data in the same database and I am using code-first migrations with Entity Framework. To that end my DbContext inherits from IdentityDbContext and then implements an interface which represents my business data:
public class DealFinderDb : IdentityDbContext<ApplicationUser>, IDealFinderDb
{
public DealFinderDb() : base("name=DealFinderConnectionString", false)
{
}
public IDbSet<Deal> Deals { get; set; }
public IDbSet<Category> Categories { get; set; }
public IDbSet<SavedSearch> SavedSearches { get; set; }
public static DealFinderDb Create()
{
return new DealFinderDb();
}
}
public interface IDealFinderDb : IDisposable
{
IDbSet<Deal> Deals { get; set; }
IDbSet<Category> Categories { get; set; }
IDbSet<SavedSearch> SavedSearches { get; set; }
int SaveChanges();
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity)
where TEntity : class;
}
In my controller I need to be able to get the current user which means my controller has a dependency, not only on a IDealFinderDb but also on a UserManager. I understand that the best way to test this is to mock an IUserStore and pass that into the constructor of my controller. I have written the tests that mock both the IUserStore and the controller's HttpContext and these tests work as expected. This means my controller looks like this:
public class SavedSearchesController : Controller
{
private readonly IDealFinderDb dealFinderDb;
private readonly UserManager<ApplicationUser> userManager;
public SavedSearchesController(IDealFinderDb dealFinderDb, IUserStore<ApplicationUser> userStore)
{
this.dealFinderDb = dealFinderDb;
this.userManager = new UserManager<ApplicationUser>(userStore);
}
public ActionResult Index()
{
var user = this.userManager.FindById(this.User.Identity.GetUserId());
var usersSavedSearches = this.dealFinderDb.SavedSearches.Where(s => s.User.Id == user.Id);
return this.View(usersSavedSearches);
}
// Snip unrelated action methods.
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.dealFinderDb.Dispose();
}
base.Dispose(disposing);
}
}
This seems fine but I am using Unity to provide implementations for these interfaces at run-time and this is where I'm stuck. My first attempt at my UnityConfig looks like this:
container.RegisterType<IDealFinderDb, DealFinderDb>();
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
new InjectionConstructor(typeof(DealFinderDb)));
...but the problem with that is I end up with a DbContext being instantiated twice leading to an error of "System.InvalidOperationException: 'An entity object cannot be referenced by multiple instances of IEntityChangeTracker.'" when I call Add() on any of my IDBSets in my DbContext I guess this is because unity is instantiating my DbContext twice.
So my next attempt was to ensure that only a single instance of DealFinderDb is created and that looks like this in my UnityConfig:
container.RegisterType<DealFinderDb, DealFinderDb>(new ContainerControlledLifetimeManager());
container.RegisterType<IDealFinderDb, DealFinderDb>();
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
new InjectionConstructor(typeof(DealFinderDb)));
...but when this.userManager.FindById() is called in my controller I get the error "System.InvalidOperationException: 'The operation cannot be completed because the DbContext has been disposed.'". Obviously I could avoiding calling Dispose on my Context but this is bad as I assume means I am actually using the same DBContext instance for the entire life-cycle of my application.
What should I put in my UnityConfig to ensure that both the IDealFinderDb and IUserStore dependencies are satisfied and that only a single context is instantiated each time my controller is instantiated?
Thanks
What should I put in my UnityConfig to ensure that both the
IDealFinderDb and IUserStore dependencies are satisfied and that only
a single context is instantiated each my controller is instantiated?
You should use per-graph lifetime manager which is called PerResolveLifetimeManager in Unity:
container.RegisterType<IDealFinderDb, DealFinderDb>(new PerResolveLifetimeManager());
According to best practice to software design pattern, you should always follow Singleton Pattern while creating database context and logger context and many other things as per business requirement if you feel there is a need for singleton object go for that and while using singleton pattern do take care of thread safety singleton if you are implementing threads.its so easy and for help, you can refer MSDN, it has an implementation of the singleton.
https://msdn.microsoft.com/en-us/library/ff647854.aspx
Hope this helps.
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.
I have a simple repository that fetches some data using EF6. I'm also using a DI framework to inject the dependencies.
namespace Domain
{
public interface IMyRespository
{
List<MyObject> FetchObjects();
}
}
namespace Data
{
public class MyRepository : IMyRepository
{
private readonly MyDbContext _context;
public MyRepository(MyDbContext context)
{
_context = context;
}
public List<MyObjects> FetchObjects()
{
return _context.MyObjects.ToList();
}
}
}
A new requirement states that I need to log each FetchObjects() call and it's outputs. I thought this would be perfect example to apply the Decorator pattern.
namespace Domain
{
public class MyRepositoryDecorator : IMyRepository
{
private readonly IMyRepository _inner;
private readonly ILogRepository _logRepository;
public MyRepositoryDecorator(IMyRepository inner, ILogRepository logRepository)
{
_inner = inner;
_logRepository = logRepository;
}
public List<MyObjects> FetchObjects()
{
var objects = _inner.FetchObjects();
var logObject = new LogObject(objects);
_logRepository.Insert(logObject);
_logRepository.Save();
return objects;
}
}
}
Now I'm looking to employ the UnitOfWork pattern and I'm unsure how to implement in this case.
As I understand it some component needs to manage the UnitOfWork. So in this case a service class would make some calls and at the end call Save/Commit on the UnitOfWork class.
However if the repository interface indicates a readonly action there is no reason for the service class to wrap the call in a UnitOfWork and call Save/Commit at the end. It would look really weird too. However the decorator requires this to do it's job.
I'm probably missing some essential construct here. Any ideas on how to properly approach this scenario?
It would be a bad idea to mix UoW with Repository using Decorator (or similar) simply because it is not unusual for UoW to span across multiple repositories.
Also it is not up to the Repository to decide whether UoW should be committed or not. Repositories should know as less as possible about UoWs, ideally (and it is the case most of the time) nothing.
In your scenario the UnitOfWork class would pretty much only handles the transaction, so it can be implemented as a simple wrapper around TransactionScope, something like:
public sealed class UnitOfWork : IDisposable {
private readonly TransactionScope _transaction;
public UnitOfWork() { _transaction = new TransactionScope(); }
public void Commit { _transaction.Commit(); }
public void Dispose { _transaction.Dispose(); }
}
Now it is up to the service to instantiate/commit UoW, not up to Repository:
//assuming in a service
public void DoSomething() {
using(var uow = new UnitOfWork()) {
_repositoryA.UpdateSomething();
_repositoryB.DeleteSomething();
_uow.Commit();
}
}
And if your service only wants to read the data, then just do not use UnitOfWork in that operation (or use it without calling Commit so it will just be disposed).
In case if your repository needs to know about UoW, it will normally be passed as another parameter in its behavior method.
Note that it is not done because Repository wants to call Commit, but sometimes (rarely) it is needed for the repository to "enlist" to UoW. These cases are rather more complex.
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.