Click here to Skip to main content
13,091,145 members (63,228 online)
Rate this:
Please Sign up or sign in to vote.

For all my applications (ASP.NET MVC3, EF Code First), I have this general pattern that i'm using:


public class Product 
        public int ProductID { get; set; } 
        public string Name { get; set; } 
        public string Category { get; set; } 
        public decimal Price { get; set; } 


public class EFDbContext : DbContext 
        public DbSet<Product> Products { get; set; } 
        protected override void OnModelCreating(DbModelBuilder modelBuilder) 
            // Product 
                .HasKey(p => p.ProductID) 
                .Property(p => p.ProductID)

I have a Generic Repository, which will be used by my Unit Of Work class, as below:

public class UnitOfWork : IUnitOfWork, IDisposable 
        private readonly EFDbContext context; 
        private IGenericRepository<Product> _productRepository; 
        public UnitOfWork() 
            context = new EFDbContext(); 
        public EFDbContext Context 
                return context; 
        public IGenericRepository<Product> ProductRepository 
                if (_productRepository == null) 
                    _productRepository = new 
                return _productRepository; 
       // save() 
       // Dispose() & so on.. left out

I have a Service Layer, which as it should, models business logic. This layer, uses Unit Of Work, as below:

public class ProductService : IProductService 
        private IUnitOfWork unitOfWork; 
        public ProductService(IUnitOfWork unitOfWorkParam) 
            unitOfWork = unitOfWorkParam; 
        public void AddProduct(Product product) 
        // other services for business logic.. 

Now, my UI project (ASP.NET MVC3), uses the service layer as below

public class HomeController : Controller 
        private IProductService productService; 
        public HomeController(IProductService productServiceParam) 
            productService = productServiceParam; 
        public ActionResult Products() 
            // User productService.GetProducts and so on 

Thus the whole setup of the Projects to summazie would be:

Controller --> Service Layer --> UnitOfWork (which contains context, repositories)
--> DB

Now, my question is, the EFDbContext is contained in UnitOfWork, and thus, in this class, we can use queries such as:

using (var context = new EFDbContext()) 
    // use context.Entry<> 
    // use context.Find<> 
    // use context.Attach<> 
    // and other useful functions 

but, how can i get this functionality migrated to my Service Layer, which uses UnitOfWork.Repositories ?

Have i missed something in design?

It would be great to have the Service Layer capable somehow of using the bare context object, where in we can use useful extension methods such as context.Entry<> ..

Can anyone please help me with this?

Posted 4-Aug-12 3:50am
robroysd 5-Aug-12 18:58pm
FYI, for my own reference, and for anyone interested, i had posted the same issue on, here's the link

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

This looks complex. Why don't you use annotations on your class to define keys, etc ? For example, [Table("Product")] above the class and [Key] above the ProductId.

In my code, the DbContext has a private constructor, and a public static instance property, which returns the same instance across requests for the same session ( it uses the session key to do this ). I can access my DBContext from anywhere in my project, but I don't break it up in to dlls, so perhaps your issue is one of what dlls are consumed where ?
robroysd 4-Aug-12 18:13pm
I can use data annotations, but i use Fluent API so as to have all relationship maps at one place.
For example:
// Product:
// define product properties such as <Product>().has key etc etc
// define relations such as <Product>().HasMany(SomeList).WithRequired()..

This way, i can have everything in one place, i.e. the modelBuilder object.

I will look into the DbContext --> public static instance. Thanks.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web01 | 2.8.170813.1 | Last Updated 4 Aug 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100