Bounded DbContext with Generic Unit of Work, Generic Repositories, Entity Framework 6 & EntLib Unity 3.0 in MVC 4

Update: 08/12/2013 – Changed InjectionConstructor parameter to: ResolvedParameter<IDbContext>(), to trigger compilation of the container when setting up the DbBounded Context and UnitOfWork(s) registrations.

Update: 08/08/2013 – Added PerRequestLifetimeManager() to the IUnitOfWork Unity Registration (binding) in UnityConfig.cs, so that the life-cycle of the UnitOfWork(s) instances being injected have singleton behavior within the scope of an Http request.

Update: 08/07/2013 – Ken from Microsoft has been kind enough to reach out and inform those of us that are using EF4 or EF5, that there maybe some potential collision issues, if there are entities with overlapping names, even if they live in different assemblies, please read below for a potential solution for this. If this does not apply to your use case or scenario, please continue on to the blog post after the block-quote.

At the risk of spamming your blog in comments I am turning to email. This is Ken the poster on your blog. J Your BoundedContext implementation has another interesting usage to easily support multiple DbContexts. Something that isn’t always that easy to do with a Repo + UoW frameworks. However, with EF5 and probably EF4 your readers will run into a bug if they have entities with overlapping names – EVEN IF they are separated by namespaces or live in different assemblies. For instance say you have two databases that both have a Logging table.

ExceptionMessage: The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type ‘MyType’. Previously found CLR type ‘Namespace1.MyTable’, newly found CLR type ‘Namespace2.MyTable’. The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type ‘ReferenceTable’. Previously found CLR type ‘Namespace1.ReferenceTable’, newly found CLR type ‘Namespace2.ReferenceTable’.”

The issue occurs with at EF5 unsure about EF4 but I suspect so. Read more here: http://entityframework.codeplex.com/workitem/911

The issue is resolved in EF6 beta1 from my testing.

Codewise this would be setup as follows

 

UnityConfig.cs
 
container.RegisterType("DbContext1");
container.RegisterType("DbContext2");
container.RegisterType(
    "DbContext1UnitOfWork", new InjectionConstructor(container.Resolve("DbContext1")));
container.RegisterType(
    "DbContext2UnitOfWork", new InjectionConstructor(container.Resolve("DbContext2")));
 
An Api Controller
 
public class SomethingFromDbContext1Controller : ApiController
    {
        private readonly IUnitOfWork _uow;
 
        public GenericRaptorTicketController(
            [Dependency("DbContext1UnitOfWork ")] IUnitOfWork uow)
        {
            _uow = uow;
        }

Now all of the above logic in the controller goes to Database1 using the types specified by namespace (dealing with overlapping table names that resulted in POCO classes that had the same name, different namespace). Easily I could add a second, third, fourth controller and specify DbContext2UnitOfWork and point to a second database. Cool stuff. Your approach is creative and I am sharing it with my peers and customers.

Now if only I have find a T4 template to bend to my will to shape the Data Mappings and Entities. Simon Huge’s Reverse POCO template comes close with a few modifications. J

-Ken

So there was an interesting question that was raised over the weekend from Tim, on could we take our generic Unit of Work and Repositories and implement the Bounded DbContext Pattern or philosophy if you will from DDD (Domain Driven Design) concepts. There are a few reasons to go with this Pattern e.g organization, manageability, decoupling, performance (in some cases), maintainability, etc.

My favorite reason is when working with large databases and having functionality in your application that is only working with specific domain areas, why load up a DbContext that has the overhead of your entire entity graph when your only working with a specific few? For example, you may have a database that has close to 100 tables (e.g. AdventureWorks), however if a user is only managing Products on a screen, why load up a DbContext that has the overhead of the entire entity graph. Figuring out where to decouple and decompose your domain model, to implement the Bounded DbContext Pattern can span a wide array of reasons, those reasons could span from business to technical reasons, usually both.

As an example, the AdventureWorks database is already separated into domain SQL Schemas, each of the tables shown here are prefixed with the SQL Schema. This is somewhat of an example of which entities would be in a Bounded DbContext, a Bounded DbContext could be created for each of the SQL Schema’s, and each of the Bounded DbContext’s would have the tables as DbSet’s in them. Again, separating your domain into areas really depends on your use cases both business and technical, this is just an example of a starting point.

7-31-2013 2-52-45 PM

Example: Potential Bounded DbContext’s in AdventureWorks based on SQL schemas defined.

  • HumanDbcontext
  • PersonDbcontext
  • ProductionDbcontext
  • PurchasingDbcontext
  • SalesDbcontext

Anyhow, back to the topic at hand, with some minor changes, here’s how we can accomplish Bounded DbContext with our UnitOfWork and Generic Repositories, we’ll start off from our last post: Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs. We are using the Northwind database as an example since this was used in the previous post, however with a database schema of this size, it’s probably not the ideal candidate for Bounded DbContext, you would probably implement this pattern on a database that had a much larger schema. But for the objective of this blog, Northwind will do. :)

