马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

IOC控制反转、Unity简介

[复制链接]
查看2454 | 回复1 | 2019-10-12 10:22:07 | 显示全部楼层 |阅读模式

参考博客地点:

Unity系列文章,推荐:http://www.cnblogs.com/qqlin/archive/2012/10/16/2717964.html

https://www.cnblogs.com/lyps/p/10560256.html

这篇文章紧张先容.NET Framework下面的IOC以及Unity的使用,下一篇文章先容.NET Core下面自带的容器IServiceCollection以及Autofac的使用https://www.cnblogs.com/taotaozhuanyong/p/11562184.html

IOC(Inverse of Control),控制反转。

说到IOC,就不得不提DI(Dependency Injection),依赖注入

IOC是目的结果,需要DI依赖注入的手段。

分层架构时这些是必须的,可以分别边界独立演化,也方便分工,促进代码复用。。

依赖倒置原则DIP:

  体系架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖。依赖抽象而不是依赖细节。在A勒种调用了B类,A类就是高层,B类就是低层。

面向抽象:

  1、一个方法满意多种范例

  2、支持下层的扩展。

下面有三种创建一个对象的方式:

  1. AndroidPhone phone = new AndroidPhone();//1 满是细节
  2. IPhone phone = new AndroidPhone();//2 左边抽象右边细节
  3. IPhone phone = ObjectFactory.CreatePhone();//3 封装转移
复制代码
  1. /// <summary>
  2. /// 简朴工厂+设置文件+反射
  3. /// </summary>
  4. public class ObjectFactory
  5. {
  6. public static IPhone CreatePhone()
  7. {
  8. string classModule = ConfigurationManager.AppSettings["iPhoneType"];
  9. Assembly assemly = Assembly.Load(classModule.Split(',')[1]);
  10. Type type = assemly.GetType(classModule.Split(',')[0]);
  11. return (IPhone)Activator.CreateInstance(type);//无参数构造函数
  12. }
  13. public static IPhone CreatePhone(IBaseBll iBLL)
  14. {
  15. string classModule = ConfigurationManager.AppSettings["iPhoneType"];
  16. Assembly assemly = Assembly.Load(classModule.Split(',')[1]);
  17. Type type = assemly.GetType(classModule.Split(',')[0]);
  18. return (IPhone)Activator.CreateInstance(type, new object[] { iBLL });
  19. }
  20. }
复制代码

在App.config下面设置节点:

  1. <appSettings>
  2. <add key="iPhoneType" value="Bingle.Service.AndroidPhone,Bingle.Service" />
  3. </appSettings>
复制代码

只有抽象,没有细节,好处是可扩展。

IOC控制反转:

  传统开辟,上端依赖(调用/指定)下端对象,这个样子会有依赖。控制反转就是把对下端对象的依赖转移到第三方容器(工厂+设置文件+反射),能够让程序拥有更好的扩展性。

下面出现一个题目:

  构造A对象,但是A依赖于B对象,那就先构造B,如果B又依赖C,再构造C。。。。。。

  1. IDAL.IBaseDAL baseDAL = new Ruamou.DAL.BaseDAL();
  2. IBLL.IBaseBll baseBll = new Ruanmou.BLL.BaseBll(baseDAL);
  3. IPhone phone = ObjectFactory.CreatePhone(baseBll);
复制代码

如今这个题目已经袒露了,下面开始了DI,依赖注入,就能做到构造某个对象时,将依赖的对象自动初始化并注入。

IOC是目的结果,需要DI依赖注入的手段。

DI依赖注入:

  三种方式注入:构造函数注入、属性注入、方法注入(按照时间顺序)

  [Dependency]//属性注入

  1. [Dependency]//属性注入
  2. public IMicrophone iMicrophone { get; set; }
复制代码

  [InjectionConstructor]//构造函数注入,默认找参数最多的构造函数,方法注入不加这个特性也是可以的,可以不消特性,可以去掉对容器的依赖

  1. [InjectionConstructor]//构造函数注入:默认找参数最多的构造函数
  2. public ApplePhoneUpdate(IHeadphone headphone)
  3. {
  4. this.iHeadphone = headphone;
  5. Console.WriteLine("{0} 带参数构造函数", this.GetType().Name);
  6. }
