ibcadmin 发表于 2019-10-12 10:22:07

IOC控制反转、Unity简介

<p>参考博客地点:</p>
<p> </p>
<p>Unity系列文章,推荐:http://www.cnblogs.com/qqlin/archive/2012/10/16/2717964.html</p>
<p>https://www.cnblogs.com/lyps/p/10560256.html<br /></p>
<p> </p>
<p><strong>这篇文章紧张先容.NET Framework下面的IOC以及Unity的使用,下一篇文章先容.NET Core下面自带的容器IServiceCollection以及Autofac的使用https://www.cnblogs.com/taotaozhuanyong/p/11562184.html</strong></p>
<p>IOC(Inverse of Control),控制反转。</p>
<p>说到IOC,就不得不提DI(Dependency Injection),依赖注入</p>
<p>IOC是目的结果,需要DI依赖注入的手段。</p>
<p>分层架构时这些是必须的,可以分别边界独立演化,也方便分工,促进代码复用。。</p>
<p>依赖倒置原则DIP:</p>
<p>  体系架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖。依赖抽象而不是依赖细节。在A勒种调用了B类,A类就是高层,B类就是低层。</p>
<p>面向抽象:</p>
<p>  1、一个方法满意多种范例</p>
<p>  2、支持下层的扩展。</p>
<p>下面有三种创建一个对象的方式:</p>

AndroidPhone phone = new AndroidPhone();//1 满是细节

IPhone phone = new AndroidPhone();//2 左边抽象右边细节

IPhone phone = ObjectFactory.CreatePhone();//3 封装转移


/// <summary>
/// 简朴工厂+设置文件+反射
/// </summary>
public class ObjectFactory
{
    public static IPhone CreatePhone()
    {
      string classModule = ConfigurationManager.AppSettings["iPhoneType"];
      Assembly assemly = Assembly.Load(classModule.Split(','));
      Type type = assemly.GetType(classModule.Split(','));
      return (IPhone)Activator.CreateInstance(type);//无参数构造函数
    }

    public static IPhone CreatePhone(IBaseBll iBLL)
    {
      string classModule = ConfigurationManager.AppSettings["iPhoneType"];
      Assembly assemly = Assembly.Load(classModule.Split(','));
      Type type = assemly.GetType(classModule.Split(','));
      return (IPhone)Activator.CreateInstance(type, new object[] { iBLL });
    }
}

<p>在App.config下面设置节点:</p>

<appSettings>
    <add key="iPhoneType" value="Bingle.Service.AndroidPhone,Bingle.Service" />
</appSettings>

<p>只有抽象,没有细节,好处是可扩展。</p>
<p>IOC控制反转:</p>
<p>  传统开辟,上端依赖(调用/指定)下端对象,这个样子会有依赖。控制反转就是把对下端对象的依赖转移到第三方容器(工厂+设置文件+反射),能够让程序拥有更好的扩展性。</p>
<p>下面出现一个题目:</p>
<p>  构造A对象,但是A依赖于B对象,那就先构造B,如果B又依赖C,再构造C。。。。。。</p>

IDAL.IBaseDAL baseDAL = new Ruamou.DAL.BaseDAL();
IBLL.IBaseBll baseBll = new Ruanmou.BLL.BaseBll(baseDAL);
IPhone phone = ObjectFactory.CreatePhone(baseBll);

<p>如今这个题目已经袒露了,下面开始了DI,依赖注入,就能做到构造某个对象时,将依赖的对象自动初始化并注入。</p>
<p>IOC是目的结果,需要DI依赖注入的手段。</p>
<p>DI依赖注入:</p>
<p>  三种方式注入:构造函数注入、属性注入、方法注入(按照时间顺序)</p>
<p>  //属性注入</p>

//属性注入
public IMicrophone iMicrophone { get; set; }

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

//构造函数注入:默认找参数最多的构造函数
public ApplePhoneUpdate(IHeadphone headphone)
{
    this.iHeadphone = headphone;
    Console.WriteLine("{0} 带参数构造函数", this.GetType().Name);
}

<p>  //方法注入</p>

//方法注入
public void Init(IPower power)
{
   this.iPower = power;
}

