Recently I was using Entity Framework with a DB first approach in an application and using the Repository pattern with Unit of Work to have easy management of DB operations.
So my repository constructor accepted an IDataContext object (IDataContext is a custom interface I had written which encapsulates the DbContext generated after adding Entity Data model. Refer sample code below.
public class RepositoryBase<TEntity> : IRepositoryBase<TEntity>
where TEntity : class
public RepositoryBase(IDataContext context)
The UnitOfWork class had a constructor that accepted the ILifetimeScope object and using this object, I was resolving the context in the constructor. I also had a couple of repositories specified as properties in this class. Refer sample code below.
public class UnitOfWork : IUnitOfWork
public UnitOfWork(ILifetimeScope scope)
this.scope = scope.
this.Context = this.scope.Resolve<IDataContext>();
public Task<int> SaveAsync()
public IRepositoryBase<SampleClass> SampleRepository
if(this.sampleClassRepository == null) this.sampleClassRepository = this.scope.Resolve<IRespositoryBase<SampleClass>>(); // Observe above line later
The code that was using this repository was something like
using(var uow = this.scope.Resolve<IUnitOfWork>())
uow.SaveAsync(); // This should actually save above new entity into DB but it wasn't saving anything.
The problem with this approach was that When I was working with the repository, Autofac initially sees that the repository object has not been created and so creates a new object by resolution by injecting a NEW CONTEXT object as it sees that repository constructor requires an IDataContext object.
So because of this issue, we end up with 2 different contexts, one which just got created while trying to access the repository and this also has the change (insert), and the other which got created while creation of UnitOfWork object. And what happens is insert action goes into repository context object and Save action works upon the UnitOfWork’s context object. Hence, nothing fails but nothing happens in DB as well.
To make sure that repositories are also using the same context as UnitOfWork, what we can do is to pass the unitOfWork’s context to the Resolve method of ILifetimeScope as shown below.
if(this.sampleClassRepository == null)
(new TypedParameter(typeof(IDataContext), this.Context));
This is present in the UnitOfWork class. And this.Context refers to unitOfWork’s context. This statement ensures that when repository instance is being created, instead of creating a new context, we’re going to reuse the context of unitOfWork and so any Save operations performed would thus perform the operations on the database as well.
Hope this helps!
Reference : http://docs.autofac.org/en/latest/resolve/parameters.html