复制代码

  [InjectionMethod]//方法注入

  1. [InjectionMethod]//方法注入
  2. public void Init(IPower power)
  3. {
  4. this.iPower = power;
  5. }
复制代码

如何使用Unity容器?

  1、安装Unity

  

102207ntfpzo276uop2c3t.png

  2、容器三部曲:

    实例化容器、注册范例、获取实例

  3、项目版本和服务处的版本要不绝。

下面是Iphone与AndroidPhone的界说:

102208nmnv5v88cmohkhez.gif
102208sxvxvp5vb35xrp6f.gif
  1. public interface IPhone
  2. {
  3. void Call();
  4. IMicrophone iMicrophone { get; set; }
  5. IHeadphone iHeadphone { get; set; }
  6. IPower iPower { get; set; }
  7. }
  8. public class AndroidPhone : IPhone
  9. {
  10. public IMicrophone iMicrophone { get; set; }
  11. public IHeadphone iHeadphone { get; set; }
  12. public IPower iPower { get; set; }
  13. //public AndroidPhone()
  14. //{
  15. // Console.WriteLine("{0}构造函数", this.GetType().Name);
  16. //}
  17. public AndroidPhone(AbstractPad pad, IHeadphone headphone)
  18. {
  19. Console.WriteLine("{0}构造函数", this.GetType().Name);
  20. }
  21. //[ElevenInjectionConstructor]
  22. public AndroidPhone(AbstractPad pad)
  23. {
  24. Console.WriteLine("{0}构造函数", this.GetType().Name);
  25. }
  26. public AndroidPhone(IBaseBll baseBll)
  27. {
  28. Console.WriteLine("{0}构造函数", this.GetType().Name);
  29. }
  30. public void Call()
  31. {
  32. Console.WriteLine("{0}打电话", this.GetType().Name); ;
  33. }
  34. }
复制代码
View Code
  1. IUnityContainer container = new UnityContainer();//1 实例化容器
  2. container.RegisterType<IPhone, AndroidPhone>();//2 注册范例
  3. IPhone iphone = container.Resolve<IPhone>();//3 获取实例
复制代码

我们来看一下Unity下面RegisterType方法内里的泛型束缚:

102208a7771ddtzifb3wxz.png

另有一个方法:

102209rm9cm44mbmehhy2p.png

  1. IUnityContainer container = new UnityContainer();//1 实例化容器
  2. container.RegisterInstance<AbstractPad>(new ApplePadChild());
  3. AbstractPad abstractPad = container.Resolve<AbstractPad>();
复制代码

后遭的时间,有依赖:

102209awyog5kabk4x10h5.png

下面来解决这个题目:但是要保持Unity版本同等

下面是一些注册时要依赖的范例

102210nkq71zxnfkpwnv8x.gif
102210lb2zp62g2kg82h84.gif
  1. public interface IHeadphone
  2. {
  3. }
  4. public class Headphone : IHeadphone
  5. {
  6. public Headphone(IMicrophone microphone)
  7. {
  8. Console.WriteLine("Headphone 被构造");
  9. }
  10. }
  11. public interface IMicrophone
  12. {
  13. }
  14. public class Microphone : IMicrophone
  15. {
  16. public Microphone(IPower power)
  17. {
  18. Console.WriteLine("Microphone 被构造");
  19. }
  20. }
  21. public interface IPower
  22. {
  23. }
  24. public class Power : IPower
  25. {
  26. public Power(IBLL.IBaseBll baseBll)
  27. {
  28. Console.WriteLine("Power 被构造");
  29. }
  30. }
  31. public interface IBaseBll
  32. {
  33. void DoSomething();
  34. }
  35. public class BaseBll : IBaseBll
  36. {
  37. private IBaseDAL _baseDAL = null;
  38. public BaseBll(IBaseDAL baseDAL, int id)
  39. {
  40. Console.WriteLine($"{nameof(BaseBll)}被构造。。。{id}。");
  41. this._baseDAL = baseDAL;
  42. }
  43. public void DoSomething()
  44. {
  45. this._baseDAL.Add();
  46. this._baseDAL.Update();
  47. this._baseDAL.Find();
  48. this._baseDAL.Delete();
  49. }
  50. }
  51. public interface IBaseDAL
  52. {
  53. void Add();
  54. void Delete();
  55. void Update();
  56. void Find();
  57. }
  58. public class BaseDAL : IBaseDAL
  59. {
  60. public BaseDAL()
  61. {
  62. Console.WriteLine($"{nameof(BaseDAL)}被构造。。。。");
  63. }
  64. public void Add()
  65. {
  66. Console.WriteLine($"{nameof(Add)}");
  67. }
  68. public void Delete()
  69. {
  70. Console.WriteLine($"{nameof(Delete)}");
  71. }
  72. public void Find()
  73. {
  74. Console.WriteLine($"{nameof(Find)}");
  75. }
  76. public void Update()
  77. {
  78. Console.WriteLine($"{nameof(Update)}");
  79. }
  80. }
