IOC Unity

IOC的功能就是类似于简单工厂+配置文件 创建对象的效果差不多,只不过功能比之强大不少,慢慢往下看吧

IOS特点

1、控制反转:把对象的创建交给第三方容器来做

2、依赖注入:是一种具体的手段,注入的对象并不是我们自己主动创建的,而是容器创建的


注入的方式分为3种:

1、属性注入:直接在属性上加上[Dependency] 在容器创建该实例的时候,会自动赋值

2、方法注入:方法上添加[InjectionMethod] 只要方法上天津爱了这个特性,在容器创建这个方法的时候,会自动调用这个方法

3、构造函数注入:[InjectionConstructor]容器创建对象的时候会有限选择带这个特性的构造函数,会根据注册的类型,找到已经注册的参数创建传过来,如果去掉这个特性,会自动选取参数最多的构造函数


注:只要添加了特性之后,如果这个类型在Unity中并没有注册的话 会报错


 [Dependency]//属性注入
        public IHome firstHome { get; set; }

        public IHome secondHome { get; set; }

        public IHome thirdHome { get; set; }

        public Chinese()
        { 
        
        }

        [InjectionConstructor]//构造函数注入  注:这个可有可无 如果没有 默认参数最多的一个构造函数
        public Chinese(IHome home)
        {
            this.thirdHome = home;
        }


        public void Say()
        {
            Console.WriteLine("我是中国人");
        }


        [InjectionMethod]//方法注入
        public void Init(IHome home)
        {
            this.secondHome = home;
        }



Unity 是创建对象的第三方容器


要想使用Unity需要先引用以下dll


下面的这个是为了AOP用的


Unity创建对象

 {
                    //创建没有依赖注入的

                    IUnityContainer container = new UnityContainer();
                    container.RegisterType<IPeople, Student>();
                    // 接口--类型  父类--子类  抽象类--子类
                    //  container.RegisterInstance<IPeople>(new Student());//实例注册,和上面的注册方式 是一样的 不过这里可以在Student(参数)可以传递参数                    
                    IPeople people = container.Resolve<IPeople>();

                }

                {
                    //创建需要依赖注入的
                    IUnityContainer container = new UnityContainer();
                    container.RegisterType<IPeople, Chinese>();
                    container.RegisterType<IHome, home>();
                    IPeople people = container.Resolve<IPeople>();
                }

                {
                    //区别一个接口下的不同类型
                    IUnityContainer container = new UnityContainer();
                    container.RegisterType<IPeople, Chinese>("Chinese");
                    container.RegisterType<IPeople, Student>("Student");
                    container.RegisterType<IHome, home>();
                    IPeople people1 = container.Resolve<IPeople>("Chinese");
                    IPeople people2 = container.Resolve<IPeople>("Student");
                }

                { 
                    //还可以设置 某种类型 是否生成单例
                    IUnityContainer container = new UnityContainer();
                    //container.RegisterType<IPeople, Chinese>(new TransientLifetimeManager());//瞬时 这种是默认的
                    container.RegisterType<IPeople, Chinese>(new ContainerControlledLifetimeManager());//容器单例
                    //container.RegisterType<IPeople, Chinese>(new PerThreadLifetimeManager());//线程单例
                    container.RegisterType<IHome, home>();
                    IPeople people2 = container.Resolve<IPeople>();
                }


Unity+配置文件 创建对象


配置文件

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity>
  

    <containers>


      <!--普通配置  可以通过后面添加 name=“”区分不同类型-->
      <container name="testContainer">
        <!--type=接口命名空间,接口dll名称-->
        <!--mapto要创建的类型的命名空间,要创建的类型的dll名称-->
        <!--name=“”用来区分相同接口下的不同类型,如果没有必要 可以不写-->
        <register type="Unity.Interface.IPeople,Unity" mapTo="Unity.Class.Chinese,Unity" name="Chinese"/>
        <register type="Unity.Interface.IPeople,Unity" mapTo="Unity.Class.Student,Unity" name="Student"/>
        <register type="Unity.Interface.IHome,Unity" mapTo="Unity.Class.home,Unity"/> 
      </container>
  
    </containers>
  </unity>
</configuration>

创建代码


下面是封装了一个通过配置文件创建对象的通用代码

  private static IUnityContainer CreateUnity(string NodeName)
        {
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config.xml");//找配置文件的路径
            Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
            IUnityContainer container = new UnityContainer();
            section.Configure(container, NodeName);
            return container;
        }

