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.
![]() |
Example: Potential Bounded DbContext’s in AdventureWorks based on SQL schemas defined.
|
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
Spa.App_Start.UnityConfig.cs – Unity 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
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.
Hi Long,
The first I think you are vietnamese, right? ^^.I’ve research Kendo UI and angularjs with ui-routeer.And I got he problem with Tabstrip,I spent 3 days but still not found the solution how to used Tabstrip Angular of Kendo UI and ui-router.Do you have any advices?
Thanks,
Loi Tran
LikeLike
Yes, I’m Vietnamese.
You should be using the AngularJS $routeProvider, meaning your application should really be using AngularJS for things (architecture) other than your widgets, which should Kendo UI.
LikeLike
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.
LikeLike
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.
LikeLike
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.
LikeLike
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.
LikeLike
Yes it supports async with the latest release, you can get the the newest additions in the main branch https://genericunitofworkandrepositories.codeplex.com/SourceControl/latest#main/
LikeLike
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
LikeLike
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.
LikeLike
thanks , learned something new , but I prefer not using queries at all , i’m addicted to code first 🙂
LikeLike
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;
}
LikeLike
Typo in the above… the container registration should be:
container.RegisterType(new InjectionConstructor(
new ResolvedParameter(“NorthwindUnitOfWork”),
new ResolvedParameter(“NorthwindCustomerUnitOfWork”));
LikeLike
WordPress doesn’t like generic types 🙂 Let’s try that again:
container.RegisterType(new InjectionConstructor(
new ResolvedParameter(“NorthwindUnitOfWork”),
new ResolvedParameter(“NorthwindCustomerUnitOfWork”));
LikeLike
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
LikeLike
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!
LikeLike
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.
LikeLike
I like the helpful information you provide in your articles.
I’ll bookmark your weblog and check again here regularly.
I’m quite certain I will learn plenty of new
stuff right here! Best of luck for the next!
LikeLike
Is there any possibility of getting an example with Ninject as the DI Framework
Looking forward to it
Thanks
LikeLike
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.
LikeLike
How about Unit Testing with Microsoft Fakes?
I tried, but ran into complications.
Most samples assumes an IRepository instead of IUnitofWork.
LikeLike
Have you thought about creating an Async Repository or adding Async methods to your repository?
LikeLike
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. 🙂
LikeLike
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.
LikeLike
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?
LikeLike
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);
}
LikeLike
Hey Ivan, could you provide me with an email address?
LikeLike
Looks promising, will let you know when I’ve uploaded to GitHub.
LikeLike
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!
LikeLike
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!
LikeLike
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.
LikeLike
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.
LikeLike
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.
LikeLike
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?
LikeLike
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?
LikeLike
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.
LikeLike
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!
LikeLike
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
LikeLike
Is it a typo or error. You’re constructor is CustomerController
LikeLike
Hi Le! You’re article really help me a lot. I have almost the same situation as Aaron where I have multiple DatabaseContext and I am only injecting services in the controller. But in my case, I will not allow the Service Layer “A” talk to Service Layer “B” project (both have different DB). They will be both use by the MVC app. I am injecting my UnitOfWork in the service layer. I have the following code
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType( “NorthwindContext”, new PerRequestLifetimeManager());
container.RegisterType(“NorthwindCustomerContext”, new PerRequestLifetimeManager() );
}
public class CustomerService : ICustomerService
{
private readonly IRepository _customerRepository;
}
I have encountered this error
“The type IDataContext does not have an accessible constructor.”
I think I am missing something on defining the dependency with IDataContext but I don’t know how to. Can you please help me. Pretty please (^_^)
LikeLike
this link helped me with my concern –> http://stackoverflow.com/questions/21455981/unity-injection-of-multiple-perresolvelifetimemanager-registered-types
LikeLike
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?
LikeLike
The ladder (second) option, just use two UoW within the same controller.
LikeLike
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
LikeLike
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.
LikeLike
How will I remove the dependency of my MVC app in EntityFramework if I registered the IDbContext to the NorthWindContext? I am really sorry if I keep on asking. I really like to learn this good stuffs.
LikeLike
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.
LikeLike
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″
LikeLike
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.
LikeLike
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
LikeLike
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)?
LikeLike
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.
LikeLike
You have two options:
Option 1: add this binding (registration):
Option 2: add this binding (registration):
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.
LikeLike
Ken, please let me know if that worked for you.
LikeLike
Yes it worked (either option, went with 2). Thanks!
LikeLike
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.
LikeLike
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.
LikeLike
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?
LikeLike
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!
LikeLike
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?
LikeLike
No problem Le, Just let me know if I can help somehow.
LikeLike