复制代码
View Code

  1. IUnityContainer container = new UnityContainer();
  2. container.RegisterType<IPhone, ApplePhone>();
  3. container.RegisterType<IHeadphone, Headphone>();
  4. container.RegisterType<IMicrophone, Microphone>();
  5. container.RegisterType<IPower, Power>();
  6. container.RegisterType<IBLL.IBaseBll, BLL.BaseBll>();
  7. container.RegisterType<IDAL.IBaseDAL, Ruamou.DAL.BaseDAL>();
  8. IPhone iphone = container.Resolve<IPhone>();
复制代码

但凡是用到了需要的范例,都要给注入进去,否则容器怎么知道范例啊

Unity内里到底是怎么实现的?下面,自己来写一个IOC

1、最最根本大略的版本:

  1. public interface ILTContainer
  2. {
  3. void RegisterType<TFrom, TTo>();
  4. T Resolve<T>();
  5. }
  6. /// <summary>
  7. /// 容器--工厂
  8. /// </summary>
  9. public class LTContainer : ILTContainer
  10. {
  11. private Dictionary<string, Type> LTDic = new Dictionary<string, Type>();
  12. public void RegisterType<TFrom, TTo>()
  13. {
  14. LTDic.Add(typeof(TFrom).FullName, typeof(TTo));
  15. }
  16. public T Resolve<T>()
  17. {
  18. Type type = LTDic[typeof(T).FullName];
  19. return (T)Activator.CreateInstance(type);
  20. }
  21. }
  22. }
复制代码

调用一下:

  1. ILTContainer container = new LTContainer();
  2. container.RegisterType<IPerson, Student>();
  3. var person = container.Resolve<IPerson>();
复制代码

2、升级一点点

102210aslbz9li49sfzf27.png

  1. public interface IPerson
  2. {
  3. }
  4. public class Student : IPerson
  5. {
  6. [LTInjectionConstructor]
  7. public Student(Animal animal)
  8. {
  9. Console.WriteLine("Student被构造了...");
  10. }
  11. }
  12. public abstract class Animal
  13. {
  14. }
  15. public class Cat : Animal
  16. {
  17. public Cat()
  18. {
  19. Console.WriteLine("Animal被构造了....");
  20. }
  21. }
  22. }