创建

 IUnityContainer container= CreateUnity("testContainer");
                    IPeople people = container.Resolve<IPeople>("Chinese");

Unity 创建 AOP

配置文件
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity>
    
    <!--下面这一句配置 是为了aop的 如果用不到可以不写-->
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>

    <containers>


      
      <!--aop的配置-->
      <container name="testContainerAOP">
        
        <extension type="Interception"/><!--配置AOP需要添加此节点-->
        
        <register type="Unity.Interface.IPeople,Unity" mapTo="Unity.Class.Chinese,Unity" name="Chinese">
          <interceptor type="InterfaceInterceptor"/><!--扩展类型的dll-->
          <interceptionBehavior type="Unity.AOP.LogBehavior, Unity"/> <!--aop方法-->
          <!--lifetime生命周期 如 transient瞬时 containercontrolled容器单例  perthread线程单例-->
          <lifetime type="transient" />
          <constructor></constructor>
        </register>
        
        
        <register type="Unity.Interface.IPeople,Unity" mapTo="Unity.Class.Student,Unity" name="Student"/>
        <register type="Unity.Interface.IHome,Unity" mapTo="Unity.Class.home,Unity"/>
      </container>
      <!--aop的配置-->    
    </containers>
  </unity>
</configuration>


AOP方法

public class LogBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("方法执行前");
            IMethodReturn im= getNext().Invoke(input, getNext);
            Console.WriteLine("方法执行后");
            return im;
        }

        public bool WillExecute
        {
            get { return true; }
        }
    }


创建方法

IUnityContainer container = CreateUnity("testContainerAOP");
                    IPeople people = container.Resolve<IPeople>("Chinese");
                    people.Say();


结果



Unity AOP之坑

在Unity配置文件创建AOP的时候,并不是默认调用参数最多的构造函数,而是去调用无参构造函数,解决办法是在配置文件中<constructor></constructor>节点里面添加参数配置 

如想要调用下面这个构造函数

public Chinese(int id)
        {
            Console.WriteLine("有参构造{0}",id.ToString());
        }


需要添加下面的这个节点
<constructor>

            <param name="id" Type="System.Int32,mscorlib" value="3" />
<!--参数名称  参数命名空间+类型名称   dll名称    value=参数值-->
          </constructor>

即可


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前言 unity的框架,除了各大公司自己内部使用的,开源并好用的实际并不是很多,我会慢慢挖掘,依次写出自己的一点见解,错误的地方,望各路大神指正。 一、基本概念 控制反转(Inversion of Control,英文缩写为IOC),我的理解就是,原本A类要获取B类的对象,需要你在A类中自己New一个对象,那么是由A来获取并控制B的对象,IOC就是把对象获取的这个过程交给容器和依赖注入来处理,A类并不知道B的对象是哪里来的,对B对象的控制,由自己变成了其他类,官方一点的概念可以百度,这个还是蛮多的。 二、StrangeIOC基础类型 实际要理解一个框架的类型,还是要自己看源码,这里我只说一下几个重要类型的作用,这个看源码的时候有个印象,也方便理解,而且说这部分的帖子也很多,我就不再赘述了。 1.Context 上下文组件定义程序边界,也就是可以把一个程序定义成多上下文,让代码更加模块化 它提供了程序入口,也算是框架中耦合度最高的地方 2.Binder和Binding 这两个类是这个框架最重要的组成部分 Binding存储了对象的绑定关系,而Binder存储了Binding的对象 3.View和Mediator MVCS中的View层,View只用于显示,也就是View只负责管理UI,Mediator负责界面逻辑,事件响应等 4.Model MVCS中的Model层,负责数据部分 5.Command MVCS中的Control层,负责执行逻辑代码 6.Service MVCS中的Service层,负责与第三方交互,这个Service我理解的,并不是一定指代服务器,也可以是其他的软件,什么都可以,它就是我们程序对外的接口 7.Dispatcher 派发器是框架内通信主线的其中一种,用来派发消息,触发命令,从而进一步解耦 8.Signal 信号是框架内另外一种通信主线,它采用强类型,来绑定信号和命令之间的关系,实现消息响应的触发 9.ReflectionBinder 反射部分,通过binding来获取类的信息,存储在ReflectedClass中 10.injector 注入器,通过反射获取的信息,来实例化请求的对象 --------------------- 作者:蓝天小僧 来源:CSDN 原文:https://blog.csdn.net/zcaixzy5211314/article/details/80876228 版权声明:本文为博主原创文章,转载请附上博文链接!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值