博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义Unity对象生命周期管理集成ADO.NET Entity Framework
阅读量:5983 次
发布时间:2019-06-20

本文共 5685 字,大约阅读时间需要 18 分钟。

在Unity中,从Unity 取得的实例为 Transient。如果你希望使用多线程方式,就需要在组成时使用lifecycle参数,这时候取出的组件就不再是同一个了。在Unity IOC中,它支持我们对于组件的实例进行控制,也就是说我们可以透明的管理一个组件拥有多少个实例。Unity IOC容器提供了如下几种生命处理方式:

  • Singleton:一个组件只有一个实例被创建,所有请求的客户使用程序得到的都是同一个实例。
  • Transient:这种处理方式与我们平时使用new的效果是一样的,对于每次的请求得到的都是一个新的实例。
  • Custom:自定义的生命处理方式。

我要增加一个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 IDictionary
GetObjectTable() { 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/

你可能感兴趣的文章
三年前端,面试思考(头条蚂蚁美团offer)
查看>>
巧用 TypeScript(二)
查看>>
python---网络基础(socket)
查看>>
小程序构建骨架屏的探索
查看>>
深度学习精要之CapsuleNets理论与实践(附Python代码)
查看>>
rabbitmq中文教程python版 - 工作队列
查看>>
SpringBoot 1024行代码 - Eureka Server
查看>>
Docker和rkt快别争了,k8s才是容器生态的中心
查看>>
服务器时区问题
查看>>
JAVA反射技术应用-ReflectUtil
查看>>
removeGeneratedClassFiles Failed
查看>>
nagios安装全攻略
查看>>
Perl进阶知识点(2)
查看>>
Android adb.exe 启动失败
查看>>
我的友情链接
查看>>
使用JavaMail完成邮件的编写
查看>>
Xcode8修改或者新建的XIB文件 xcode7上报错问题
查看>>
MSSQL获取昨天,本周,本月。。。
查看>>
记录:我的大学的最后时光(大三下学期 _11
查看>>
标签使用 struts2
查看>>