复制代码
  1. public interface ILTContainer
  2. {
  3. void RegisterType<TFrom, TTo>();
  4. T Resolve<T>();
  5. }
  6. /// <summary>
  7. /// 容器--工厂
  8. /// </summary>
  9. public class LTContainer : ILTContainer
  10. {
  11. private Dictionary<string, Type> LTDic = new Dictionary<string, Type>();
  12. public void RegisterType<TFrom, TTo>()
  13. {
  14. LTDic.Add(typeof(TFrom).FullName, typeof(TTo));
  15. }
  16. public T Resolve<T>()
  17. {
  18. Type type = LTDic[typeof(T).FullName];
  19. var ctorArray = type.GetConstructors();
  20. ConstructorInfo ctor = null;
  21. if (ctorArray.Count(c => c.IsDefined(typeof(LTInjectionConstructorAttribute), true)) > 0)
  22. {
  23. ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(LTInjectionConstructorAttribute), true));
  24. }
  25. else
  26. {
  27. ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
  28. }
  29. List<object> paraList = new List<object>();
  30. foreach (var item in ctor.GetParameters())
  31. {
  32. Type paraType = item.ParameterType;
  33. Type targetType = this.LTDic[paraType.FullName];
  34. paraList.Add(Activator.CreateInstance(targetType));
  35. }
  36. return (T)Activator.CreateInstance(type, paraList.ToArray());
  37. //return (T)this.CreateObject(type);
  38. }
  39. private object CreateObject(Type type)
  40. {
  41. ConstructorInfo[] ctorArray = type.GetConstructors();
  42. ConstructorInfo ctor = null;
  43. if (ctorArray.Count(c => c.IsDefined(typeof(LTInjectionConstructorAttribute), true)) > 0)
  44. {
  45. ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(LTInjectionConstructorAttribute), true));
  46. }
  47. else
  48. {
  49. ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
  50. }
  51. List<object> paraList = new List<object>();
  52. foreach (var parameter in ctor.GetParameters())
  53. {
  54. Type paraType = parameter.ParameterType;
  55. Type targetType = this.LTDic[paraType.FullName];
  56. object para = this.CreateObject(targetType);
  57. //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
  58. paraList.Add(para);
  59. }
  60. return Activator.CreateInstance(type, paraList.ToArray());
  61. }
  62. //属性注入+方法注入?
  63. }
复制代码

调用一下:

  1. ILTContainer container = new LTContainer();
  2. ILTContainer container = new LTContainer();
  3. container.RegisterType<IPerson, Student>();
  4. container.RegisterType<Animal, Cat>();
  5. var person = container.Resolve<IPerson>();
复制代码

3、再升级一点点:

  继承找出targetType的构造,找出一个符合的构造函数,分别构造其参数,继承...递归

102210w2l6n28c09xt0cb9.png

  1. public interface ILTContainer
  2. {
  3. void RegisterType<TFrom, TTo>();
  4. T Resolve<T>();
  5. }
  6. /// <summary>
  7. /// 容器--工厂
  8. /// </summary>
  9. public class LTContainer : ILTContainer
  10. {
  11. private Dictionary<string, Type> LTDic = new Dictionary<string, Type>();
  12. public void RegisterType<TFrom, TTo>()
  13. {
  14. LTDic.Add(typeof(TFrom).FullName, typeof(TTo));
  15. }
  16. public T Resolve<T>()
  17. {
  18. Type type = LTDic[typeof(T).FullName];
  19. //继承找出targetType的构造函数,找出一个符合的构造函数,分别构造其参数
  20. //继承......递归
  21. return (T)this.CreateObject(type);
  22. }
  23. public object CreateObject(Type type)
  24. {
  25. ConstructorInfo[] ctorArray = type.GetConstructors();
  26. ConstructorInfo ctor = null;
  27. if (ctorArray.Count(c => c.IsDefined(typeof(LTContainer), true)) > 0)
  28. {
  29. ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(LTContainer), true));
  30. }
  31. else
  32. {
  33. ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
  34. }
  35. List<object> paraList = new List<object>();
  36. foreach (var parameter in ctor.GetParameters())
  37. {
  38. Type paraType = parameter.ParameterType;
  39. Type targetType = this.LTDic[paraType.FullName];
  40. object para = this.CreateObject(targetType);
  41. //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
  42. paraList.Add(para);
  43. }
  44. return Activator.CreateInstance(type, paraList.ToArray());
  45. }
  46. //属性注入+方法注入?
  47. }
复制代码

生命管理周期:

  1. IUnityContainer container = new UnityContainer();
复制代码

默认瞬时生命周期:每次都是构造一个新的

  1. container.RegisterType<AbstractPad, ApplePad>();
  2. container.RegisterType<AbstractPad, ApplePad>(new TransientLifetimeManager());
复制代码

全局单例:全局就只有一个该范例实例

非欺压性,只有通过容器获取才是单例;项目中一般推荐容器单例而不是自己写单例

  1. container.RegisterType<AbstractPad, ApplePad>(new SingletonLifetimeManager());
  2. AbstractPad pad1 = container.Resolve<AbstractPad>();
  3. AbstractPad pad2 = container.Resolve<AbstractPad>();
  4. Console.WriteLine(object.ReferenceEquals(pad1, pad2));