<p>如何使用Unity容器?</p>
<p>  1、安装Unity</p>
<p>  <div align="center"></div></p>
<p> </p>
<p>   2、容器三部曲:</p>
<p>    实例化容器、注册范例、获取实例</p>
<p>  3、项目版本和服务处的版本要不绝。</p>
<p>下面是Iphone与AndroidPhone的界说:</p>
<div align="center"></div><div align="center"></div>

public interface IPhone
{
   void Call();
   IMicrophone iMicrophone { get; set; }
   IHeadphone iHeadphone { get; set; }
   IPower iPower { get; set; }
}




public class AndroidPhone : IPhone
{
   public IMicrophone iMicrophone { get; set; }
   public IHeadphone iHeadphone { get; set; }
   public IPower iPower { get; set; }

   //public AndroidPhone()
   //{
   //    Console.WriteLine("{0}构造函数", this.GetType().Name);
   //}
   
   public AndroidPhone(AbstractPad pad, IHeadphone headphone)
   {
         Console.WriteLine("{0}构造函数", this.GetType().Name);
   }

   //
   public AndroidPhone(AbstractPad pad)
   {
         Console.WriteLine("{0}构造函数", this.GetType().Name);
   }
   public AndroidPhone(IBaseBll baseBll)
   {
         Console.WriteLine("{0}构造函数", this.GetType().Name);
   }

   public void Call()
   {
         Console.WriteLine("{0}打电话", this.GetType().Name); ;
   }
}

View Code

IUnityContainer container = new UnityContainer();//1 实例化容器
container.RegisterType<IPhone, AndroidPhone>();//2 注册范例
IPhone iphone = container.Resolve<IPhone>();//3 获取实例

<p>我们来看一下Unity下面RegisterType方法内里的泛型束缚:</p>
<p><div align="center"></div></p>
<p> </p>
<p>另有一个方法:</p>
<p><div align="center"></div></p>
<p> </p>
<p> </p>

IUnityContainer container = new UnityContainer();//1 实例化容器

container.RegisterInstance<AbstractPad>(new ApplePadChild());

AbstractPad abstractPad = container.Resolve<AbstractPad>();

<p>后遭的时间,有依赖:</p>
<p><div align="center"></div></p>
<p> </p>
<p> 下面来解决这个题目:但是要保持Unity版本同等</p>
<p>下面是一些注册时要依赖的范例</p>
<div align="center"></div><div align="center"></div>

public interface IHeadphone
{

}

public class Headphone : IHeadphone
{
   public Headphone(IMicrophone microphone)
   {
         Console.WriteLine("Headphone 被构造");
   }
}
public interface IMicrophone
{

}

public class Microphone : IMicrophone
{

   public Microphone(IPower power)
   {
         Console.WriteLine("Microphone 被构造");
   }
}
public interface IPower
{

}

public class Power : IPower
{
    public Power(IBLL.IBaseBll baseBll)
    {
      Console.WriteLine("Power 被构造");
    }
}
public interface IBaseBll
{
   void DoSomething();
}
public class BaseBll : IBaseBll
{
   private IBaseDAL _baseDAL = null;
   public BaseBll(IBaseDAL baseDAL, int id)
   {
         Console.WriteLine($"{nameof(BaseBll)}被构造。。。{id}。");
         this._baseDAL = baseDAL;
   }
   public void DoSomething()
   {
         this._baseDAL.Add();
         this._baseDAL.Update();
         this._baseDAL.Find();
         this._baseDAL.Delete();
   }
}

public interface IBaseDAL
{
   void Add();
   void Delete();
   void Update();
   void Find();
}
public class BaseDAL : IBaseDAL
{
    public BaseDAL()
    {
      Console.WriteLine($"{nameof(BaseDAL)}被构造。。。。");
    }

    public void Add()
    {
      Console.WriteLine($"{nameof(Add)}");
    }

    public void Delete()
    {
      Console.WriteLine($"{nameof(Delete)}");
    }

    public void Find()
    {
      Console.WriteLine($"{nameof(Find)}");
    }

    public void Update()
    {
      Console.WriteLine($"{nameof(Update)}");
    }
}

View Code
<p> </p>

IUnityContainer container = new UnityContainer();
container.RegisterType<IPhone, ApplePhone>();
container.RegisterType<IHeadphone, Headphone>();
container.RegisterType<IMicrophone, Microphone>();
container.RegisterType<IPower, Power>();
container.RegisterType<IBLL.IBaseBll, BLL.BaseBll>();
container.RegisterType<IDAL.IBaseDAL, Ruamou.DAL.BaseDAL>();
IPhone iphone = container.Resolve<IPhone>();

