2015-02-11 73 views
11

我正在努力完成這項工作。我已經得到了統一和Unity.AspNet.WebApi包(V 1404年3月5日)安裝並低於其附帶的軟件包使用WebApi中的Unity解決每個請求的dbcontext

public static class UnityWebApiActivator 
{ 
    /// <summary>Integrates Unity when the application starts.</summary> 
    public static void Start() 
    { 
     var container = UnityConfig.GetConfiguredContainer(); 
     var resolver = new UnityHierarchicalDependencyResolver(container); 

     GlobalConfiguration.Configuration.DependencyResolver = resolver; 

     // DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule)); 
    } 

    /// <summary>Disposes the Unity container when the application is shut down.</summary> 
    public static void Shutdown() 
    { 
     var container = UnityConfig.GetConfiguredContainer(); 
     container.Dispose(); 
    } 
} 

和我的類型註冊激活代碼如下所示:

public static void RegisterTypes(IUnityContainer container) 
     { 
      container.RegisterType<IAuditService, AuditService>(
       new PerThreadLifetimeManager(), 
       new InjectionConstructor(new SecurityDbContext())); 
     } 

到目前爲止,我嘗試過PerThreadLifetimeManager和TransientLifetimeManager,但沒有成功。我也得到了Unity.Mvc包,並嘗試使用MSDN建議的PerRequestLifetimeManager,但沒有運氣。它總是給我同樣的dbcontex實例。

我寧願不包括任何MVC依賴,因爲這純粹是WebApi,但是當我嘗試使用Unity.Mvc時,我也結束了一些http運行時錯誤。

任何人都有一個很好的建議/例子解決dbcontext每個請求與WebApi中的Unity,最好沒有任何mvc依賴?

回答

12

我注入db上下文的方式是這裏的問題。 Unity會記住創建的實例併爲所有創建的新AuditService實例注入相同的實例。我只需要解決如下所示的數據庫上下文。

container.RegisterType<DbContext, SecurityDbContext>(new PerThreadLifetimeManager()); 

PerThreadLifetimeManager做的工作,它應該很好,考慮到每個Web請求將由不同的線程服務。

+0

無法獲取此'SecurityDbContext'。這是一個自定義的繼承Dbcontext類的類嗎? – picnic4u 2016-05-16 19:07:25

+0

是SecurityDbContext繼承DbContext,它是通過覆蓋OnModelCreating方法添加EF映射的地方。 – Otake 2016-05-22 13:02:26

+0

@Otake如何在控制器上聲明它以使其工作? Tks – Pascal 2016-08-11 21:22:52

1

我設法通過在WebApiConfig類中聲明我的自定義UnityResolver類來解決每個請求。假設您使用OWIN上下文,UnityResolver類使用HttpConfiguration類。

public static void Register(HttpConfiguration config) 
     {  
      // Web API configuration and services 
      var _container = new UnityContainer(); 
      DependencyConfiguration.ConfigureContainer(_container); 
      config.DependencyResolver = new UnityResolver(_container); 
     } 

的ConfigureContainer類只是這裏我宣佈我的IOC依賴如下圖所示的類:

private static void RegisterReleaseEnv(IUnityContainer container) 
     { 
      //Repository Registration 
      container    
       .RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager()); 

     } 

這是非常重要的,你使用HierarchicalLifetimeManager壽命經理,讓你得到每一個新的實例請求。

的UnityResolver類則是這樣的:

public class UnityResolver : IDependencyResolver 
    { 
     protected IUnityContainer container; 

     public UnityResolver(IUnityContainer container) 
     { 
      if (container == null) 
      { 
       throw new ArgumentNullException("container"); 
      } 
      this.container = container; 
     } 

     public object GetService(Type serviceType) 
     { 
      try 
      { 
       return container.Resolve(serviceType); 
      } 
      catch (ResolutionFailedException) 
      { 
       return null; 
      } 
     } 

     public IEnumerable<object> GetServices(Type serviceType) 
     { 
      try 
      { 
       return container.ResolveAll(serviceType); 
      } 
      catch (ResolutionFailedException) 
      { 
       return new List<object>(); 
      } 
     } 

     public IDependencyScope BeginScope() 
     { 
      var child = container.CreateChildContainer(); 
      return new UnityResolver(child); 
     } 

     public void Dispose() 
     { 
      container.Dispose(); 
     } 
    } 

然後我得到一個使用通用Repistory一個新的數據庫上下文,如下圖所示:

public class GenericRepository<TEntity> : IRepository<TEntity>, IDisposable where TEntity : class 
{ 
    internal BackendContainer context; 
    internal DbSet<TEntity> dbSet; 

    public GenericRepository(BackendContainer context) 
    { 
     this.context = context; 
     this.dbSet = context.Set<TEntity>(); 
    } 

    public GenericRepository() 
     : this(new BackendContainer()) 
    { 
    } 


    public virtual IQueryable<TEntity> All() 
    { 
     return dbSet.AsQueryable(); 
    } 
} 

因爲團結解析器,通用倉庫的每個請求都實例化,DbContext(BackendContainer)也是如此。

我希望這會有所幫助。

欲瞭解更多信息:http://www.asp.net/web-api/overview/advanced/dependency-injection

相關問題