复制代码

线程单例:同一个线程就只有一个实例,不同线程就是不同实例

  1. container.RegisterType<AbstractPad, ApplePad>(new PerThreadLifetimeManager());
  2. AbstractPad pad1 = null;
  3. AbstractPad pad2 = null;
  4. AbstractPad pad3 = null;
  5. Action act1 = new Action(() =>
  6. {
  7. pad1 = container.Resolve<AbstractPad>();
  8. Console.WriteLine($"pad1由线程id={Thread.CurrentThread.ManagedThreadId}");
  9. });
  10. var result1 = act1.BeginInvoke(null, null);
  11. Action act2 = new Action(() =>
  12. {
  13. pad2 = container.Resolve<AbstractPad>();
  14. Console.WriteLine($"pad2由线程id={Thread.CurrentThread.ManagedThreadId}");
  15. });
  16. var result2 = act2.BeginInvoke(t =>
  17. {
  18. pad3 = container.Resolve<AbstractPad>();
  19. Console.WriteLine($"pad3由线程id={Thread.CurrentThread.ManagedThreadId}");
  20. Console.WriteLine($"object.ReferenceEquals(pad2, pad3)={object.ReferenceEquals(pad2, pad3)}");
  21. }, null);
  22. act1.EndInvoke(result1);
  23. act2.EndInvoke(result2);
  24. Console.WriteLine($"object.ReferenceEquals(pad1, pad2)={object.ReferenceEquals(pad1, pad2)}");
复制代码

//ExternallyControlledLifetimeManager 外部可开释单例
//PerResolveLifetimeManager 循环引用