<p>但凡是用到了需要的范例,都要给注入进去,否则容器怎么知道范例啊</p>
<p> </p>
<p><strong>Unity内里到底是怎么实现的?下面,自己来写一个IOC</strong></p>
<p><strong>1、最最根本大略的版本:</strong></p>

public interface ILTContainer
    {
      void RegisterType<TFrom, TTo>();
      T Resolve<T>();
    }

/// <summary>
    /// 容器--工厂
    /// </summary>
    public class LTContainer : ILTContainer
    {
      private Dictionary<string, Type> LTDic = new Dictionary<string, Type>();

      public void RegisterType<TFrom, TTo>()
      {
            LTDic.Add(typeof(TFrom).FullName, typeof(TTo));
      }

      public T Resolve<T>()
      {
            Type type = LTDic;
            return (T)Activator.CreateInstance(type);
      }
    }
}

<p>调用一下:</p>

ILTContainer container = new LTContainer();
container.RegisterType<IPerson, Student>();

var person = container.Resolve<IPerson>();

<p> </p>
<p><strong>2、升级一点点</strong></p>
<p><div align="center"></div></p>
<p> </p>
<p> </p>

public interface IPerson
    {

    }

    public class Student : IPerson
    {
      
      public Student(Animal animal)
      {
            Console.WriteLine("Student被构造了...");
      }

    }

    public abstract class Animal
    {
    }

    public class Cat : Animal
    {
      public Cat()
      {
            Console.WriteLine("Animal被构造了....");
      }
    }
}


public interface ILTContainer
    {
      void RegisterType<TFrom, TTo>();
      T Resolve<T>();
    }


    /// <summary>
    /// 容器--工厂
    /// </summary>
    public class LTContainer : ILTContainer
    {
      private Dictionary<string, Type> LTDic = new Dictionary<string, Type>();

      public void RegisterType<TFrom, TTo>()
      {
            LTDic.Add(typeof(TFrom).FullName, typeof(TTo));
      }

      public T Resolve<T>()
      {
            Type type = LTDic;
            var ctorArray = type.GetConstructors();
            ConstructorInfo ctor = null;
            if (ctorArray.Count(c => c.IsDefined(typeof(LTInjectionConstructorAttribute), true)) > 0)
            {
                ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(LTInjectionConstructorAttribute), true));
            }
            else
            {
                ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
            }
            List<object> paraList = new List<object>();
            foreach (var item in ctor.GetParameters())
            {
                Type paraType = item.ParameterType;
                Type targetType = this.LTDic;
                paraList.Add(Activator.CreateInstance(targetType));
            }
            return (T)Activator.CreateInstance(type, paraList.ToArray());
            //return (T)this.CreateObject(type);

      }

      private object CreateObject(Type type)
      {
            ConstructorInfo[] ctorArray = type.GetConstructors();
            ConstructorInfo ctor = null;
            if (ctorArray.Count(c => c.IsDefined(typeof(LTInjectionConstructorAttribute), true)) > 0)
            {
                ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(LTInjectionConstructorAttribute), true));
            }
            else
            {
                ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
            }
            List<object> paraList = new List<object>();
            foreach (var parameter in ctor.GetParameters())
            {
                Type paraType = parameter.ParameterType;
                Type targetType = this.LTDic;
                object para = this.CreateObject(targetType);
                //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
                paraList.Add(para);
            }
            return Activator.CreateInstance(type, paraList.ToArray());
      }
      //属性注入+方法注入?

    }

<p>调用一下:</p>

ILTContainer container = new LTContainer();
ILTContainer container = new LTContainer();
container.RegisterType<IPerson, Student>();
container.RegisterType<Animal, Cat>();
var person = container.Resolve<IPerson>();

<p><strong>3、再升级一点点:</strong></p>
<p>  继承找出targetType的构造,找出一个符合的构造函数,分别构造其参数,继承...递归</p>
<p><div align="center"></div></p>
<p> </p>
<p> </p>

