private readonly ILogger _logger; private readonly IRepository _repository; public HomeController(ILogger logger,IRepository repository) { _logger = logger; _repository = repository; }
这是存储库:
public class EfRepository : IRepository { // ...methods for add,delete,update entities // .... public void dispose() { if (this._context != null) { this._context.SaveChanges(); (this._context as Idisposable).dispose(); this._context = null; } } }
最后,IoC中的注册类型:
_builder.RegisterType<Logger>().As<ILogger>(); _builder.RegisterType<EfRepository>().As<IRepository>().WithParameter("context",new PcpContext());
当我运行应用程序时,我收到此错误:
The operation cannot be completed because the DbContext has been
disposed.
我试着像这样改变注册EfRepository:
_builder.RegisterType<EfRepository>() .As<IRepository>() .WithParameter("context",new PcpContext()).InstancePerLifetimeScope();
解决方法
使用当前代码,在处理IRepository实例时,它还将释放该PcpContext实例.然后,任何后续尝试解析IRepository都将接收已处置的PcpContext实例.您需要一种方法在每个Http请求上接收一个新的EF DbContext实例,该请求在请求结束时处理.
一种选择可以是为IRepository注册代码块,以便每次需要解析IRepository时执行代码块:
_builder.Register<IRepository>(c => new EfRepository(new PcpContext()))
一个更好的选择是创建一个新的IDatabaseContext抽象,更新EfRepository,因此它依赖于新的IDatabaseContext抽象而不是PcpContextclass(可能已经是这种情况:)).
IDatabaseContext的实现类将是您的PcpContext类,它必须从EF DbContext继承并可能接收连接字符串作为参数.
public class EfRepository : IRepository { private readonly IDatabaseContext _context; public EfRepository(IDatabaseContext context) { _context = context; } ...methods for add,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,update entities } public class PcpContext: DbContext,IDatabaseContext { public EntityFrameworkContext(string connectionString) : base(connectionString) { } ...methods exposing EF for add,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 }
使用IoC容器并将生命周期管理负担留给他们的想法变得更好.现在,您的Repository类不需要是一次性的,也不需要管理和处理其IDatabaseContext依赖项. Autofac将跟踪上下文实例并在适当时处理它.
出于同样的原因,您可能希望将InstancePerLifetimeScope与数据库上下文相关性一起使用.这意味着在同一个Http请求中为每个存储库实例共享相同的EF上下文,并在请求结束时进行处理.
_builder.RegisterType<EfRepository>() .As<IRepository>(); _builder.RegisterType<PcpContext>() .As<IDatabaseContext>() .WithParameter("connectionString","NameOfConnStringInWebConfig") .InstancePerLifetimeScope();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。