自己写的容器内里,加上生命周期:

  1. public interface IBingleContainer
  2. {
  3. void RegisterType<TFrom, TTo>(LifeTimeType lifeTimeType = LifeTimeType.Transient);
  4. T Resolve<T>();
  5. }
  6. /// <summary>
  7. /// 容器--工厂
  8. /// </summary>
  9. public class BingleContainer : IBingleContainer
  10. {
  11. private Dictionary<string, RegisterInfo> BingleContainerDictionary = new Dictionary<string, RegisterInfo>();
  12. /// <summary>
  13. /// 缓存起来,范例的对象实例
  14. /// </summary>
  15. private Dictionary<Type, object> TypeObjectDictionary = new Dictionary<Type, object>();
  16. /// <summary>
  17. ///
  18. /// </summary>
  19. /// <typeparam name="TFrom"></typeparam>
  20. /// <typeparam name="TTo"></typeparam>
  21. /// <param name="lifeTimeType">默认参数,不通报就是Transient</param>
  22. public void RegisterType<TFrom, TTo>(LifeTimeType lifeTimeType = LifeTimeType.Transient)
  23. {
  24. BingleContainerDictionary.Add(typeof(TFrom).FullName, new RegisterInfo()
  25. {
  26. TargetType = typeof(TTo),
  27. LifeTime = lifeTimeType
  28. });
  29. }
  30. public T Resolve<T>()
  31. {
  32. RegisterInfo info = BingleContainerDictionary[typeof(T).FullName];
  33. Type type = BingleContainerDictionary[typeof(T).FullName].TargetType;
  34. T result = default(T);
  35. switch (info.LifeTime)
  36. {
  37. case LifeTimeType.Transient:
  38. result = (T)this.CreateObject(type);
  39. break;
  40. case LifeTimeType.Singleton:
  41. if (this.TypeObjectDictionary.ContainsKey(type))
  42. {
  43. result = (T)this.TypeObjectDictionary[type];
  44. }
  45. else
  46. {
  47. result = (T)this.CreateObject(type);
  48. this.TypeObjectDictionary[type] = result;
  49. }
  50. break;
  51. case LifeTimeType.PerThread:
  52. //怎么包管用线程校验呢? 线程槽,把数据存在这里
  53. {
  54. string key = type.FullName;
  55. object oValue = CallContext.GetData(key);
  56. if (oValue == null)
  57. {
  58. result = (T)this.CreateObject(type);
  59. CallContext.SetData(key, result);
  60. }
  61. else
  62. {
  63. result = (T)oValue;
  64. }
  65. }
  66. break;
  67. default:
  68. throw new Exception("wrong LifeTime");
  69. }
  70. return result;
  71. }
  72. private object CreateObject(Type type)
  73. {
  74. ConstructorInfo[] ctorArray = type.GetConstructors();
  75. ConstructorInfo ctor = null;
  76. if (ctorArray.Count(c => c.IsDefined(typeof(BingleInjectionConstructorAttribute), true)) > 0)
  77. {
  78. ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(BingleInjectionConstructorAttribute), true));
  79. }
  80. else
  81. {
  82. ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
  83. }
  84. List<object> paraList = new List<object>();
  85. foreach (var parameter in ctor.GetParameters())
  86. {
  87. Type paraType = parameter.ParameterType;
  88. RegisterInfo info = BingleContainerDictionary[paraType.FullName];
  89. Type targetType = info.TargetType;
  90. //object para = this.CreateObject(targetType);
  91. object para = null;
  92. #region
  93. {
  94. switch (info.LifeTime)
  95. {
  96. case LifeTimeType.Transient:
  97. para = this.CreateObject(targetType);
  98. break;
  99. case LifeTimeType.Singleton:
  100. //需要线程安全 双if+lock
  101. {
  102. if (this.TypeObjectDictionary.ContainsKey(targetType))
  103. {
  104. para = this.TypeObjectDictionary[targetType];
  105. }
  106. else
  107. {
  108. para = this.CreateObject(targetType);
  109. this.TypeObjectDictionary[targetType] = para;
  110. }
  111. }
  112. break;
  113. case LifeTimeType.PerThread:
  114. //怎么包管用线程校验呢? 线程槽,把数据存在这里
  115. {
  116. string key = targetType.FullName;
  117. object oValue = CallContext.GetData(key);
  118. if (oValue == null)
  119. {
  120. para = this.CreateObject(targetType);
  121. CallContext.SetData(key, para);
  122. }
  123. else
  124. {
  125. para = oValue;
  126. }
  127. }
  128. break;
  129. default:
  130. throw new Exception("wrong LifeTime");
  131. }
  132. }
  133. #endregion
  134. //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
  135. paraList.Add(para);
  136. }
  137. return Activator.CreateInstance(type, paraList.ToArray());
  138. }
  139. //属性注入+方法注入?
  140. }
复制代码
  1. public class RegisterInfo
  2. {
  3. /// <summary>
  4. /// 目的范例
  5. /// </summary>
  6. public Type TargetType { get; set; }
  7. /// <summary>
  8. /// 生命周期
  9. /// </summary>
  10. public LifeTimeType LifeTime { get; set; }
  11. }
  12. public enum LifeTimeType
  13. {
  14. Transient,
  15. Singleton,
  16. PerThread
  17. }
复制代码
  1. IBingleContainer container = new BingleContainer();
  2. container.RegisterType<IPhone, AndroidPhone>(LifeTimeType.PerThread);
  3. container.RegisterType<AbstractPad, ApplePad>(LifeTimeType.PerThread);
  4. container.RegisterType<IHeadphone, Headphone>(LifeTimeType.Transient);
  5. container.RegisterType<IMicrophone, Microphone>(LifeTimeType.Singleton);
  6. container.RegisterType<IPower, Power>();
  7. container.RegisterType<IBLL.IBaseBll, BLL.BaseBll>();
  8. container.RegisterType<IDAL.IBaseDAL, Ruamou.DAL.BaseDAL>();
  9. IPhone pad1 = null;
  10. IPhone pad2 = null;
  11. IPhone pad3 = null;
  12. //pad1 = container.Resolve<IPhone>();
  13. Action act1 = new Action(() =>
  14. {
  15. pad1 = container.Resolve<IPhone>();
  16. Console.WriteLine($"pad1由线程id={Thread.CurrentThread.ManagedThreadId}");
  17. });
  18. var result1 = act1.BeginInvoke(null, null);
  19. Action act2 = new Action(() =>
  20. {
  21. pad2 = container.Resolve<IPhone>();
  22. Console.WriteLine($"pad2由线程id={Thread.CurrentThread.ManagedThreadId}");
  23. });
  24. var result2 = act2.BeginInvoke(t =>
  25. {
  26. pad3 = container.Resolve<IPhone>();
  27. Console.WriteLine($"pad3由线程id={Thread.CurrentThread.ManagedThreadId}");
  28. Console.WriteLine($"object.ReferenceEquals(pad2, pad3)={object.ReferenceEquals(pad2, pad3)}");
  29. }, null);
  30. act1.EndInvoke(result1);
  31. act2.EndInvoke(result2);
  32. Console.WriteLine($"object.ReferenceEquals(pad1, pad2)={object.ReferenceEquals(pad1, pad2)}");
