本文共 5685 字,大约阅读时间需要 18 分钟。
在Unity中,从Unity 取得的实例为 Transient。如果你希望使用多线程方式,就需要在组成时使用lifecycle参数,这时候取出的组件就不再是同一个了。在Unity IOC中,它支持我们对于组件的实例进行控制,也就是说我们可以透明的管理一个组件拥有多少个实例。Unity IOC容器提供了如下几种生命处理方式:
我要增加一个Request的,一个Request请求一个实例,然后在Request结束的时候,回收资源。 增加一个Resquest级别的LifetimeManager,HttpContext.Items中数据是Request期间共享数据用的,所以HttpContext.Items中放一个字典,用类型为key,类型的实例为value。如果当前Context.Items中有类型的实例,就直接返回实例。 ObjectContext本身是有缓存的,整个Request内都是一个ObjectContext,ObjectContext一级缓存能力进一步利用。
用在Unity中,如何获取对象的实例及如何销毁对象都是由LifetimeManager完成的,其定义如下
public abstract class LifetimeManager : ILifetimePolicy, IBuilderPolicy{ protected LifetimeManager(); public abstract object GetValue(); public abstract void RemoveValue(); public abstract void SetValue(object newValue);}
其中GetValue方法获取对象实例,RemoveValue方法销毁对象,SetValue方法为对外引用的保存提供新的实例
有了这3个方法,就可以通过自定义LifetimeManager来实现从HttpContext中取值。
下面我们来实现Unity集成ADO.NET Entity Framework的工作:
1、利用Unity的依赖注入,ObjectContext会给我们生成3个构造函数,类似于下面的代码:
// Original file name:// Generation date: 2008/8/24 10:05:33namespace RequestLifeTimeManagerTest{ using Microsoft.Practices.Unity; ////// There are no comments for AdventureWorksLTEntities in the schema. /// public partial class AdventureWorksLTEntities : global::System.Data.Objects.ObjectContext { ////// Initializes a new AdventureWorksLTEntities object using the connection string found in the 'AdventureWorksLTEntities' section of the application configuration file. /// public AdventureWorksLTEntities() : base("name=AdventureWorksLTEntities", "AdventureWorksLTEntities") { this.OnContextCreated(); } ////// Initialize a new AdventureWorksLTEntities object. /// public AdventureWorksLTEntities(string connectionString) : base(connectionString, "AdventureWorksLTEntities") { this.OnContextCreated(); } ////// Initialize a new AdventureWorksLTEntities object. /// public AdventureWorksLTEntities(global::System.Data.EntityClient.EntityConnection connection) : base(connection, "AdventureWorksLTEntities") { this.OnContextCreated(); } partial void OnContextCreated();……}构造函数注入包含了二种情况,一种是类仅有一个构造函数时,Unity 可以进行自动注入;另一种情况是,类包含多个构造函数时,必须使用 Attribute 或者配置文件指定注入时使用的构造函数。ObjectContext有多个构造函数,而且ObjectContext的构造函数代码是Visual Studio 代码生成的,最好的选择是使用配置文件或者使用配置API指定注入时使用的构造函数。下面是使用配置API:namespace RequestLifeTimeManagerTest{ public class EFContainerExtension : UnityContainerExtension { protected override void Initialize() { this.Container.RegisterType(new RequestControlledLifetimeManager(typeof(AdventureWorksLTEntities))) .Configure () .ConfigureInjectionFor (new InjectionConstructor()); } }}我们定义了一个Unity扩展,在扩展类EFContainerExtension 我们选择了第一个构造函数以及ObjectContext使用RequestControlledLifetimeManager实现ObjectContext的生命周期管理。2、实现RequestControlledLifetimeManager,完成对整个Request内都是一个ObjectContext的对象的生命周期管理:using System;using System.Collections.Generic;using System.Linq;using System.Web;using Microsoft.Practices.Unity;namespace RequestLifeTimeManagerTest{ public class RequestControlledLifetimeManager : LifetimeManager { private Type objectType; /// /// /// /// public RequestControlledLifetimeManager(Type t) { this.objectType = t; } private IDictionaryGetObjectTable() { IDictionary objects = HttpContext.Current.Items[RequestLifeTimeManagerTest.UnityHttpModule.UNITYOBJECTS] as IDictionary ; if (objects == null) { lock (this) { if (HttpContext.Current.Items[RequestLifeTimeManagerTest.UnityHttpModule.UNITYOBJECTS] == null) { objects = new Dictionary (); HttpContext.Current.Items[RequestLifeTimeManagerTest.UnityHttpModule.UNITYOBJECTS] = objects; } else { return HttpContext.Current.Items[RequestLifeTimeManagerTest.UnityHttpModule.UNITYOBJECTS] as IDictionary ; } } } return objects; } public override object GetValue() { IDictionary objects = this.GetObjectTable(); object obj = null; if (objects.TryGetValue(this.objectType, out obj)) { return obj; } return null; } public override void RemoveValue() { IDictionary objects = this.GetObjectTable(); object obj = null; if (objects.TryGetValue(this.objectType, out obj)) { ((IDisposable)obj).Dispose(); objects.Remove(this.objectType); } } public override void SetValue(object newValue) { IDictionary objects = this.GetObjectTable(); objects.Add(this.objectType, newValue); } }}写一个HttpMoudle,在Request结束的时候回收资源。 using System;using System.Web;using System.Collections.Generic; namespace RequestLifeTimeManagerTest{ public class UnityHttpModule : IHttpModule { internal const string UNITYOBJECTS = "UNITYOBJECTS"; #region IHttpModule Members public void Dispose() { //clean-up code here. } public void Init(HttpApplication context) { context.EndRequest += new EventHandler(context_EndRequest); } #endregion private void context_EndRequest(object sender, EventArgs e) { IDictionary objects = HttpContext.Current.Items[UNITYOBJECTS] as IDictionary ; if (objects != null) { foreach (Type key in objects.Keys) { if (objects[key] is IDisposable) { ((IDisposable)objects[key]).Dispose(); } } HttpContext.Current.Items.Remove(UNITYOBJECTS); } } }}3、web.config中的配置文件内容如下,注意看红色部分:
本文来自云栖社区合作伙伴“doNET跨平台”,了解相关信息可以关注“opendotnet”微信公众号
转载地址:http://avgox.baihongyu.com/