Note: although we are using EF6 (alpha) in this example, we aren’t using any of EF6′s new features, however, it was a bit of a wiggle to get everything working. If you are attempting to get MVC, EF6 & SQL Sever CE 4.0 working, than this post and download maybe of use.

Data.NorthwindContext.cs – Before


    public class NorthwindContext : DbContext, IDbContext
    {
        static NorthwindContext()
        {
            Database.SetInitializer<NorthwindContext>(null);
        }

        public NorthwindContext()
            : base("Name=NorthwindContext")
        {
            Configuration.LazyLoadingEnabled = false;
        }

        public new IDbSet<T> Set<T>() where T : class
        {
            return base.Set<T>();
        }

        public override int SaveChanges()
        {
            this.ApplyStateChanges();
            return base.SaveChanges();
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new CustomerDemographicMap());
            modelBuilder.Configurations.Add(new CustomerMap());
            modelBuilder.Configurations.Add(new EmployeeMap());
            modelBuilder.Configurations.Add(new Order_DetailMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new RegionMap());
            modelBuilder.Configurations.Add(new ShipperMap());
            modelBuilder.Configurations.Add(new SupplierMap());
            modelBuilder.Configurations.Add(new TerritoryMap());
            modelBuilder.Configurations.Add(new InvoiceMap());
        }
    }

After

Data.DbContextBase.cs

We’ll go ahead abstract out our DbContext into a base class, since we’ll have multiple Bounded DbContexts.


    public abstract DbContextBase : DbContext, IDbContext
    {
        public DbContextBase(string nameOrConnectionString) : 
            base(nameOrConnectionString)
        {
            Configuration.LazyLoadingEnabled = false;
        }

        public new IDbSet<T> Set<T>() where T : class
        {
            return base.Set<T>();
        }

        public override int SaveChanges()
        {
            this.ApplyStateChanges();
            return base.SaveChanges();
        }
    }

Data.NorthwindCustomerDataContext.cs
*Customer Bounded Context


    public class NorthwindCustomerContext : DbContextBase
    {
        static NorthwindCustomerContext()
        {
            Database.SetInitializer<NorthwindCustomerContext>(null);
        }

        public NorthwindCustomerContext()
            : base("Name=NorthwindContext")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CustomerDemographicMap());
            modelBuilder.Configurations.Add(new CustomerMap());
        }
    }

Data.NorthwindDataContext – Everything else, Bounded Context :p


    public class NorthwindContext : DbContextBase
    {
        static NorthwindContext()
        {
            Database.SetInitializer<NorthwindCustomerContext>(null);
        }

        public NorthwindContext()
            : base("Name=NorthwindContext")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new EmployeeMap());
            modelBuilder.Configurations.Add(new Order_DetailMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new RegionMap());
            modelBuilder.Configurations.Add(new ShipperMap());
            modelBuilder.Configurations.Add(new SupplierMap());
            modelBuilder.Configurations.Add(new TerritoryMap());
            modelBuilder.Configurations.Add(new InvoiceMap());
        }
    }

We’ll need the following EntLib Unity v3.0 NuGet Packages.

  • Unity v3.0
  • Unity bootstrapper for ASP.NET MVC v3.0
  • Unity bootstrapper for ASP.NET MVC Web API v3.0

7-30-2013 9-29-07 AM

Spa.App_Start.UnityConfig.csUnity Bindings Before


container.RegisterType<IDbContext, NorthwindContext>();
container.RegisterType<IUnitOfWork, UnitOfWork>();
 

Spa.App_Start.UnityConfig.cs – Unity Bindings After (with Registration Names)


        public static void RegisterTypes(IUnityContainer container)
        {
            container.RegisterType<IDbContext, NorthwindContext>(new PerRequestLifetimeManager(), "NorthwindContext");
            container.RegisterType<IDbContext, NorthwindCustomerContext>(new PerRequestLifetimeManager(), "NorthwindCustomerContext");
            
            container.RegisterType<IUnitOfWork, UnitOfWork>(
                "NorthwindUnitOfWork", new InjectionConstructor(new ResolvedParameter<IDbContext>("NorthwindContext")));
            
            container.RegisterType<IUnitOfWork, UnitOfWork>(
                "NorthwindCustomerUnitOfWork", new InjectionConstructor(new ResolvedParameter<IDbContext>("NorthwindCustomerContext")));
        }
 