public interface ILTContainer
    {
      void RegisterType<TFrom, TTo>();
      T Resolve<T>();
    }


    /// <summary>
    /// 容器--工厂
    /// </summary>
    public class LTContainer : ILTContainer
    {
      private Dictionary<string, Type> LTDic = new Dictionary<string, Type>();

      public void RegisterType<TFrom, TTo>()
      {
            LTDic.Add(typeof(TFrom).FullName, typeof(TTo));
      }

      public T Resolve<T>()
      {
            Type type = LTDic;
            //继承找出targetType的构造函数,找出一个符合的构造函数,分别构造其参数
            //继承......递归
            return (T)this.CreateObject(type);

      }


      public object CreateObject(Type type)
      {
            ConstructorInfo[] ctorArray = type.GetConstructors();
            ConstructorInfo ctor = null;
            if (ctorArray.Count(c => c.IsDefined(typeof(LTContainer), true)) > 0)
            {
                ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(LTContainer), true));
            }
            else
            {
                ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
            }
            List<object> paraList = new List<object>();
            foreach (var parameter in ctor.GetParameters())
            {
                Type paraType = parameter.ParameterType;
                Type targetType = this.LTDic;
                object para = this.CreateObject(targetType);
                //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
                paraList.Add(para);
            }
            return Activator.CreateInstance(type, paraList.ToArray());
      }
      //属性注入+方法注入?

    }

<p> </p>
<p><strong>生命管理周期:</strong></p>

IUnityContainer container = new UnityContainer();

<p><strong>默认瞬时生命周期</strong>:每次都是构造一个新的</p>

container.RegisterType<AbstractPad, ApplePad>();
container.RegisterType<AbstractPad, ApplePad>(new TransientLifetimeManager());

<p><strong>全局单例</strong>:全局就只有一个该范例实例</p>
<p>非欺压性,只有通过容器获取才是单例;项目中一般推荐容器单例而不是自己写单例</p>

container.RegisterType<AbstractPad, ApplePad>(new SingletonLifetimeManager());
AbstractPad pad1 = container.Resolve<AbstractPad>();
AbstractPad pad2 = container.Resolve<AbstractPad>();
Console.WriteLine(object.ReferenceEquals(pad1, pad2));

<p><strong>线程单例</strong>:同一个线程就只有一个实例,不同线程就是不同实例</p>

container.RegisterType<AbstractPad, ApplePad>(new PerThreadLifetimeManager());
AbstractPad pad1 = null;
AbstractPad pad2 = null;
AbstractPad pad3 = null;

Action act1 = new Action(() =>
                {
                  pad1 = container.Resolve<AbstractPad>();
                  Console.WriteLine($"pad1由线程id={Thread.CurrentThread.ManagedThreadId}");
                });
var result1 = act1.BeginInvoke(null, null);

Action act2 = new Action(() =>
{
    pad2 = container.Resolve<AbstractPad>();
    Console.WriteLine($"pad2由线程id={Thread.CurrentThread.ManagedThreadId}");
});
var result2 = act2.BeginInvoke(t =>
{
    pad3 = container.Resolve<AbstractPad>();
    Console.WriteLine($"pad3由线程id={Thread.CurrentThread.ManagedThreadId}");
    Console.WriteLine($"object.ReferenceEquals(pad2, pad3)={object.ReferenceEquals(pad2, pad3)}");
}, null);

act1.EndInvoke(result1);
act2.EndInvoke(result2);

Console.WriteLine($"object.ReferenceEquals(pad1, pad2)={object.ReferenceEquals(pad1, pad2)}");
<p>//ExternallyControlledLifetimeManager 外部可开释单例<br />//PerResolveLifetimeManager循环引用</p>






<p> </p>
<p><strong> 自己写的容器内里,加上生命周期:</strong></p>

public interface IBingleContainer
{
   void RegisterType<TFrom, TTo>(LifeTimeType lifeTimeType = LifeTimeType.Transient);
   T Resolve<T>();
}

/// <summary>
/// 容器--工厂
/// </summary>
public class BingleContainer : IBingleContainer
{
   private Dictionary<string, RegisterInfo> BingleContainerDictionary = new Dictionary<string, RegisterInfo>();
   

   /// <summary>
   /// 缓存起来,范例的对象实例
   /// </summary>
   private Dictionary<Type, object> TypeObjectDictionary = new Dictionary<Type, object>();

