MVC4 Unit Of Work with Entity FrameWork I am designing a new asp.net MVC4 application. I know that context class generated by EF is Unit of work and Dbset is the repository class. I am just avoiding the extra abstraction. I want to know whether I am following the correct pattern or not.

Entity

  public partial class ProductMaster
  {
    public long ID { get; set; }
    public string ProductCode { get; set; }
    public string ProductName { get; set; }

  }
  public partial class CompanyMaster
  {
    public long ID{ get; set; }
    public string CompanyName { get; set; }
    public string CompanyCode { get; set; }
  }


Context class(Generated By EF)

public partial class SampleEntities : DbContext,IUnitOfWork
{
    public SampleEntities()
        : base("name=SampleEntities")
    {
    }
    public void Commit()
    {
       SaveChanges();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public DbSet&lt;ProductMaster&gt; ProductMaster { get; set; }
    public DbSet&lt;CompanyMaster&gt; CompanyMaster { get; set; }
    public DbSet&lt;UserMaster&gt; UserMaster{ get; set; }


    public virtual ObjectResult&lt;SP_UserMaster_Result&gt; SP_UserMaster(Nullable&lt;long&gt; tM_UM_ID, string userName, string userPassword, Nullable&lt;byte&gt; userType)
    {
        var tM_UM_IDParameter = tM_UM_ID.HasValue ?
            new ObjectParameter("TM_UM_ID", tM_UM_ID) :
            new ObjectParameter("TM_UM_ID", typeof(long));

        var userNameParameter = userName != null ?
            new ObjectParameter("UserName", userName) :
            new ObjectParameter("UserName", typeof(string));

        var userPasswordParameter = userPassword != null ?
            new ObjectParameter("UserPassword", userPassword) :
            new ObjectParameter("UserPassword", typeof(string));

        var userTypeParameter = userType.HasValue ?
            new ObjectParameter("UserType", userType) :
            new ObjectParameter("UserType", typeof(byte));



        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction&lt;SP_UserMaster_Result&gt;("SP_UserMaster", tM_UM_IDParameter, userNameParameter, userPasswordParameter, userTypeParameter);
    }
}


Unit of Work Interface

public Interface IUnitOfWork
{
    public DbSet&lt;ProductMaster&gt; ProductMaster;
    public DbSet&lt;CompanyMaster&gt; CompanyMaster;
    public Dbset&lt;UserMaster&gt; UserMaster;
    public virtual ObjectResult SP_UserMaster(Nullable&lt;long&gt; tM_UM_ID, string userName, string userPassword, Nullable&lt;byte&gt; userType){};
    public void Commit();
}


Business Logic(Implementation)

 public class ProductMaster
 {
    IUnitOfWork _unitOfWork;
    public ProductMaster(IunitOfWork unitOfWork)//Injected using Ninject
    {
        this._unitOfWork = unitOfWork;
    }
    public void AddProduct(Product product)
    {
        _unitofWork.ProductMaster.Add(product);
        _unitOfWork.Commit();
    }
 }


Interface of Product Logic

 public class IProductMaster
  {
    public ProductMaster(IunitOfWork unitOfWork);
  }


Product Controller

  public class ProductController : Controller
  {
     IProductMaster _productMaster;
     public ProductController(IproductMaster productMaster)
     {
       this._ProductMaster=productMaster;//Injecting using Ninject
     }
     public void SaveProduct(ProductMaster product)
     {
        this._productMaster.AddProduct(product.ToEntity());
     }
  }
I think the problem is you’re starting with an implementation (Entity Framework) and then trying to bind this to two common design patterns – Unit Of Work and Repository.  The Entity Framework handles these two patterns and combines them together in Microsoft’s own implementation – they couldn’t actually work independently, for example you couldn’t just take a DbSet (Repository) and get a Product (entity) without instantiating the context (Unit Of Work).

These design patterns exist so they can be easily replaced within your application without changing much code, but if your IUnitOfWork is returning a DbSet&lt;T&gt; repository and you decide to read your Product entities from a local file instead of a database then you’re not really going to be able to implement this with your current abstraction.


IUnitOfWork should be strongly-named to the domain context – this is actually containing names of repositories which are specific to the domain context i.e. ProductMaster.  You could have IShopUnitOfWork derive from IUnitOfWork (which only has Commit as this is reusable in different domain contexts)
Your IUnitOfWork will get progressively bigger as you add new repositories and stored procedure definitions and I fear you’ll break the Interface Segregation Principle because of this.
I believe your repositories should actually contain the “query” calls specific for an aggregate root entity rather than your Unit Of Work – by putting it in the Unit Of Work you’re giving it two responsibilities:


i.  Maintaining the register of objects to be persisted

ii. Knowing how to authorise a user (in your example) along with all of the other stored procedure calls you’ll have

Therefore this will violate the Single Responsibility Principle

Furthermore SP_UserMaster should probably exist in the User repository as its specific to that domain entity.  Again this is strongly-named to imply a database call with a stored procedure – what if this was to be changed to a web service call?

With these caveats in mind it’s going to be hard to change your implementation to work this way with Entity Framework as Microsoft has taken the design patterns and implemented it in their own way with Unit Of Work and Repository mingled together - I'm not saying this is wrong its just the way they've decided to do it.  The main benefit of having these abstractions in this context is the benefit of being able to create stubs in unit testing so you’ll be mocking stored procedure and query calls without hitting the database.