Unity DI 配置默认生命周期管理器(Unity DI set default lifetimemanager)

本文介绍了一个自定义的PreHttpRequestLifetimeManager类,用于在一个HTTP请求的生命周期内管理同一个实例的注入。通过创建自定义的HttpModule和容器扩展,实现了对特定类型的实例在请求周期内的统一管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

蛋疼的问题困扰我几天,于是下载了源码来看,终于成功,

以下示例以自己写的PreHttpRequestLifetimeManager,可能大部分人都用得到这个生命周期管理,

少费话,贴代码:

1、PreHttpRequestLifetimeManager

/// <summary>
    ///  在HTTP请求生命周期内注入同一个实例
    /// </summary>
    public class PreHttpRequestLifetimeManager : LifetimeManager,IDisposable
    {
        /// <summary>
        /// 键
        /// </summary>
        Guid _key;
        /// <summary>
        /// 值
        /// </summary>
        object _value;

        /// <summary>  
        ///   在HTTP请求生命周期内注入同一个实例
        /// </summary>
        public PreHttpRequestLifetimeManager()
        {
            this._key = Guid.NewGuid();
        }
        /// <summary>
        /// 缓存的注入实体
        /// </summary>
        IDictionary<Guid, object> ObjectDictionary
        {
            get
            {
                var objects = HttpContext.Current.Items[HttpModuleService.UnityObjects] as IDictionary<Guid, object>;
                if (objects == null)
                {
                    lock (this)
                    {
                        if (HttpContext.Current.Items[HttpModuleService.UnityObjects] == null)
                        {
                            objects = new Dictionary<Guid, object>();
                            HttpContext.Current.Items[HttpModuleService.UnityObjects] = objects;
                        }
                        else
                        {
                            return HttpContext.Current.Items[HttpModuleService.UnityObjects] as IDictionary<Guid, object>;
                        }
                    }
                }
                return objects;
            }
        }

        public override object GetValue()
        {
            return this.ObjectDictionary.TryGetValue(this._key, out this._value) ? this._value : null;
        }
        public override void SetValue(object newValue)
        {
            if (this.ObjectDictionary.TryGetValue(this._key, out this._value)) return;
            this._value = newValue;
            this.ObjectDictionary.Add(this._key, this._value);
        }
        public override void RemoveValue()
        {
            if (this._value != null)
            {
                Dispose();
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        private void Dispose(bool disposing)
        {
            if (!disposing) return;
            var objects = this.ObjectDictionary;
            if (!objects.TryGetValue(this._key, out this._value)) return;
            var disposable = this._value as IDisposable;
            if (disposable != null)
            {
                objects.Remove(this._key);
            }
            _value = null;
        }
    }


2、写一个HttpModule

/// <summary>
    /// 自定义模块初始化
    /// </summary>
    public class HttpModuleService : IHttpModule
    {
        /// <summary>
        /// DI生命周期对象标识
        /// </summary>
        internal const string UnityObjects = "UNITYOBJECTS";
        public void Dispose()
        {
        }
        public void Init(HttpApplication context)
        {
            context.EndRequest += this.OnUnityEndRequest;
        }
        /// <summary>
        /// http请求结束时回收unity对象
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnUnityEndRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Items.Remove(UnityObjects);
        }
    }

至于httpmodule怎么使用,网上找。

3、写个自定义容器

    /// <summary>
    /// 自定义容器
    /// </summary>
    public class DefaultLifetimeManagerExtension<TLifetimeManager> : UnityContainerExtension where TLifetimeManager : LifetimeManager, new()
    {
         /// <summary>
        /// Install the default container behavior into the container.
        /// </summary>
        protected override void Initialize()
        {
            Context.Registering += OnRegister;
            Context.RegisteringInstance += OnRegisterInstance;

            Container.RegisterInstance(Container, new TLifetimeManager());
        }

        /// <summary>
        /// Remove the default behavior from the container.
        /// </summary>
        public override void Remove()
        {
            Context.Registering -= OnRegister;
            Context.RegisteringInstance -= OnRegisterInstance;
        }

        private void OnRegister(object sender, RegisterEventArgs e)
        {
            Context.RegisterNamedType(e.TypeFrom ?? e.TypeTo, e.Name);
            if (e.TypeFrom != null)
            {
                if (e.TypeFrom.IsGenericTypeDefinition && e.TypeTo.IsGenericTypeDefinition)
                {
                    Context.Policies.Set<IBuildKeyMappingPolicy>(
                        new GenericTypeBuildKeyMappingPolicy(new NamedTypeBuildKey(e.TypeTo, e.Name)),
                        new NamedTypeBuildKey(e.TypeFrom, e.Name));
                }
                else
                {
                    Context.Policies.Set<IBuildKeyMappingPolicy>(
                        new BuildKeyMappingPolicy(new NamedTypeBuildKey(e.TypeTo, e.Name)),
                        new NamedTypeBuildKey(e.TypeFrom, e.Name));
                }
            }
            if (e.LifetimeManager != null)
            {
                SetLifetimeManager(e.TypeTo, e.Name, e.LifetimeManager);
            }
        }

        private void OnRegisterInstance(object sender, RegisterInstanceEventArgs e)
        {
            Context.RegisterNamedType(e.RegisteredType, e.Name);
            SetLifetimeManager(e.RegisteredType, e.Name, e.LifetimeManager);
            var identityKey = new NamedTypeBuildKey(e.RegisteredType, e.Name);
            Context.Policies.Set<IBuildKeyMappingPolicy>(new BuildKeyMappingPolicy(identityKey), identityKey);
            e.LifetimeManager.SetValue(e.Instance);
        }

        private void SetLifetimeManager(Type lifetimeType, string name, ILifetimePolicy lifetimeManager)
        {
            if ((lifetimeManager as TransientLifetimeManager) != null)
            {
                lifetimeManager = new TLifetimeManager();
            }
            if (lifetimeType.IsGenericTypeDefinition)
            {
                var factory =
                    new LifetimeManagerFactory(Context, lifetimeManager.GetType());
                Context.Policies.Set<ILifetimeFactoryPolicy>(factory,
                    new NamedTypeBuildKey(lifetimeType, name));
            }
            else
            {
                Context.Policies.Set(lifetimeManager,
                    new NamedTypeBuildKey(lifetimeType, name));
                if (lifetimeManager is IDisposable)
                {
                    Context.Lifetime.Add(lifetimeManager);
                }
            }
        }
    }



最后一步,配置Global.asax实现注入:


private static UnityContainer container = new UnityContainer();
        protected void Application_Start()
        {
            container.AddExtension(new DefaultLifetimeManagerExtension<PreHttpRequestLifetimeManager>());
         }



注入这一步使用unity的应该都懂,我只贴了关键代码AddExtension,

我是用的mvc,经测试,在一个页面中调用不同控制器的 action,每个action都调用同一个接口注入过后获取的hashcode一致


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值