Unity framework - creating and removing Entity Framework datacontexts at the appropriate time

With any StackOverflow help, I have a Unity Framework for creating bound dependencies, including an entity Framework datacontext object:

using (IUnityContainer container = new UnityContainer()) { container.RegisterType<IMeterView, Meter>(); container.RegisterType<IUnitOfWork, CommunergySQLiteEntities>(new ContainerControlledLifetimeManager()); container.RegisterType<IRepositoryFactory, SQLiteRepositoryFactory>(); container.RegisterType<IRepositoryFactory, WCFRepositoryFactory>("Uploader"); container.Configure<InjectedMembers>() .ConfigureInjectionFor<CommunergySQLiteEntities>( new InjectionConstructor(connectionString)); MeterPresenter meterPresenter = container.Resolve<MeterPresenter>(); 

this works very well when creating a Presenter object and displaying the corresponding view, I am very pleased.

However, the problem I'm currently facing is related to the timing of creating and deleting an Entity Framework object (and I suspect that this will work for any IDisposable object). Using Unity, this CommunergySQLiteEntities SQL EF object is instantiated as I added its interface, IUnitOfWork, to the MeterPresenter constructor

  public MeterPresenter(IMeterView view, IUnitOfWork unitOfWork, IRepositoryFactory cacheRepository) { this.mView = view; this.unitOfWork = unitOfWork; this.cacheRepository = cacheRepository; this.Initialize(); } 

I was a little embarrassed at the time, since I did not want to open a database connection, but I could not see another way to use Unity dependency injection. Of course, when I really try to use the datacontext, I get this error:

  ((System.Data.Objects.ObjectContext)(unitOfWork)).Connection '((System.Data.Objects.ObjectContext)(unitOfWork)).Connection' threw an exception of type 'System.ObjectDisposedException' System.Data.Common.DbConnection {System.ObjectDisposedException} 

My understanding of the IoC principle is that you configure all your dependencies at the top, resolve your object, and leave. However, in this case, some child objects, such as a datacontext, should not be initialized at the time the parent Presenter object is created (as you would by passing them in the constructor), but Presenter really needs to know what type to use for IUnitOfWork when it wants to talk to database.

Ideally, I want something like this inside my authorized Lead:

 using(IUnitOfWork unitOfWork = new NewInstanceInjectedUnitOfWorkType()) { //do unitOfWork stuff } 

So, the facilitator knows which IUnitOfWork implementation to use to create and delete immediately, preferably from the original RegisterType call. Should I put another Unity container inside my presenter, risking creating a new dependency?

This is probably really obvious to the IoC guru, but I really appreciate the pointer in the right direction.

+6
inversion-of-control unity-container
source share
3 answers

You do not need to worry about initializing the ObjectContext at the same time as creating the presenter - the ObjectContext does not support connecting to the database. Rather, it opens connections as needed, when it really needs to talk to the database, that is, when you execute a query or commit changes and close the connection again as soon as it is completed. It will close the connection only if you explicitly open it, which is rare with the Entity Framework.

If you get an ObjectDisposedException using the ContainerControlledLifetimeManager , then this means that your container is in front of the presenter, which is a design error. It's not entirely clear what your environment is (ASP.NET? Winforms?), But the ContainerControlledLifetimeManager is probably not suitable here, as it works as a Singleton instance. Usually you really want to create a new instance of the context when resolving the type - there are many problems that you can accomplish, and you will run into it if you use a singleton instead.

So - I would get rid of the ContainerControlledLifetimeManager here, and also make sure your container is not being disposed of too early; the fact that it in the using block indicates that this is probably the cause of your ObjectDisposedException . (You still need to get rid of the container in the end, of course, simply because you are probably doing something like creating a modeless form that stays alive even after the control leaves the using ).

+4
source share

Why don't you just remove IUnitOfWork from the constructor and instead enter the unity container? Therefore, you will have the flexibility of calling container.Resolve<IUnitOfWork>() anywhere in your code, if necessary.

Example:

 using(IUnitOfWork unitOfWork = container.Resolve<IUnitOfWork>()) { //do unitOfWork stuff } 

Remember to set the instance lifetime to single.

Michael

+2
source share

I know this question is old, but I would still like to give 2 cents here.

You can register the UnitOfWork abstraction as a rule, but request Func<IUnitOfWork> in your class instead of an instance. This is a neat feature of Unity in fact, the ability to allow delegates who create your object, and not immediately receive the object.

Thus, you can do what you wanted, i.e. manage the scope of work inside your method.

In short:

 container.RegisterType<IUnitOfWork, CommunergySQLiteEntities>(); ... public MeterPresenter(IMeterView view, Func<IUnitOfWork> unitOfWorkFactory, IRepositoryFactory cacheRepository) { this.mView = view; this.unitOfWorkFactory = unitOfWorkFactory; this.cacheRepository = cacheRepository; this.Initialize(); } ... using(IUnitOfWork unitOfWork = unitOfWorkFactory()) { //do unitOfWork stuff } 

I have used this several times already, and I personally recommend it, since you still have full control over everything, including a mockery of unit testing, while at the same time not linking your code with anything other than its dependencies.

You can create an IUnitOfWorkFactory interface and paste instead if you need more complex logic, but the Func<T> delegate is enough in most cases.

0
source share

All Articles