When working with ASP.NET (web apps) remember to make sure you are making good use of the UnityPerRequestHttpModule (line 12, below) in your UnityWebActivator. This will default the lifetime of your instances to lifetime of the current HttpRequest. You can configure registrations and pass in a other specific lifetime manager’s for other registration configurations who’s life-cycle does not need to bound to the HttpRequest.

Spa.App_Start.UnityWebActivator.cs


    public static class UnityWebActivator
    {
        public static void Start() 
        {
            var container = UnityConfig.GetConfiguredContainer();

            FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
            FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

             DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
        }
    }
  

Now we could just instantiate and pass in the appropriate Bounded DbContext implementations into the UnitOfWork registrations, however we would defeat one of the fundamental reasons of DI & IoC to begin with e.g. when we write our unit test later, we aren’t going to be able to switch out DbContext with a mocked one, easily. We could even do this registration in the web.config to give us more flexibility in terms of swapping the implementations of our DbContext’s however for the purposes of this post, we’ll continue on pro-grammatically.

Spa.Controllers.CustomerController – Before

Well now, that we have Bounded DbContext and UnitOfworks, how do we get them? We have two options, first options which is leveraging DI & IoC with Unity 3.0, and the obvious method of instantiating them manually. We’ll demonstrate the first option below, in our CustomerController.


    public class CustomerController : Controller
    {
        private readonly IUnitOfWork _unitOfWork;

        public CustomerController(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            int totalCustomerCount;

            var customers =
                _unitOfWork.Repository<Customer>()
                    .Query()
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            return View();
        }

        [HttpGet]
        public ActionResult Edit(string id)
        {
            var customer = _unitOfWork.Repository<Customer>().FindById(id);
            return View(customer);
        }

        [HttpPost]
        public ActionResult Edit(Customer customer)
        {
            if (ModelState.IsValid)
                RedirectToAction("Edit");

            customer.State = ObjectState.Modified;
            _unitOfWork.Repository<Customer>().Update(customer);
            _unitOfWork.Save();

            return View(customer);
        }
    }

Spa.CustomerController – After

We can get them by passing the registration name of Unity binding we setup earlier.

Option A:


    public class CustomerController : Controller
    {
        private readonly IUnitOfWork _customerUnitOfWork;
        private readonly IUnitOfWork _northwindUnitOfWork;

        public CustomerController(IUnityContainer container)
        {
            _northwindUnitOfWork = container.Resolve<IUnitOfWork>("NorthwindUnitOfWork");;
            _customerUnitOfWork = container.Resolve<IUnitOfWork>("NorthwindCustomerUnitOfWork");
        }

        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            int totalCustomerCount;

            var customers =
                _customerUnitOfWork.Repository<Customer>()
                    .Query()
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            return View();
        }

        [HttpGet]
        public ActionResult Edit(string id)
        {
            var customer = _customerUnitOfWork.Repository<Customer>().FindById(id);
            return View(customer);
        }

        [HttpPost]
        public ActionResult Edit(Customer customer)
        {
            if (ModelState.IsValid)
                RedirectToAction("Edit");

            customer.State = ObjectState.Modified;
            _customerUnitOfWork.Repository<Customer>().Update(customer);
            _customerUnitOfWork.Save();

            return View(customer);
        }
    }

Option B:


    public class CustomerController : Controller
    {
        private readonly IUnitOfWork _customerUnitOfWork;
        private readonly IUnitOfWork _northwindUnitOfWork;

        public CustomerController(
            [Dependency("NorthwindUnitOfWork")] IUnitOfWork northwindUnitOfWork,
            [Dependency("NorthwindCustomerUnitOfWork")] IUnitOfWork customerUnitOfWork)
        {
            _northwindUnitOfWork = northwindUnitOfWork;
            _customerUnitOfWork = customerUnitOfWork;
        }

        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            int totalCustomerCount;

            var customers =
                _customerUnitOfWork.Repository<Customer>()
                    .Query()
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            return View();
        }

        [HttpGet]
        public ActionResult Edit(string id)
        {
            var customer = _customerUnitOfWork.Repository<Customer>().FindById(id);
            return View(customer);
        }

        [HttpPost]
        public ActionResult Edit(Customer customer)
        {
            if (ModelState.IsValid)
                RedirectToAction("Edit");

            customer.State = ObjectState.Modified;
            _customerUnitOfWork.Repository<Customer>().Update(customer);
            _customerUnitOfWork.Save();

            return View(customer);
        }
    }

Note: Probably a good idea, specially in this case to go ahead and create an Enum or a class with constants instead of passing in hand coded strings as the registration name.

I prefer Option B, personally I don’t like the fact that you injecting anything with the entire Container, I rather have it when something is requesting to be injected, that the requester is specific in what it requesting for. Anyhow, I’ve seen this debate go both ways, moving on…

