4

我有一個asp.net web api應用程序,它使用來自MS Unity.AspNet.WebApi和Unity nuget包的Unity依賴注入庫。此外,該應用程序使用實體框架版本6數據庫上下文爲ORM和通用資源庫。我是否使用正確的生命週期管理器進行依賴注入?

Api控制器使用自定義服務類型。自定義服務類使用EF數據庫上下文和通用存儲庫。

我的問題是:HierarchicalLifetimeManager和ContainerControlledLifetimeManager正確的生命週期管理器爲我的web API應用程序?

代碼在UnityConfig類我的應用程序:

using System; 
    using System.Configuration; 
    using System.Data.Entity; 
    using Microsoft.Practices.Unity; 
    using Microsoft.Practices.Unity.Configuration; 
    using App.Api.Models; 
    using App.Dal; 

    public class UnityConfig 
     { 
      #region Unity Container 
      private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => 
      { 
       var container = new UnityContainer(); 
       RegisterTypes(container); 
       return container; 
      }); 

      /// <summary> 
      /// Gets the configured Unity container. 
      /// </summary> 
      public static IUnityContainer GetConfiguredContainer() 
      { 
       return container.Value; 
      } 
      #endregion 

      /// <summary>Registers the type mappings with the Unity container.</summary> 
      /// <param name="container">The unity container to configure.</param> 
      /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
      /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks> 
      public static void RegisterTypes(IUnityContainer container) 
      { 

       var connectionStringEntityFramework= ConfigurationManager.ConnectionStrings["AppEntities"].ToString(); 


      // Entity Framework database context and generic repository 
// HierarchicalLifetimeManager is used: 

       container.RegisterType<DbContext, FirstAngularJsEntities>(new HierarchicalLifetimeManager(), new InjectionConstructor(connectionStringFirstAngularJsEntities)); 
       container.RegisterType<IRepository, GenRepository>(new HierarchicalLifetimeManager(), new InjectionConstructor(typeof(DbContext))); 


       // services 
// ContainerControlledLifetimeManager is used: 

       container.RegisterType<IContactService, ContactService>(new ContainerControlledLifetimeManager()); 
       container.RegisterType<IProductService, ProductService>(new ContainerControlledLifetimeManager()); 

      } 

樣本API控制器已經在其構造注入定製服務:

public class ContactApiController : ApiController 
    { 
     private readonly IContactService _contactService; 

     public ContactApiController(IContactService contactService) 
     { 
      _contactService = contactService; 
     } 

... 
} 

樣本定製服務有EF的DbContext和存儲庫中注入它的構造函數:

public class ContactService : IContactService 
    { 
     private readonly IRepository _repo; 
     private readonly DbContext _context; 


     public ContactService(DbContext context, IRepository repo) 
     { 
      _context = context; 
      _repo = repo; 

     } 

... 
} 

回答

4

使用ContainerControlledLifetimeManager你會得到你的服務的單身人士。一個很長一段時間(直到IIS回收)。 HierarchicalLifetimeManager與子容器一起使用 - 爲每個子容器創建對象的新實例,因此您不再創建子容器,它就像單身人士一樣工作:) WebApi應用的最佳方式是使用PerRequestLifetimeManager。 爲Api的每個請求創建新實例。

+0

感謝您的回覆。所以PerRequestLifetimeManager用於WebApi應用程序。 ContainerControlledLifetimeManager和HierarchicalLifetimeManager用於哪些類型的應用程序? 2名終生管理者是單身人士;可能會出現陳舊的數據問題,對不對? –

+0

@ Thomas.Benz ContainerControlledLifetimeManager用於長時間(從應用程序的開始到結束)的靜態對象。 'HierarchicalLifetimeManager'與子容器一起使用。例如,當你運行一個子進程時,你可以創建一個子容器,這個進程會得到它自己的類的實例。 – Backs

+0

對不起,雖然是一種痛苦,但「最好的方式」可能取決於依賴需要什麼而不是說'PerRequestLifetimeManager'對所有的WebAPI都是最好的。可能有很多情況下,最好的辦法是每次創建一個單獨的實例,其他人最好的方式是使用單例。 – BenCr

1

我傾向於將此視爲與您正在嘗試執行的語義兼容的最短生命週期,默認生命週期爲瞬態,除非另有要求。

  1. 的DbContext保持狀態,所以我們需要對請求一致,從而PerRequest或Hierachic
  2. Repository是/應該是無狀態的,因爲它的狀態是的DbContext,因此瞬變
  3. 服務是/應該是無狀態如此瞬態與分層式而非PerRequest去

的一個原因是,PerRequest經理不Owin發揮好,見http://www.reply.com/solidsoft-reply/en/content/managing-object-lifetimes-with-owin-and-unity,你需要編寫一些清理中間件更換的HttpModule

相關問題