在 WebApi 中使用 Unity 解析每个请求的 dbcontext
Resolving dbcontext per request with Unity in WebApi
我正在努力完成这项工作。我已经安装了 Unity 和 Unity.AspNet.WebApi 软件包 (v 3.5.1404) 并低于软件包
附带的激活码
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 运行时错误。
任何人都可以 suggestion/example 在 WebApi 中使用 Unity 解析每个请求的 dbcontext,最好没有任何 mvc 依赖?
我注入数据库上下文的方式就是问题所在。 Unity 会记住创建的实例并为创建的所有新 AuditService 实例注入相同的实例。我只需要如下解析数据库上下文。
container.RegisterType<DbContext, SecurityDbContext>(new PerThreadLifetimeManager());
PerThreadLifetimeManager 完成了这项工作,考虑到每个 Web 请求都将由不同的线程处理,应该没问题。
我通过在 WebApiConfig class 中声明我的自定义 UnityResolver class 来设法解决每个请求。假设您使用的是 OWIN 上下文,UnityResolver class 使用 HttpConfiguration class。
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var _container = new UnityContainer();
DependencyConfiguration.ConfigureContainer(_container);
config.DependencyResolver = new UnityResolver(_container);
}
ConfigureContainer class 只是一个 class,我在其中声明我的 IOC 依赖项,如下所示:
private static void RegisterReleaseEnv(IUnityContainer container)
{
//Repository Registration
container
.RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager());
}
使用 HierarchicalLifetimeManager 生命周期管理器非常重要,这样每个请求都会获得一个新实例。
UnityResolver class 看起来像这样:
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();
}
}
然后我使用 Generic 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();
}
}
由于 Unity 解析器,通用存储库根据请求实例化,DbContext (BackendContainer) 也是如此。
希望对您有所帮助。
更多信息:http://www.asp.net/web-api/overview/advanced/dependency-injection
我正在努力完成这项工作。我已经安装了 Unity 和 Unity.AspNet.WebApi 软件包 (v 3.5.1404) 并低于软件包
附带的激活码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 运行时错误。
任何人都可以 suggestion/example 在 WebApi 中使用 Unity 解析每个请求的 dbcontext,最好没有任何 mvc 依赖?
我注入数据库上下文的方式就是问题所在。 Unity 会记住创建的实例并为创建的所有新 AuditService 实例注入相同的实例。我只需要如下解析数据库上下文。
container.RegisterType<DbContext, SecurityDbContext>(new PerThreadLifetimeManager());
PerThreadLifetimeManager 完成了这项工作,考虑到每个 Web 请求都将由不同的线程处理,应该没问题。
我通过在 WebApiConfig class 中声明我的自定义 UnityResolver class 来设法解决每个请求。假设您使用的是 OWIN 上下文,UnityResolver class 使用 HttpConfiguration class。
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var _container = new UnityContainer();
DependencyConfiguration.ConfigureContainer(_container);
config.DependencyResolver = new UnityResolver(_container);
}
ConfigureContainer class 只是一个 class,我在其中声明我的 IOC 依赖项,如下所示:
private static void RegisterReleaseEnv(IUnityContainer container)
{
//Repository Registration
container
.RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager());
}
使用 HierarchicalLifetimeManager 生命周期管理器非常重要,这样每个请求都会获得一个新实例。
UnityResolver class 看起来像这样:
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();
}
}
然后我使用 Generic 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();
}
}
由于 Unity 解析器,通用存储库根据请求实例化,DbContext (BackendContainer) 也是如此。
希望对您有所帮助。
更多信息:http://www.asp.net/web-api/overview/advanced/dependency-injection