The alternative for those of us that are not using any IoC & DI

You should be using some form of DI & IoC with the N-number of frameworks out there, however if your not, obviously you an instantiate your Bounded UnitOfwork and DbContext directly.

Spa.CustomerController – without IoC and/or DI


    public class CustomerController : Controller
    {
        private readonly IUnitOfWork _customerUnitOfWork;
        private readonly IUnitOfWork _northwindUnitOfWork;

        public CustomerController(IUnityContainer container)
        {
            _northwindUnitOfWork = new UnitOfWork(new NorthwindContext());
            _customerUnitOfWork = new UnitOfWork(new NorthwindCustomerContext());
        }

        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            int totalCustomerCount;

            var customers =
                _customerUnitOfWork.Repository<Customer>()
                    .Query()
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            return View();
        }

        [HttpGet]
        public ActionResult Edit(string id)
        {
            var customer = _customerUnitOfWork.Repository<Customer>().FindById(id);
            return View(customer);
        }

        [HttpPost]
        public ActionResult Edit(Customer customer)
        {
            if (ModelState.IsValid)
                RedirectToAction("Edit");

            customer.State = ObjectState.Modified;
            _customerUnitOfWork.Repository<Customer>().Update(customer);
            _customerUnitOfWork.Save();

            return View(customer);
        }
    }
 

Now, let’s run the application.

http://localhost:29622/Customer

7-30-2013 12-35-41 AM

There you have it, Happy Coding…! :)

Download sample application: https://skydrive.live.com/redir?resid=949A1C97C2A17906!5962

Note: Please “Enable NuGet Package Restore” on the VS Solution.

About these ads

