WebApi Unity PerRequestLifetimeManagert.md
在WebApi 中自定义 Unity PerRequestLifetimeManagert
实现思路
- 使用HttpContext的Items 属性作为实例对象容器
- 自定义
UnityPerRequestHttpModule
继承IHttpModule管理实例对象容器,在HttpApplication的EndRequest
事件触发时,销毁容器中该请求的实例对象。 - 自定义
PerRequestLifetimeManager
继承LifetimeManager,调用UnityPerRequestHttpModule
获取或设置实例对象。
自定义UnityPerRequestHttpModule
/// <summary>
/// Unity PerRequest 生命周期HttpModule
/// Unity 产生的对象在 HttpModule 生命周期中有效
/// 在HttpModule生命周期中每个对象只产生一次
/// </summary>
public class UnityPerRequestHttpModule : IHttpModule
{
internal static readonly object ModuleKey = new object();
HttpApplication Context;
/// <summary>
/// 释放
/// </summary>
public void Dispose()
{
LoggerService.LoggerService.ApplicationLogger.Debug($"UnityPerRequestHttpModule【{Context.Request.Url}】销毁");
}
/// <summary>
/// 初始化
/// </summary>
/// <param name="context">HTTPApplication上下文</param>
public void Init(HttpApplication context)
{
Context = context;
context.EndRequest += Context_EndRequest;
}
/// <summary>
/// 释放 System.Web.IHttpModule 接口和 System.Web.IHttpHandler 接口之间组织和共享的该HttpModel数据
/// </summary>
/// <param name="sender">HttpApplication</param>
/// <param name="e"></param>
private void Context_EndRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
var dict = GetDictionary(app.Context);
if (dict != null)
{
foreach (var disposable in dict.Values.OfType<IDisposable>())
{
disposable.Dispose();
}
}
}
/// <summary>
/// 在System.Web.IHttpModule 接口和 System.Web.IHttpHandler 接口之间组织和共享的数据中获取该HttpModel的数据
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private static Dictionary<object, object> GetDictionary(HttpContext context)
{
if (context == null)
throw new ArgumentNullException("context");
var dict = (Dictionary<object, object>)context.Items[ModuleKey];
if (dict == null)
{
dict = new Dictionary<object, object>();
HttpContext.Current.Items[ModuleKey] = dict;
}
return dict;
}
/// <summary>
/// 准备模块和注册器
/// </summary>
internal static void Register()
{
DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
/// <summary>
/// 从 HttpModel的数据中获取指定对象
/// </summary>
/// <param name="lifetimeManagerKey">指定对象的Key</param>
/// <returns></returns>
internal static object GetValue(object lifetimeManagerKey)
{
var dict = GetDictionary(HttpContext.Current);
object obj = null;
if (dict.TryGetValue(lifetimeManagerKey, out obj))
{
return obj;
}
return null;
}
/// <summary>
/// 将对象和对象对应的Key存入HttpModel的数据中
/// </summary>
/// <param name="lifetimeManagerKey">指定对象的Key</param>
/// <param name="value">指定对象</param>
internal static void SetValue(object lifetimeManagerKey, object value)
{
GetDictionary(HttpContext.Current)[lifetimeManagerKey] = value;
}
}
在WebCinfig中配置自定义的UnityPerRequestHttpModule
<system.web>
<httpModules>
<add name="UnityPerRequestHttpModule" type="UnityPerRequestHttpModule"/>
</httpModules>
</system.web>
<system.webServer>
<modules>
<remove name="UnityPerRequestHttpModule" />
<add name="UnityPerRequestHttpModule" type="UnityPerRequestHttpModule" />
</modules>
</system.webServer>
自定义PerRequestLifetimeManager
/// <summary>
/// WebAPI 请求生命周期
/// 实际是HttpModule生命周期
/// 在HttpModule生命周期中每个对象只产生一次
/// </summary>
public class PerRequestLifetimeManager : LifetimeManager
{
private Type instanceType;
/// <summary>
/// 实例化WebAPI 请求生命周期
/// </summary>
public PerRequestLifetimeManager() { }
/// <summary>
/// 实例化WebAPI 请求生命周期
/// </summary>
/// <param name="instanceType">
/// 实例类型
/// 设置该参数后在一个HttpModel生命周期中对象不同接口解析到的是同一个实例
/// </param>
public PerRequestLifetimeManager(Type instanceType)
{
this.instanceType = instanceType;
}
private readonly object lifetimeKey = Guid.NewGuid();
/// <summary>
/// 生命周期Key
/// </summary>
public object LifetimeKey => instanceType == null ? lifetimeKey : instanceType.FullName;
/// <summary>
/// 获取对象
/// </summary>
/// <param name="container">生命周期容器</param>
/// <returns></returns>
public override object GetValue(ILifetimeContainer container = null)
{
LoggerService.LoggerService.ApplicationLogger.Debug($"从Request生命周期获取实例【{LifetimeKey}】");
return UnityPerRequestHttpModule.GetValue(LifetimeKey);
}
/// <summary>
/// 删除对象
/// </summary>
/// <param name="container">生命周期容器</param>
public override void RemoveValue(ILifetimeContainer container = null)
{
var disposable = this.GetValue() as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
LoggerService.LoggerService.ApplicationLogger.Debug($"从Request生命周期删除实例【{LifetimeKey}】");
UnityPerRequestHttpModule.SetValue(LifetimeKey, null);
}
/// <summary>
/// 设置对象
/// </summary>
/// <param name="newValue">实例化的对象</param>
/// <param name="container">生命周期容器</param>
public override void SetValue(object newValue, ILifetimeContainer container = null)
{
LoggerService.LoggerService.ApplicationLogger.Debug($"向Request生命周期添加实例【{LifetimeKey}】");
UnityPerRequestHttpModule.SetValue(LifetimeKey, newValue);
}
/// <summary>
/// 创建生命周期管理器时调用
/// </summary>
/// <returns></returns>
protected override LifetimeManager OnCreateLifetimeManager()
{
return this;
}
}
使用方法
var container = new UnityContainer();
//注册对象映射
container.RegisterType<ITestA, TestA>(new PerRequestLifetimeManager(typeof(TestA)));
container.RegisterType<ITestB, TestB>(new PerRequestLifetimeManager());
//解析对象
var testA = container.Resolve<ITestA>();
var testB = container.Resolve<ITestB>();