2011-06-15 67 views
2

我使用Unity MVC3代碼http://unitymvc3.codeplex.com/爲我的IUnitOfWork的每個請求實例創建NHibernate會話。MVC 3,Unity 2 - 每個請求生命週期管理器

它幾個星期前工作,我做了一些更改,現在我的IUnitOfWork似乎有一個靜態的生命週期。

從我的global.asax.cs:

private static IUnitOfWorkFactory _UoWFactory = new UnitOfWorkFactory(Enums.Databases.MyDBName) 
                  .AddMapping<DepartmentMap>() 
                  .CompleteConfiguration(); 

/// <summary> 
/// Configure Unity Application Block 
/// </summary> 
private void ConfigureUnity() 
{ 
    CIUnity.UnityContainer.Container = new UnityContainer() 
     .RegisterType(typeof(IRepository<>), typeof(Repository<>)) 
     .RegisterType<IUnitOfWork, UnitOfWork>(Enums.Databases.MyDBName.ToString(), new HierarchicalLifetimeManager(), new InjectionConstructor(Enums.Databases.MyDBName)) 
     .RegisterInstance<IUnitOfWorkFactory>(Enums.Databases.MyDBName.ToString(), _UoWFactory); 

    DependencyResolver.SetResolver(new UnityDependencyResolver(CIUnity.UnityContainer.Container)); 
} 

ConfigureUnity()從我Application_Start()

下面有我的測試代碼中調用從我的HomeController構造函數:

private IUnitOfWork uow; 
private IUnitOfWork uow2; 

public HomeController() 
{ 
    uow = CIUnity.Container.Resolve<IUnitOfWork>(Enums.Databases.MyDBName.ToString()); 
    IRepository<Employee> repo = uow.GetRepository<Employee>(); 

    uow2 = CIUnity.Container.Resolve<IUnitOfWork>(Enums.Databases.MyDBName.ToString()); 
    IRepository<Department> deptrepo = uow2.GetRepository<Department>(); 

    var q = from a in repo.Find() 
      select a; 

    var d = from b in deptrepo.Find() 
      select b; 
} 

...的IUnitOfWork解析爲相同的實例,但是,在後續的頁面請求中,不會創建新的IUnitOfWork ...但代碼有效,所以它以某種方式regi測量/拉動物體,使其靜止。

回答

2

我會得到完全擺脫IUnitOfWorkFactory的,只是注入IUnityOfWork到您的控制器 - 提供您只想要求每一個工作單元,這似乎合乎邏輯的。然後,您將更多地利用IoC容器的力量,而不僅僅將其用作服務定位器。

只要改變你的HomeController構造函數:

public HomeController(IUnitOfWork unitOfWork) 
{ 
    IRepository<Employee> repo = unitOfWork.GetRepository<Employee>(); 

    IRepository<Department> deptrepo = unitOfWork.GetRepository<Department>(); 

    ... 
} 

如果你還沒有這樣做,加:

CIUnity.Container.RegisterControllers(); 

你叫DependencyResolver.SetResolver

之前當MVC核心試圖實例化你的控制器,它將使用Unity.MVC3解析器,它將自動滿足在這種情況下意味着unitOfWork的任何依賴關係。

Unity.MVC3解析器還會在請求結束時自動處理您的工作單元。

+0

感謝您的意見。我在工廠背後的推理是因爲我們可能需要爲每個請求(每個數據庫一個)提供多個工作單元/ ISessions - 因此IUnitOfWork的指定註冊背後的原因。我最終的計劃是將業務層的IService對象注入到控制器中。 – 2011-06-16 12:37:07

+0

@Chris - 我看不到工廠在代碼示例中如何使用。控制器構造函數只是通過靜態容器解析存儲庫。有什麼缺失? – MangoBrainz 2011-06-16 13:35:09

0

它看起來像你想UnitOfWorkFactory返回你的IUnitOfWork依賴?看起來像你應該使用.RegisterFactory來實現這一點。您可以使用ContainerControlledLifetimeManager註冊工廠,並且它將表現爲「單例」而不訴諸靜態成員。

生命週期管理可以用WCF(也可能是網絡)有點棘手。我一直在使用本文中的代碼很長一段時間。它完美地將Unity生命週期映射到WCF請求生命週期......它可能會給你一些關於如何最好地實現你的目標的想法。

http://drewdotnet.blogspot.com/2009/07/unity-lifetime-managers-and-wcf.html