55 thoughts on “Bounded DbContext with Generic Unit of Work, Generic Repositories, Entity Framework 6 & EntLib Unity 3.0 in MVC 4

  1. The community seems to be moving away from the use of UoW and Repos with EF 6. The DbContext is a unit of work and DbSets are repositories. No need to build same on top. This is what I am grappling with right now. All I need is some abstraction on top of the DbContext and the EF won’t be coupled with the Service layer.

    Is this something you’ve considered?

    • One of the framework’s design and architectural intent is to minimize the surface area of your ORM e.g. EF, in the case you need switch this out or refactor, this would be minimized to the Repository layer. Whether or not this is an architectural design principle that would be of value to one’s project or not, that would be something you would have to answer to. In most cases these patterns have been extremely beneficial in long term projects.

    • Yep. I realize that. I think I am going to go with Query objects or the like, as proposed by the great Ayende Rahien and Jimmy Bogard. The need for abstraction is absolute. I just think the repository pattern is on the way out. I’d rather be on the cutting edge. Cheers.

  2. What’s Taking place i am new to this, I stumbled upon this I have found It positively helpful
    and it has aided me out loads. I’m hoping to
    give a contribution & aid different users like its aided me.
    Good job.

  3. Hi Le,

    Thanks for great post. Any succeed in getting the this generic UOW and Repo pattern working asynchronously and with await and Task in .NET 4.5 ?

    At the moment I have something like

    BoundedUnitOfWork where TContext: IBoundedDbContext
    and Repository inside the BoundedUnitOfWork

    and It works perfectly fine. Though still trying to get it async.

    I really appreciate any update or starting point to work on.

  4. 50% related question , I would like to hear your opinion : I wanna add to your solution a Settings class that every x seconds will update ‘global system data’ from the database , like “DefaultDateTImeFormat” or “MaxUsers” or “SecondServerUrl” for example , how you suggest to do this?

    I though about :

    A) every time a ‘client’ do a request to the server , use his session to run a method to check if X minutes has passed since last update and then update my Settings class with the fresh data

    B) not use users/client session , use Settings class in Application scope and every X minutes create a new UnitOfWork and get the data . ( I don’t know if its good to reCreate UnitOfWork paramter or not , is there a session limit ? )

    C) ?

    Thanks

    • Your probably better off using the new .NET System.Runtime.Caching libs and setup a SqlChangeMonitor (dependency) with this. That way your cache/class is only refreshed when it needs be, in this case when there is an actual change in the Settings SQL table.

  5. Nice post, however I’m not a fan of the tight coupling between Unity and your controllers (which you create either by injecting a Unity container or adding the [Dependency] attributes to your controller constructors).

    A better approach (IMHO of course :) that would allow you to inject your UnitOfWork dependencies without tightly coupling to Unity is to add the following to your existing Unity IoC configuration as follows:

    container.RegisterType(new InjectionConstructor(
    new ResolvedParameter(“NorthwindUnitOfWork”),
    new ResolvedParameter(“NorthwindCustomerUnitOfWork”));

    You should now be able to use the following controller constructor and Unity will resolve the correct IUnitOfWork concrete types for each injected dependency:

    public CustomerController(IUnitOfWork northwindUnitOfWork, IUnitOfWork customerUnitOfWork)
    {
    _northwindUnitOfWork = northwindUnitOfWork;
    _customerUnitOfWork = customerUnitOfWork;
    }

    • Typo in the above… the container registration should be:

      container.RegisterType(new InjectionConstructor(
      new ResolvedParameter(“NorthwindUnitOfWork”),
      new ResolvedParameter(“NorthwindCustomerUnitOfWork”));

    • WordPress doesn’t like generic types :) Let’s try that again:

      container.RegisterType(new InjectionConstructor(
      new ResolvedParameter(“NorthwindUnitOfWork”),
      new ResolvedParameter(“NorthwindCustomerUnitOfWork”));

    • Sorry – WordPress is removing the generic type T marker from my posts:

      container.RegisterType of Type T needs to reference CustomerController as the Type T

  6. Once again great post, can’t wait to check out the asynchronous one.
    A conceptual question:
    Should UnitOfWork be a singleton?
    Else why should I even bother saving repositories? (The use case of a thread using the same repo twice is not so common in a web application).

    The motivation to the question comes from trying to add some notification capabilities to the repositories. Such as letting some listeners know when a certain entity was updated.
    Without making the UnitOfWork singleton, you must introduce a Bus or some other way to persist these events.
    Thanks!

    • Hi Tomer,

      The IUnitOfWork instance lifecycle is bound to the lifecycle of the HttpRequest, this is configured in the UnityConfig under AppStart. So it is Singleton for a given user for their HttpRequest.

    • Probably not, concepts should stay fairly the same if not exact despite what DI & IoC framework you use. Just use Ninjects named bindings as depicted in the post vs. Unity’s.

    • Hi Ivan, yes I started, now it’s just as matter of finding the time to finish. Once, it’s complete I’ll update the blog post. Question, have you started on this? If so, I’m entertaining the idea of checking this into GitHub, and see if we could divvy this work up. :)

    • I am using your Repository and UoW with EF6 RC1 to implement the 3 OData base classes: ODataController, EntitySetController and AsyncEntitySetController.
      I started the Async implementation. Need more research and testing, but I’d be happy to help you out.

    • Funny, the AsyncEntitySetController was the same reason why I started on add Async implementations to the UoW and Repo Framework. Question, I noticed when implementing the AsyncEntitySetController, that it want’s you to return a collection vs. an IQueryable, if that’s the case will query translation (OData automatically passing and handling all the query criteria to EF) still work?

    • I got this far:

      [Queryable]
      public async override Task<IEnumerable> Get()
      {
      return await _db.Repository().Query().GetAsync();
      }

      protected async override Task GetEntityByKeyAsync(int key)
      {
      return await _db.Repository().FindByIdAsync(key);
      }

      public async override Task Patch(int key, Delta patch)
      {
      var entity = await _db.Repository().FindByIdAsync(key);

      if (entity == null)
      {
      throw new HttpResponseException(HttpStatusCode.NotFound);
      }
      patch.Patch(entity);

      //TODO:
      var cancellationToken = new CancellationToken();
      await _db.SaveAsync(cancellationToken);

      // Create an HttpResponseMessage and add an HTTP header field
      return Request.CreateResponse(HttpStatusCode.OK, entity);
      }

      protected async override Task PatchEntityAsync(int key, Delta patch)
      {
      var entity = await _db.Repository().FindByIdAsync(key);

      if (entity == null)
      {
      throw new HttpResponseException(HttpStatusCode.NotFound);
      }
      patch.Patch(entity);

      //TODO:
      var cancellationToken = new CancellationToken();

      await _db.SaveAsync(cancellationToken);

      // Create an HttpResponseMessage and add an HTTP header field
      return entity;
      }

      protected async override Task UpdateEntityAsync(int key, Genre update)
      {
      // Verify that a genre with this Id exists.
      var q = await _db.Repository()
      .Query()
      .Filter(x => x.Id == key)
      .GetAsync();

      if (q == null || !q.Any())
      {
      throw new HttpResponseException(HttpStatusCode.NotFound);
      }

      _db.Repository().Update(update);

      //TODO:
      var cancellationToken = new CancellationToken();

      await _db.SaveAsync(cancellationToken);

      //_context.Products.Attach(update); // Replace the existing entity in the DbSet.
      //_context.Entry(update).State = System.Data.EntityState.Modified;
      //_context.SaveChanges();
      return update;
      }

      public async override Task Delete([FromODataUri] int key)
      {
      var entity = await _db.Repository().FindByIdAsync(key);

      if (entity == null)
      {
      throw new HttpResponseException(HttpStatusCode.NotFound);
      }
      _db.Repository().Delete(entity);

      //TODO:
      var cancellationToken = new CancellationToken();

      await _db.SaveAsync(cancellationToken);
      }

  7. Once again keep digging and modeling using your post and the UnitOfWork pattern… Here is a little problem I ran into:
    On the NorthWindContext class, you have declared a static ctor, which sets the DB initializer to null.
    static NorthwindContext()
    {
    Database.SetInitializer(null);
    }

    Say I want to use a different initializer such as DropCreateDatabaseIfModelChanges? No problem I just use:
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges());

    However, if I want to use a custom initializer and override the seed method (in order to insert some records to the DB) there is a little problem that raises:
    1. I obviously can’t inject the IUnitOfWork to the NorthwindContext, even if I ignore the static constructor, since it result a circular dependency.
    2. Nor I can inject it to the UnitOfWork from the same reasons.

    What I can do, is manually creating a UnitOfWork instance inside the Seed method giving a DBContext object is provided to this method. However it is pretty ugly.

    Any ideas how to overcome this coupling issue on your model?
    Thanks!

  8. Great post series! Love it!.
    I’ve been playing with some portion of the code around, trying to figure out how would I go and get related entities by using OData queries (syntax) -> basically make the Repository translate the $expand into .Include (the repository syntax).
    In more details say I have:
    class Customer
    {
    public int CustomerId { get; set; }
    public virtual Address { get; set; }
    }

    class Address
    {
    public int AddressId { get; set; }
    public string Name { get; set; }
    }

    And my get method is the default:
    return _unitOfWork.Repository().Query().Get();

    I don’t get the Address related to the customer unless I specifically add:
    .Include(x => x.Address)
    To the controller (prevents me from generalizing some basic controllers).

    While this might be the desired behavior, I would really like Repository to “understand” the OData syntax – that is – ‘?$expand=Address’, will give me the same result.

    Thanks!

    • Sure, you can need to enable lazy loading which I’ve disabled. You can find this in the UnitOfWork.cs, believe it’s in the Constructor.

  9. Do you have a repository that works with the objects generated by the EF6 Designer?
    E.g. db.edmx has db.Context.tt and db.tt, db.tt will generate the POCO classes in the edmx model.
    I’d love to see the UoW and Repository for that.
    Thx for your great contribution.

    • This already works with EF6 designer generated DbContext and POCO entities. Just need to set the UnitOfWork here to the DbContext that was generated by the designer and your good to go.

  10. Say I have multiple DbContexts, split by schema or even across databases. If my controller or service layer needs to do an atomic operation across those contexts (UoWs), how would I go about doing it? Typically you might instantiate a TransactionScope in the controller or service layer and inside of it create the UoWs/DbContexts and make the changes. Now, since my UoWs/DbContexts are instantiated and injected by the container, where might the TransactionScope “live” and be created?

    • Hi Jim, I would imagine you would do this the same way we traditionally have done this which is make sure MTC is installed on all box’s that are participating in the transaction with the web server (e.g. if it’s a web app) along with the SQL servers, and instantiate the Transaction scope via using block and go from there. Could you let me know, if you are successful in this?

    • Btw, last I’ve touched upon this in EF5, we didn’t need to instantiate the DbContext within the using block of the TransactionScope, again, please verify this and let me know if this works.

  11. I’m in the middle of building my context(s) out, so this is a very well timed post. I will have a single-tenant database/multi-tenant application architecture (with each tenant having a different URL and possibly customization in the UI).

    One Tenant Management DB and one DB for each Tenant. I was planning on having a bounded context for each DB (as I don’t know of a way for one context to share DB — if you know how to do this — that would be amazing!) — so at some point there could be two active bounded contexts, one pointing to the Tenant Management DB and the other pointing to the Tenant customer DB.

    There may be time in which I will need to do cross-talk between the two, for example If I’m pulling up a list of Tenants (as a SaaS employee), and I want to see the number of customers a Tenant has (something along these lines).

    It would be great to see an example of communication between two different context.uow.repo.entity in a new business logic class library project, just before the web api.

    Thanks for the great post!

    • Multiple Bounded DbContext

      Bounded DbContext with Generic Unit of Work, Generic Repositories, Entity Framework 6 & EntLib Unity 3.0 in MVC 4

      http://blog.longle.net/2013/07/30/bounded-dbcontext-with-generic-unit-of-work-generic-repositories-entity-framework-6-unity-3-0-in-mvc-4/

      Fictitious (pseudo) code of Multiple UoW in Repo

      
      namespace Northwind.Service
      {
          public interface IProductService
          {
              bool ValidateProductWorkflow(Product product);
          }
      
          public class ProductService : IProductService
          {
              private readonly IUnitOfWork _customerUnitOfWork;
              private readonly IUnitOfWork _northwindUnitOfWork;
      
              public CustomerController(
                  [Dependency("NorthwindUnitOfWork")] IUnitOfWork northwindUnitOfWork,
                  [Dependency("NorthwindCustomerUnitOfWork")] IUnitOfWork customerUnitOfWork)
              {
                  _northwindUnitOfWork = northwindUnitOfWork;
                  _customerUnitOfWork = customerUnitOfWork;
              }
      
              public bool ValidateProductWorkflow(Product product)
              {
                  var supplier = _northwindUnitOfWork
                      .Repository<Supplier>()
                      .Query()
                      .Filter(
                          t => t.SupplierID == product.SupplierID
                               && t.Products.Any(u => u.ProductID == product.ProductID)
                      )
                      .Get()
                      .Single();
      
                  var supplier = _customerUnitOfWork
                      .Repository<Customer>()
                      .Query()
                      .Get()
                      .Single();
      
                  return supplier == null;
              }
          }
      }
      
      
  12. Thanks for the answer. I really appreciate the time you are spending.

    I come across one question which is
    what if I have an MVC controller which may need to leverage 2 different unit of work above that you have e.g.

    For example a scenario in which both NorthwindCustomerContext and NorthwindContext are needed.

    Do I have to create another DbContext containing the mapping I need? and just work with that.
    or
    Could I instantiate both at the same time and work with them in the controller and wrap any concurrency with TransactionScope?

  13. Thanks a lot for the post. I’ve got a question, considering following layers in my app:
    Data
    Entity
    Repository layer
    Services business layer
    UI MVC application

    Does UI layer have to be aware of DbContext in data layer or can I just hide the
    Information about context in service business layers? And how to do that

    • The UI or MVC web app, should not have any code at all with dependencies with EF e.g. DbContext and same goes for your Entity project which has all of your POCO’s. It should only know of the UnitOfWork. You shouldn’t even need a reference to EF for that matter, it should only be copied to your bin directory for your connection string providerName e.g. providerName=”System.Data.SqlClient”.

      You do this by simply referencing the Repository project in your MVC app, and only interacting with the UnitOfWork with interacting with the database.

  14. Impressive work. I have been following this series and playing with your code a fair bit lately. I noticed when playing with the Web API test client, Web API help page that there appears to be an interaction between the HelpController and the Unity Setup resulting in this exception:

    The type String cannot be constructed. You must configure the container to supply this value.

    [ResolutionFailedException: Resolution of the dependency failed, type = “BISWebApi.Areas.HelpPage.Controllers.HelpController”, name = “(none)”.
    Exception occurred while: while resolving.
    Exception is: InvalidOperationException – The type String cannot be constructed. You must configure the container to supply this value.
    ———————————————–
    At the time of the exception, the container was:

    Resolving BISWebApi.Areas.HelpPage.Controllers.HelpController,(none)
    Resolving parameter “config” of constructor BISWebApi.Areas.HelpPage.Controllers.HelpController(System.Web.Http.HttpConfiguration config)
    Resolving System.Web.Http.HttpConfiguration,(none)
    Resolving parameter “routes” of constructor System.Web.Http.HttpConfiguration(System.Web.Http.HttpRouteCollection routes)
    Resolving System.Web.Http.HttpRouteCollection,(none)
    Resolving parameter “virtualPathRoot” of constructor System.Web.Http.HttpRouteCollection(System.String virtualPathRoot)
    Resolving System.String,(none)

    Nuget version wise I am using the following libraries. Curious if you have run into this yourself or if any of the readers have seen something similar. I haven’t found a Unity configuration around this exception yet.

    • Yikes the comment posts added the Nuget versions as HTML. :-/ What I get I suppose for cutting and paste from packages.config.

      Microsoft.AspNet.WebApi.HelpPage”version=”4.0.30506″

      Unity version=”3.0.1304.0″
      Unity.AspNet.WebApi version=”3.0.1304.0″
      Unity.Interception version=”3.0.1304.0″
      Unity.Mvc version=”3.0.1304.0″

    • Hi Ken, thx for the postive feedback, could you paste in all the constructors for the HelpController? It appears that the problem is that Unity is unable to resolve the HelpController with a constructor with parameters.

    • You are correct. The code is from the HelpPage nugget package and the issue is indeed how to select the correct controller. It’s just the boilerplate code from the MVC4 template via PU2.

      [InjectionConstructor]
      public HelpController()
      : this(GlobalConfiguration.Configuration)
      {
      }

      public HelpController(HttpConfiguration config)
      {
      Configuration = config;
      }

      [InjectionConstructor] works around the issue but being new to Unity (sadly) I am now looking into how to specify this elsewhere or if there is a better way to configure the container at startup. Any developer using your most excellent blog series that wants to use this technique with ASP.NET Web API will run into this issue. :-)

      -Ken

    • Quick question, the exception says a problem with injecting constructor parameter config which I see is the HelpController(HttpConfiguration config) constructor, however I see that the paramaterless constructor HelpController is the one marked with the [InjectionConstructor] attribute, which constructor do you need to be invoked by Unity (container)?

    • In this case the parameterless one. Only because it appears this constructor is used in normal operation verified by watching execution outside of this project to see what was involved for simply navigating to http:///help (right click new project, F5, navigate to help to see what is normally used). Again this is boilerplate code written by the ASP.NET team using ApiExplorer to generate docs for the Web API code which is why I don’t wish to modify it.

      To be clear I added the [InjectionConstructor] attribute to get around the exception. I am hoping I can remove it and instead find a better way to specify the appropriate constructor in the UnityMvcActivator for example.

    • You have two options:

      Option 1: add this binding (registration):

      container.RegisterType<HelpController>(new InjectionConstructor(GlobalConfiguration.Configuration));
      

      Option 2: add this binding (registration):

      container.RegisterType<HelpController>(new InjectionConstructor());
      

      Please remove any attributes that were added to the HelpController, make sure there are no changes to it, and it is as it was from the VS Template.

      Either of these should work, preferably go with Option 2, which is the default behavior to begin with.

    • Hi Ken,

      You said the following:

      “Now if only I have find a T4 template to bend to my will to shape the Data Mappings and Entities. Simon Huge’s Reverse POCO template comes close with a few modifications. J”

      I’m currently working through this code/post and I’m also using Simon Huge’s Reverse POCO template. There is a fork of this template that allows for the exclusion of generated types. For example you can exclude mappings or entities. I’m using this fork to generate my mappings in the data layer and entities in my model layer.

      Also, looking a Le’s code, he made a change to the entities and mappings by applying State. It’s difficult to extend via partial classes the configuration of the auto-generated mappings (configuration) when everything is init in the constructor — and of course there is no partial constructors.

      Before the mappings classes, while partial were also internal — with no option to change this.

      So in addition to using the fork I mentioned, I changed the T4 to allow for public partial configuration classes and the addition of a OnInit() in the constructor so I could add the addition of Ignore State in the configuration — otherwise we are really locked down on what we can do with the configuration files.

      Anyhow, if you’re interested I can post the changes I’ve made that allow me to take advantage of Le’s setup and use Simon Huge’s T4 code.

    • Aaron, thank you for your thoughtful comments. I would be interested in seeing your extensions to Simon’s work which it appears Le maybe be incorporating into this posting. Your idea on moving the State property to a separate partial class is also a great idea.

    • Aron,

      Yes, could you please reply and post the your version of the T4 templates of Simon Huge’s T4 implantation with the UoW and Repo setup we have here. Would like to take a look, and I’m sure some of the readers here might be able to leverage this, especially when dealing with large databases to generate there POCO entities. Question, does this also generate the EF entity mappings as well?

    • Hi Le,

      I just emailed you the T4 template. Just add them to your project and when you save the .tt file, it will attempt to read you connection string so forth.

      Yes, it has the ability to generate POCOs (Entities), Context/IContext, Configuration (Mappings).

      Also, you have the option to make the classes partial.

      With the version you have, you can selectively choose which out of these you want to generate. For example, I don’t want the POCOs generated in my Data project, but I do want them generated in my Model project.

      Also, in the version you have, you can make the Configuration (Mappings) classes internal or public and choose if you want to add an OnInit() to the constructor.

      The reason you would want to do this is as follows:

      I have the Entities generated in the Model dll, and this project includes the State property which the Entities add through partial classes. Also they inherit from — i think it’s called IObjectState. I don’t want the State property to propigate to the DB, so I need to use Fluent API to Ignore the State property. The default for the template was to make the Configuration (Mapping) classes Internal. That cause me to have to add the Entities to the same project or they could not see the new State property of the Entities. I changed this to public, and now you can separte the Configuration from the Entities.

      Also, since the Configuration (Mappings) are set in the constructor (for example Ignore(x => x.State), and there is no partial constructors, even though the Configuration classes generated where partial, I could not extend them properly. So I added an option to place a public partial OnInit() method to the constructor of the generated Configuration (Mappings) classes. This way in the non-generated public partial class Customer, I could add the implementation of OnInit(), which in my case (and per your example) was this.Ignore(x => x). This way when the Context was build and passed in the Configuration constructor, the State would get ignored.

      Thanks!

    • Thanks Aron, once I’ve looked at these, are you OK with me uploading them and making them available to any other readers that may find these handy?

Please Leave a Reply or Tweet me @LeLong37...!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s