2014-09-30 59 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,所以沒有得到相關的錯誤,還可以通過許多參數如我所願,通過使用我的工廠。

相關問題