C# Unity WebApi DbContext在使用InjectionConstructor时被释放,但在没有它的情况下可以正常工作

C# Unity WebApi DbContext在使用InjectionConstructor时被释放,但在没有它的情况下可以正常工作,c#,asp.net-web-api,unity-container,dispose,dbcontext,C#,Asp.net Web Api,Unity Container,Dispose,Dbcontext,Repository,OrderRequestRepository.cs public OrderRequestRepository(IntranetApplicationsContext context, ILogger logger) { _context = context; _logger = logger; } ...CRUD Methods public void Dispose() { Dispose

Repository,OrderRequestRepository.cs

 public OrderRequestRepository(IntranetApplicationsContext context, ILogger logger)
    {
        _context = context;
        _logger = logger;
    }


...CRUD Methods

 public void Dispose()
    {
        Dispose(true);
    }

 protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
           _context.Dispose();
        }

        GC.SuppressFinalize(this);
    }
Unity.WebApi UnityConfig.cs

 container.RegisterType<IOrderRequestRepository, OrderRequestRepository>(new InjectionConstructor(new IntranetApplicationsContext() , new ElmahLogger()));
container.RegisterType(新的InjectionConstructor(新的intranetapplicationcontext(),新的ElmahLogger());
在UnityConfig.cs中的上述行中,对api的第一次调用起作用,第二次调用失败,出现错误:

操作无法完成,因为DbContext已被释放。

如果我注释掉了_context.Dispose()行,那么它就可以工作了,这很好,因为垃圾收集可以帮我清理,但理想情况下我希望自己管理它

或者,如果我在UnityConfig.cs中使用下面的行,而不使用InjectionConstructor,那么它也可以正常工作

container.RegisterType<ILogger, ElmahLogger>();
container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
container.RegisterType();
container.RegisterType();
但是我想使用InjectionConstructor,因为我想向OrderRequestRepository构造函数添加另一个参数并管理处置。关于为什么两者都会导致错误,有什么建议吗

更新

按照Steven的建议,我删除了IDisposable代码,因为

  • 一般的规则是,创建对象的人应该销毁它,所以我将不使用EF-dbcontext(intranetapplicationcontext)

  • IOC容器(在我的例子中是Unity.Webapi)应该处理处置

  • 因此,使用UnityConfig中的这一行

    container.RegisterType<IOrderRequestRepository, OrderRequestRepository> (new InjectionConstructor(new IntranetApplicationsContext(), new ElmahLogger()));
    
    container.RegisterType(新的InjectionConstructor(新的intranetapplicationcontext(),新的ElmahLogger());
    
    使用EF进行读取是可行的,但有趣的是,当我尝试编辑时,会出现以下错误:

    附加类型为的实体 “IntranetApplications.Infrastructure.Models.OrderRequest”失败 因为相同类型的另一个实体已具有相同的主实体 键值。使用“附加”方法或设置时可能会发生这种情况 实体的状态为“未更改”或“已修改”,如果实体处于 该图形具有冲突的键值。这可能是因为 实体是新的,尚未收到数据库生成的密钥 价值观在这种情况下,请使用“添加”方法或“添加”实体状态 跟踪图形,然后将非新实体的状态设置为 “未更改”或“修改”,视情况而定

    如果我回滚并使用UnityConfig中的基本行

    container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
    
    container.RegisterType<ILogger, ElmahLogger>();
    container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
    container.RegisterType<IOrderRequestRepositoryFactory, OrderRequestRepositoryFactory>();
    
    container.RegisterType();
    

    。。。一切正常。我相信这两行都使用相同的默认生存期管理器TransientLifetimeManager,所以奇怪的是,使用InjectionConstructor似乎仍然会破坏一些东西。

    这里的问题是,您的
    OrderRequestRepository
    正在处理它不拥有的东西。
    intranetapplicationcontext
    被注入到存储库中,由于
    OrderRequestRepository
    不知道该依赖项的生活方式是什么,因此它无法处理它

    您可能注册了
    intranetapplicationcontext
    ,以便在存储库处于暂时状态时拥有每个请求的生活方式


    解决方案:只有当您有任何东西需要自行处理时,才实现IDisposable。在您的情况下,这意味着您的存储库根本不需要IDisposable。

    我已经解决了这个问题,而不是修复错误:

    我使用InjectionConstructor以便可以传递多个参数,但作为替代方法,我对其进行了更改,以便将单个参数,即工厂对象传递给存储库

    public class OrderRequestRepository : IOrderRequestRepository
    {
        private readonly IntranetApplicationsContext _context;
        private readonly ILogger _logger;
    
        public OrderRequestRepository(IOrderRequestRepositoryFactory respositoryFactory)
        {
            _context = respositoryFactory.CreateIntranetApplicationsContext();
            _logger = respositoryFactory.CreateLogger();
        }
    
        ...
    }
    
    工厂

    public interface IOrderRequestRepositoryFactory
    {
        ILogger CreateLogger();
        IntranetApplicationsContext CreateIntranetApplicationsContext();
    }
    
    public class OrderRequestRepositoryFactory : IOrderRequestRepositoryFactory
    {
        public ILogger CreateLogger()
        {
            return new ElmahLogger();
        }
    
        public IntranetApplicationsContext CreateIntranetApplicationsContext()
        {
            return new IntranetApplicationsContext();
        }
    }
    
    单位配置

    container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
    
    container.RegisterType<ILogger, ElmahLogger>();
    container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
    container.RegisterType<IOrderRequestRepositoryFactory, OrderRequestRepositoryFactory>();
    
    container.RegisterType();
    container.RegisterType();
    container.RegisterType();
    
    这是因为我没有使用InjectionConstructor,所以不需要获取相关的错误,并且仍然可以通过使用我的工厂传递任意多的参数