参考博客地点:
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、支持下层的扩展。
下面有三种创建一个对象的方式:
- 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(',')[1]);
- Type type = assemly.GetType(classModule.Split(',')[0]);
- return (IPhone)Activator.CreateInstance(type);//无参数构造函数
- }
- public static IPhone CreatePhone(IBaseBll iBLL)
- {
- string classModule = ConfigurationManager.AppSettings["iPhoneType"];
- Assembly assemly = Assembly.Load(classModule.Split(',')[1]);
- Type type = assemly.GetType(classModule.Split(',')[0]);
- return (IPhone)Activator.CreateInstance(type, new object[] { iBLL });
- }
- }
复制代码
在App.config下面设置节点:
- <appSettings>
- <add key="iPhoneType" value="Bingle.Service.AndroidPhone,Bingle.Service" />
- </appSettings>
复制代码
只有抽象,没有细节,好处是可扩展。
IOC控制反转:
传统开辟,上端依赖(调用/指定)下端对象,这个样子会有依赖。控制反转就是把对下端对象的依赖转移到第三方容器(工厂+设置文件+反射),能够让程序拥有更好的扩展性。
下面出现一个题目:
构造A对象,但是A依赖于B对象,那就先构造B,如果B又依赖C,再构造C。。。。。。
- IDAL.IBaseDAL baseDAL = new Ruamou.DAL.BaseDAL();
- IBLL.IBaseBll baseBll = new Ruanmou.BLL.BaseBll(baseDAL);
- IPhone phone = ObjectFactory.CreatePhone(baseBll);
复制代码
如今这个题目已经袒露了,下面开始了DI,依赖注入,就能做到构造某个对象时,将依赖的对象自动初始化并注入。
IOC是目的结果,需要DI依赖注入的手段。
DI依赖注入:
三种方式注入:构造函数注入、属性注入、方法注入(按照时间顺序)
[Dependency]//属性注入
- [Dependency]//属性注入
- public IMicrophone iMicrophone { get; set; }
复制代码
[InjectionConstructor]//构造函数注入,默认找参数最多的构造函数,方法注入不加这个特性也是可以的,可以不消特性,可以去掉对容器的依赖
- [InjectionConstructor]//构造函数注入:默认找参数最多的构造函数
- public ApplePhoneUpdate(IHeadphone headphone)
- {
- this.iHeadphone = headphone;
- Console.WriteLine("{0} 带参数构造函数", this.GetType().Name);
- }
复制代码
[InjectionMethod]//方法注入
- [InjectionMethod]//方法注入
- public void Init(IPower power)
- {
- this.iPower = power;
- }
复制代码
如何使用Unity容器?
1、安装Unity
2、容器三部曲:
实例化容器、注册范例、获取实例
3、项目版本和服务处的版本要不绝。
下面是Iphone与AndroidPhone的界说:
- 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);
- }
- //[ElevenInjectionConstructor]
- 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 获取实例
复制代码
我们来看一下Unity下面RegisterType方法内里的泛型束缚:
另有一个方法:
- IUnityContainer container = new UnityContainer();//1 实例化容器
- container.RegisterInstance<AbstractPad>(new ApplePadChild());
- AbstractPad abstractPad = container.Resolve<AbstractPad>();
复制代码
后遭的时间,有依赖:
下面来解决这个题目:但是要保持Unity版本同等
下面是一些注册时要依赖的范例
- 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
- 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>();
复制代码
但凡是用到了需要的范例,都要给注入进去,否则容器怎么知道范例啊
Unity内里到底是怎么实现的?下面,自己来写一个IOC
1、最最根本大略的版本:
- 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[typeof(T).FullName];
- return (T)Activator.CreateInstance(type);
- }
- }
- }
复制代码
调用一下:
- ILTContainer container = new LTContainer();
- container.RegisterType<IPerson, Student>();
- var person = container.Resolve<IPerson>();
复制代码
2、升级一点点
- public interface IPerson
- {
- }
- public class Student : IPerson
- {
- [LTInjectionConstructor]
- 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[typeof(T).FullName];
- 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[paraType.FullName];
- 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[paraType.FullName];
- object para = this.CreateObject(targetType);
- //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
- paraList.Add(para);
- }
- return Activator.CreateInstance(type, paraList.ToArray());
- }
- //属性注入+方法注入?
- }
复制代码
调用一下:
- ILTContainer container = new LTContainer();
- ILTContainer container = new LTContainer();
- container.RegisterType<IPerson, Student>();
- container.RegisterType<Animal, Cat>();
- var person = container.Resolve<IPerson>();
复制代码
3、再升级一点点:
继承找出targetType的构造,找出一个符合的构造函数,分别构造其参数,继承...递归
- 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[typeof(T).FullName];
- //继承找出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[paraType.FullName];
- object para = this.CreateObject(targetType);
- //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
- paraList.Add(para);
- }
- return Activator.CreateInstance(type, paraList.ToArray());
- }
- //属性注入+方法注入?
- }
复制代码
生命管理周期:
- IUnityContainer container = new UnityContainer();
复制代码
默认瞬时生命周期:每次都是构造一个新的
- container.RegisterType<AbstractPad, ApplePad>();
- container.RegisterType<AbstractPad, ApplePad>(new TransientLifetimeManager());
复制代码
全局单例:全局就只有一个该范例实例
非欺压性,只有通过容器获取才是单例;项目中一般推荐容器单例而不是自己写单例
- container.RegisterType<AbstractPad, ApplePad>(new SingletonLifetimeManager());
- AbstractPad pad1 = container.Resolve<AbstractPad>();
- AbstractPad pad2 = container.Resolve<AbstractPad>();
- Console.WriteLine(object.ReferenceEquals(pad1, pad2));
复制代码
线程单例:同一个线程就只有一个实例,不同线程就是不同实例
- 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)}");
复制代码//ExternallyControlledLifetimeManager 外部可开释单例 //PerResolveLifetimeManager 循环引用
自己写的容器内里,加上生命周期:
- 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[typeof(T).FullName];
- Type type = BingleContainerDictionary[typeof(T).FullName].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[type];
- }
- else
- {
- result = (T)this.CreateObject(type);
- this.TypeObjectDictionary[type] = 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[paraType.FullName];
- 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[targetType];
- }
- else
- {
- para = this.CreateObject(targetType);
- this.TypeObjectDictionary[targetType] = 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)}");
复制代码
容器依赖细节?如果不想依赖细节,又想创建对象,反射+设置文件:
- 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();
复制代码
设置文件:
- <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
来源:https://www.cnblogs.com/taotaozhuanyong/p/11562082.html |