When using the WithParameter method, the parameter instance will be the same for every resolved object. So with .WithParameter("context", new PcpContext())
you are effectively using the same instance of the PcpContext class for any resolved instance of IRepository.
With your current code, when an IRepository instance is disposed, it will also dispose that PcpContext instance. Then any subsequent attempt to resolve an IRepository will receive the PcpContext instance that was disposed. You need a way to receive a fresh new instance of the EF DbContext on each Http Request that is disposed of at the end of the request.
One option could be to register a code block for the IRepository so that code block is executed every time an IRepository needs to be resolved:
_builder.Register<IRepository>(c => new EfRepository(new PcpContext()))
A better option would be to create a new IDatabaseContext
abstraction, updating EfRepository
so it depends on the new IDatabaseContext abstraction instead of the PcpContext
class (Which may already be the case :) ).
The implementation class for IDatabaseContext will be your PcpContext class, which must inherit from the EF DbContext and probably receive the connection string as a parameter.
public class EfRepository : IRepository
{
private readonly IDatabaseContext _context;
public EfRepository(IDatabaseContext context)
{
_context = context;
}
...methods for add, delete, update entities
//There is no longer need for this to be disposable.
//The disaposable object is the database context, and Autofac will take care of it
//public void Dispose()
}
public interface IDatabaseContext : IDisposable
{
... declare methods for add, delete, update entities
}
public class PcpContext: DbContext, IDatabaseContext
{
public EntityFrameworkContext(string connectionString)
: base(connectionString)
{
}
...methods exposing EF for add, delete, update entities
//No need to implement IDisposable as we inherit from DbContext
//that already implements it and we don′t introduce new resources that should be disposed of
}
This gets better with the idea of using an IoC container and leaving the burden of lifetime management to them. Now your Repository class does not need to be disposable nor needs to manage and dispose of its IDatabaseContext dependency. It is Autofac who will keep track of the context instance and dispose of it when appropriate.
For the same reason, you probably want to use InstancePerLifetimeScope with the database context dependency. That would mean the same EF context is shared for every repository instance on the same Http request and is disposed at the end of the request.
_builder.RegisterType<EfRepository>()
.As<IRepository>();
_builder.RegisterType<PcpContext>()
.As<IDatabaseContext>()
.WithParameter("connectionString", "NameOfConnStringInWebConfig")
.InstancePerLifetimeScope();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…