   /// <summary>
   ///
   /// </summary>
   /// <typeparam name="TFrom"></typeparam>
   /// <typeparam name="TTo"></typeparam>
   /// <param name="lifeTimeType">默认参数,不通报就是Transient</param>
   public void RegisterType<TFrom, TTo>(LifeTimeType lifeTimeType = LifeTimeType.Transient)
   {
         BingleContainerDictionary.Add(typeof(TFrom).FullName, new RegisterInfo()
         {
             TargetType = typeof(TTo),
             LifeTime = lifeTimeType
         });
   }

   public T Resolve<T>()
   {
         RegisterInfo info = BingleContainerDictionary;
         Type type = BingleContainerDictionary.TargetType;
         T result = default(T);
         switch (info.LifeTime)
         {
             case LifeTimeType.Transient:
               result = (T)this.CreateObject(type);
               break;
             case LifeTimeType.Singleton:
               if (this.TypeObjectDictionary.ContainsKey(type))
               {
                     result = (T)this.TypeObjectDictionary;
               }
               else
               {
                     result = (T)this.CreateObject(type);
                     this.TypeObjectDictionary = result;
               }
               break;
             case LifeTimeType.PerThread:
               //怎么包管用线程校验呢? 线程槽,把数据存在这里
               {
                     string key = type.FullName;
                     object oValue = CallContext.GetData(key);
                     if (oValue == null)
                     {
                         result = (T)this.CreateObject(type);
                         CallContext.SetData(key, result);
                     }
                     else
                     {
                         result = (T)oValue;
                     }
               }
               break;
             default:
               throw new Exception("wrong LifeTime");
         }
         return result;
   }
   private object CreateObject(Type type)
   {
         ConstructorInfo[] ctorArray = type.GetConstructors();
         ConstructorInfo ctor = null;
         if (ctorArray.Count(c => c.IsDefined(typeof(BingleInjectionConstructorAttribute), true)) > 0)
         {
             ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(BingleInjectionConstructorAttribute), true));
         }
         else
         {
             ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
         }
         List<object> paraList = new List<object>();
         foreach (var parameter in ctor.GetParameters())
         {
             Type paraType = parameter.ParameterType;
             RegisterInfo info = BingleContainerDictionary;
             Type targetType = info.TargetType;
             //object para = this.CreateObject(targetType);
             object para = null;
             #region
                {
                  switch (info.LifeTime)
                  {
                        case LifeTimeType.Transient:
                            para = this.CreateObject(targetType);
                            break;
                        case LifeTimeType.Singleton:
                            //需要线程安全 双if+lock
                            {
                              if (this.TypeObjectDictionary.ContainsKey(targetType))
                              {
                                    para = this.TypeObjectDictionary;
                              }
                              else
                              {
                                    para = this.CreateObject(targetType);
                                    this.TypeObjectDictionary = para;
                              }
                            }
                            break;
                        case LifeTimeType.PerThread:
                            //怎么包管用线程校验呢? 线程槽,把数据存在这里
                            {
                              string key = targetType.FullName;
                              object oValue = CallContext.GetData(key);
                              if (oValue == null)
                              {
                                    para = this.CreateObject(targetType);
                                    CallContext.SetData(key, para);
                              }
                              else
                              {
                                    para = oValue;
                              }
                            }
                            break;
                        default:
                            throw new Exception("wrong LifeTime");
                  }
                }
                #endregion
             //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
             paraList.Add(para);
         }
         return Activator.CreateInstance(type, paraList.ToArray());
   }
   //属性注入+方法注入?


}


public class RegisterInfo
{
    /// <summary>
    /// 目的范例
    /// </summary>
    public Type TargetType { get; set; }
    /// <summary>
    /// 生命周期
    /// </summary>
    public LifeTimeType LifeTime { get; set; }
}

public enum LifeTimeType
{
    Transient,
    Singleton,
    PerThread
}


IBingleContainer container = new BingleContainer();
container.RegisterType<IPhone, AndroidPhone>(LifeTimeType.PerThread);
container.RegisterType<AbstractPad, ApplePad>(LifeTimeType.PerThread);
container.RegisterType<IHeadphone, Headphone>(LifeTimeType.Transient);
container.RegisterType<IMicrophone, Microphone>(LifeTimeType.Singleton);
container.RegisterType<IPower, Power>();
container.RegisterType<IBLL.IBaseBll, BLL.BaseBll>();
container.RegisterType<IDAL.IBaseDAL, Ruamou.DAL.BaseDAL>();
IPhone pad1 = null;
IPhone pad2 = null;
IPhone pad3 = null;
//pad1 = container.Resolve<IPhone>();
Action act1 = new Action(() =>
{
   pad1 = container.Resolve<IPhone>();
   Console.WriteLine($"pad1由线程id={Thread.CurrentThread.ManagedThreadId}");
});
var result1 = act1.BeginInvoke(null, null);