复制代码

容器依赖细节?如果不想依赖细节,又想创建对象,反射+设置文件:

  1. ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
  2. fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");//找设置文件的路径
  3. Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
  4. UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
  5. IUnityContainer container = new UnityContainer();
  6. section.Configure(container, "testContainer1");
  7. // container.AddNewExtension<Interception>().Configure<Interception>()
  8. //.SetInterceptorFor<IPhone>(new InterfaceInterceptor());
  9. IPhone phone = container.Resolve<IPhone>();
  10. phone.Call();
  11. IPhone android = container.Resolve<IPhone>("Android");
  12. android.Call();
  13. IDBContext<Program> context = container.Resolve<IDBContext<Program>>();
  14. context.DoNothing();
复制代码

设置文件:

102211k7y7czzff5n7o65y.gif
102211lxz8t8lqq1s86m68.gif
  1. <unity>
  2. <!--<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>-->
  3. <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
  4. <containers>
  5. <container name="testContainer1">
  6. <extension type="Interception"/>
  7. <register type="Bingle.Interface.IPhone,Bingle.Interface" mapTo="Bingle.Service.ApplePhone, Bingle.Service"/>
  8. <!--是dll名称,不是定名空间-->
  9. <register type="Bingle.Interface.IPhone,Bingle.Interface" mapTo="Bingle.Service.AndroidPhone, Bingle.Service" name="Android">
  10. <!--别名-->
  11. <interceptor type="InterfaceInterceptor"/>
  12. <interceptionBehavior type="Bingle.Framework.AOP.LogBeforeBehavior, Bingle.Framework"/>
  13. <interceptionBehavior type="Bingle.Framework.AOP.LogAfterBehavior, Bingle.Framework"/>
  14. <interceptionBehavior type="Bingle.Framework.AOP.ParameterCheckBehavior, Bingle.Framework"/>
  15. <lifetime type="transient" />
  16. </register>
  17. <register type="Bingle.Interface.IMicrophone, Bingle.Interface" mapTo="Bingle.Service.Microphone, Bingle.Service"/>
  18. <register type="Bingle.Interface.IHeadphone, Bingle.Interface" mapTo="Bingle.Service.Headphone, Bingle.Service"/>
  19. <register type="Bingle.Interface.IPower, Bingle.Interface" mapTo="Bingle.Service.Power, Bingle.Service"/>
  20. <register type="Bingle.Interface.AbstractPad, Bingle.Interface" mapTo="Bingle.Service.ApplePad, Bingle.Service"/>
  21. <register type="Bingle.IBLL.IBaseBll, Bingle.IBLL" mapTo="Bingle.BLL.BaseBll, Bingle.BLL">
  22. <constructor>
  23. <param name="baseDAL" type="Bingle.IDAL.IBaseDAL, Bingle.IDAL" />
  24. <param name="id" type="System.Int32" value="3" />
  25. </constructor>
  26. </register>
  27. <register type="Bingle.IDAL.IBaseDAL, Bingle.IDAL" mapTo="Ruamou.DAL.BaseDAL, Ruamou.DAL"/>
  28. <register type="Bingle.IDAL.IDBContext`1, Bingle.IDAL" mapTo="Ruamou.DAL.DBContextDAL`1, Ruamou.DAL"/>
  29. </container>
  30. <unity>
复制代码
View Code







来源:https://www.cnblogs.com/taotaozhuanyong/p/11562082.html
C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则