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

相关问题