2014-09-30 55 views
1

Repositiory,OrderRequestRepository.cs统一的WebAPI的DbContext,但不能正常工作

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())); 

随着UnityConfig.cs的上面的行首先调用api工程,第二次调用失败,出现错误:

该操作无法完成因为DbContext已经被处置。

如果我注释掉_context.Dispose()线,那么它的工作原理,这是很好的垃圾回收将清理对我来说,理想的情况我想管理它自己。

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

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

但我想用InjectionConstructor因为我想另一个参数添加到OrderRequestRepository构造管理处置。关于为什么两者都会导致错误的任何建议?

更新

我删除了IDisposable代码,由史蒂芬的建议,因为

  1. 一般的规则是,谁创建对象的一个​​应该毁掉它,所以我会单独留下我的EF dbcontext(IntranetApplicationsContext)。

  2. IoC容器(Unity.Webapi在我的情况)应该处理处置

因此,与这条线在UnityConfig

container.RegisterType<IOrderRequestRepository, OrderRequestRepository> (new InjectionConstructor(new IntranetApplicationsContext(), new ElmahLogger())); 

与EF读取正在努力,但有趣的是,当我尝试编辑我得到以下错误:

Attaching an entity of type 'IntranetApplications.Infrastructure.Models.OrderRequest' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

如果我回滚并使用b在UnityConfig asic线

container.RegisterType<IOrderRequestRepository, OrderRequestRepository>(); 

...一切正常。我相信这两条线都使用了相同的默认生命期管理器TransientLifetimeManager,因此使用InjectionConstructor似乎仍然会破坏事情很奇怪。

回答

1

这里的问题是,你的OrderRequestRepository正在处置它不拥有的东西。 IntranetApplicationsContext被注入存储库,并且由于OrderRequestRepository不知道该依赖关系的生活方式是什么,所以它不能处理它。

您可能注册了IntranetApplicationsContext以获得每个请求的生活方式,而您的存储库是暂时的。

解决方案:如果您有任何需要处理的地方,请仅实施IDisposable。在你的情况下,这意味着你的存储库根本不需要IDisposable。

1

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

我用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(); 
    } 
} 

UnityConfig

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

这工作,因为,我没有使用InjectionConstructor,所以没有得到相关的错误,还可以通过许多参数如我所愿,通过使用我的工厂。

相关问题