Action act2 = new Action(() =>
{
   pad2 = container.Resolve<IPhone>();
   Console.WriteLine($"pad2由线程id={Thread.CurrentThread.ManagedThreadId}");
});
var result2 = act2.BeginInvoke(t =>
{
   pad3 = container.Resolve<IPhone>();
   Console.WriteLine($"pad3由线程id={Thread.CurrentThread.ManagedThreadId}");
   Console.WriteLine($"object.ReferenceEquals(pad2, pad3)={object.ReferenceEquals(pad2, pad3)}");
}, null);

act1.EndInvoke(result1);
act2.EndInvoke(result2);

Console.WriteLine($"object.ReferenceEquals(pad1, pad2)={object.ReferenceEquals(pad1, pad2)}");

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

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");//找设置文件的路径
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);

IUnityContainer container = new UnityContainer();
section.Configure(container, "testContainer1");

// container.AddNewExtension<Interception>().Configure<Interception>()
//.SetInterceptorFor<IPhone>(new InterfaceInterceptor());

IPhone phone = container.Resolve<IPhone>();
phone.Call();
IPhone android = container.Resolve<IPhone>("Android");
android.Call();

IDBContext<Program> context = container.Resolve<IDBContext<Program>>();
context.DoNothing();

<p>设置文件:</p>
<div align="center"></div><div align="center"></div>

<unity>
   <!--<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>-->
   <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
   <containers>
   <container name="testContainer1">
       <extension type="Interception"/>
       <register type="Bingle.Interface.IPhone,Bingle.Interface" mapTo="Bingle.Service.ApplePhone, Bingle.Service"/>
       <!--是dll名称,不是定名空间-->
       <register type="Bingle.Interface.IPhone,Bingle.Interface" mapTo="Bingle.Service.AndroidPhone, Bingle.Service" name="Android">
         <!--别名-->
         <interceptor type="InterfaceInterceptor"/>
         <interceptionBehavior type="Bingle.Framework.AOP.LogBeforeBehavior, Bingle.Framework"/>
         <interceptionBehavior type="Bingle.Framework.AOP.LogAfterBehavior, Bingle.Framework"/>
         <interceptionBehavior type="Bingle.Framework.AOP.ParameterCheckBehavior, Bingle.Framework"/>
         <lifetime type="transient" />
       </register>

       <register type="Bingle.Interface.IMicrophone, Bingle.Interface" mapTo="Bingle.Service.Microphone, Bingle.Service"/>
       <register type="Bingle.Interface.IHeadphone, Bingle.Interface" mapTo="Bingle.Service.Headphone, Bingle.Service"/>
       <register type="Bingle.Interface.IPower, Bingle.Interface" mapTo="Bingle.Service.Power, Bingle.Service"/>
       <register type="Bingle.Interface.AbstractPad, Bingle.Interface" mapTo="Bingle.Service.ApplePad, Bingle.Service"/>
       <register type="Bingle.IBLL.IBaseBll, Bingle.IBLL" mapTo="Bingle.BLL.BaseBll, Bingle.BLL">
         <constructor>
         <param name="baseDAL" type="Bingle.IDAL.IBaseDAL, Bingle.IDAL"/>
         <param name="id" type="System.Int32" value="3" />
         </constructor>
       </register>
       <register type="Bingle.IDAL.IBaseDAL, Bingle.IDAL" mapTo="Ruamou.DAL.BaseDAL, Ruamou.DAL"/>
       <register type="Bingle.IDAL.IDBContext`1, Bingle.IDAL" mapTo="Ruamou.DAL.DBContextDAL`1, Ruamou.DAL"/>
   </container>
    <unity>

View Code
<p> </p><br><br/><br/><br/><br/><br/>来源:<a href="https://www.cnblogs.com/taotaozhuanyong/p/11562082.html" target="_blank">https://www.cnblogs.com/taotaozhuanyong/p/11562082.html</a>
页: [1]
查看完整版本: IOC控制反转、Unity简介