• 为Unity添加线程级别的生命周期管理


    事情是酱紫的

      在当前项目中,用到了微软的unity依赖注入工具,原先项目代码是跑在WEB上的,从Kigg复制过来的代码自带了PerRequest级别的对象生命周期管理,结合Entity Framework和UnitOfWork、Repository模式,用起来没什么问题。可是后来,加了一个C/S结构的服务程序,为了代码复用,我把用于WEB上的程序集加了进来。这样一来,原先的PerRequest级别的对象生命周期管理肯定是不能用了,怎么办呢?我草率的把ObjectContext对象的生命周期搞成了singleton,可是跑了一段时间我就发现问题:服务器的数据库写是在多线程方式下运行的,而ObjectContest不是线程安全的,这显然不行。于是我想到,自己定义一个类似于PerRequest级别的生命周期管理--PerThread。


    PerThread对象生命周期管理

      听名字就知道,这个对象生命周期管理是为同一个线程里的类型注入同一个对象实例的管理方式。因为手头有PerRequest的代码,所以模仿着写一个还是很容易的。我直接上代码。要是代码或想法有问题还请提出,平时写BS为主,对线程不熟。

      1   /// <summary>
      2     /// 线程级别生命周期
      3     /// </summary>
      4     public class UnityPerThreadLifetimeManager : LifetimeManager
      5     {
      6         private Thread _thread;
      7         public UnityPerThreadLifetimeManager(Thread thread)
      8         {
      9             _thread = thread;
     10         }
     11         public UnityPerThreadLifetimeManager()
     12             : this(Thread.CurrentThread)
     13         {
     14   
     15         }
     16         public override object GetValue()
     17         {
     18             IDictionary<UnityPerThreadLifetimeManager, object> backingStore = BackingStore;
     19             return backingStore.ContainsKey(this) ? backingStore[this] : null;
     20         }
     21 
     22         public override void RemoveValue()
     23         {
     24             throw new NotImplementedException();
     25         }
     26 
     27         public override void SetValue(object newValue)
     28         {
     29             IDictionary<UnityPerThreadLifetimeManager, object> backingStore = BackingStore;
     30 
     31             if (backingStore.ContainsKey(this))
     32             {
     33                 object oldValue = backingStore[this];
     34 
     35                 if (!ReferenceEquals(newValue, oldValue))
     36                 {
     37                     IDisposable disposable = oldValue as IDisposable;
     38 
     39                     if (disposable != null)
     40                     {
     41                         disposable.Dispose();
     42                     }
     43 
     44                     if (newValue == null)
     45                     {
     46                         backingStore.Remove(this);
     47                     }
     48                     else
     49                     {
     50                         backingStore[this] = newValue;
     51                     }
     52                 }
     53             }
     54             else
     55             {
     56                 if (newValue != null)
     57                 {
     58                     backingStore.Add(this, newValue);
     59                 }
     60             }
     61         }
     62 
     63         private IDictionary<UnityPerThreadLifetimeManager, object> BackingStore
     64         {
     65             get
     66             {
     67                 _thread = (Thread.CurrentThread != null) ? Thread.CurrentThread : _thread;
     68 
     69                 return UnityPerThreadLifetimeManager.GetInstances(_thread);
     70             }
     71         }
     72 
     73         private static IDictionary<Thread, IDictionary<UnityPerThreadLifetimeManager, object>> totalStore = new Dictionary<Thread, IDictionary<UnityPerThreadLifetimeManager, object>>();
     74 
     75         internal static IDictionary<UnityPerThreadLifetimeManager, object> GetInstances(Thread thread)
     76         {
     77             IDictionary<UnityPerThreadLifetimeManager, object> instances;
     78 
     79             if (totalStore.ContainsKey (thread ))
     80             {
     81                 instances = (IDictionary<UnityPerThreadLifetimeManager, object>)totalStore[thread ];
     82             }
     83             else
     84             {
     85                 lock (totalStore)
     86                 {
     87                     //删除已经结束的线程
     88                     IList<Thread> threads = totalStore.Keys.ToList();
     89                     for (int i = totalStore.Count - 1; i >= 0; i--)
     90                     {
     91                         Thread item = threads[i];
     92                         if (item.IsAlive == false)
     93                         {
     94                             IDictionary<UnityPerThreadLifetimeManager, object> removeInstances = (IDictionary<UnityPerThreadLifetimeManager, object>)totalStore[item];
     95                             foreach (var ins in removeInstances )
     96                             {
     97                                 IDisposable dispose = ins.Value as IDisposable;
     98                                 if (dispose != null)
     99                                     dispose.Dispose();
    100                             }
    101                             totalStore.Remove(item);
    102                         }
    103                     }
    104 
    105                     if (totalStore.ContainsKey(thread))
    106                     {
    107                         instances = (IDictionary<UnityPerThreadLifetimeManager, object>)totalStore[thread ];
    108                     }
    109                     else
    110                     {
    111                         instances = new Dictionary<UnityPerThreadLifetimeManager, object>();
    112                         totalStore.Add(thread, instances);
    113                     }
    114                 }
    115             }
    116 
    117             return instances;
    118         }
    119     }
  • 相关阅读:
    关于Markdown
    20. 有效的括号(栈)
    数组队列
    MySql编码、卸载、启动问题
    循环队列
    链表实现与时间复杂度分析
    栈的应用和基本实现
    使用链表实现栈
    封装动态数组类Array
    Android平台的开发环境的发展演变
  • 原文地址:https://www.cnblogs.com/xxfss2/p/2852514.html
Copyright © 2020-2023  润新知