• C# Unity容器的使用


    最简单的使用方式(记得安装Unity NuGet包呀)

                   Console.WriteLine("***************Unity容器的初步应用***************");
                   IUnityContainer container = new UnityContainer();//1 声明一个容器
                   container.RegisterType<IPhone, AndroidPhone>();//2 初始化容器 注册类型
                   IPhone phone = container.Resolve<IPhone>();//3 反射创建对象
                   phone.Call();
    
    • 当你想使用一个接口 注册不同类型是 你需要指定名称 像下面这样 child、grandchild 便是指定的名称
                   container.RegisterType<AbstractPad, ApplePad>();//抽象类      
                   container.RegisterType<AbstractPad, ApplePad>("child");//1对多
                   container.RegisterType<AbstractPad, ApplePadChild>("grandchild");//1对多
    

    这样在你创建时 你可以像下面这样 指定创建

                   AbstractPad pad = container.Resolve<AbstractPad>();
                   var childPad = container.Resolve<AbstractPad>("child");
                   var grandchildPad = container.Resolve<AbstractPad>("grandchild");
    

    否则 注册是会出现覆盖的情况的 如下

                   container.RegisterType<AbstractPad, ApplePad>();//抽象类
                   container.RegisterType<AbstractPad, ApplePadChild>();//覆盖的
    

    若是此时你创建对象 则pad将是 ApplePadChild类型

     var pad = container.Resolve<AbstractPad>();
    
    • 另外 父子类也会出现覆盖现象 比如
                    container.RegisterType<AbstractPad, ApplePad>();//抽象类
                    container.RegisterType<ApplePad, ApplePadChild>();//父子类  会覆盖<AbstractPad, ApplePad>  因为这个也是AbstractPad 
    

    此时创建对象 则pad也是 ApplePadChild类型

     var pad = container.Resolve<AbstractPad>();
    

    三种注入方式

    • 属性注入 添加标识[Dependency]
            [Dependency]//属性注入:不错,但是有对容器有依赖
            public IMicrophone iMicrophone { get; set; }
    
    • 构造函数注入--标识 [InjectionConstructor]
            [InjectionConstructor]//构造函数注入:最好的,默认找参数最多的构造函数 【插注:.net core 内置容器默认寻找最少参数构造参数】
            public ApplePhone(IHeadphone headphone)
            {
                this.iHeadphone = headphone;
                Console.WriteLine("{0}带参数构造函数", this.GetType().Name);
            }
    

    此处的[InjectionConstructor]标识可省略 省略后 默认找参数最多的构造函数

    • 方法注入--标识[InjectionMethod]
            [InjectionMethod]//方法注入:最不好的,增加一个没有意义的方法,破坏封装
            public void Init1234(IPower power)
            {
                this.iPower = power;
            }
    

    生命周期管理

                    //容器成了对象创建的入口,可以加入自己的管理逻辑:生命周期
                    IUnityContainer container = new UnityContainer();
                    container.RegisterType<IPhone, AndroidPhone>();//默认 瞬时
                    container.RegisterType<IPhone, AndroidPhone>(new TransientLifetimeManager());//默认  瞬时  每一次都是全新生成
                    container.RegisterType<IPhone, AndroidPhone>(new ContainerControlledLifetimeManager());//容器单例  单例就需自己实现
                                    //container.RegisterType<IPhone, AndroidPhone>(new PerThreadLifetimeManager());//线程单例:相同线程的实例相同 不同线程的实例不同   web请求/多线程操作
                    container.RegisterType<IPhone, AndroidPhone>(new HierarchicalLifetimeManager());//分级容器单例
                    IUnityContainer childContainer = container.CreateChildContainer();//获取子容器
    
                    container.RegisterType<IPhone, AndroidPhone>(new ExternallyControlledLifetimeManager()); //外部可释放单例 单例是全局唯一;一旦释放大家都没了;
                    container.RegisterType<IPhone, AndroidPhone>(new PerResolveLifetimeManager());//循环引用 不推荐
    

    配置文件使用

                //不想要类;但是程序运行又必须要细节;配置文件
                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, "testContainer");//配置文件节点名
                IPhone phone = container.Resolve<IPhone>();
                phone.Call();
    
                IPhone android = container.Resolve<IPhone>("Android");
                android.Call();
    

    Aop配置

      <container name="testContainerAOP">
            <extension type="Interception"/>
            <register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend">
              <interceptor type="InterfaceInterceptor"/>//以下是AOP插入工作
              <interceptionBehavior type="Ruanmou.Framework.AOP.AuthorizeBehavior, Ruanmou.Framework"/>//type=类名, 类所在dll名称
              <interceptionBehavior type="Ruanmou.Framework.AOP.SmsBehavior, Ruanmou.Framework"/>
              <interceptionBehavior type="Ruanmou.Framework.AOP.ExceptionLoggingBehavior, Ruanmou.Framework"/>
              <interceptionBehavior type="Ruanmou.Framework.AOP.CachingBehavior, Ruanmou.Framework"/>
              <interceptionBehavior type="Ruanmou.Framework.AOP.LogBeforeBehavior, Ruanmou.Framework"/>
              <interceptionBehavior type="Ruanmou.Framework.AOP.ParameterCheckBehavior, Ruanmou.Framework"/>
              <interceptionBehavior type="Ruanmou.Framework.AOP.LogAfterBehavior, Ruanmou.Framework"/>
            </register>
            <register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend" name="Android"/>
            <register type="Ruanmou.Interface.IMicrophone, Ruanmou.Interface" mapTo="Ruanmou.Service.Microphone, Ruanmou.Service.Extend"/>
           
            </register>
          </container>
    
  • 相关阅读:
    关于Java的i++和++i的区别
    Java基础(八 前面补充)
    Java基础(七)
    Java基础(六)
    Java基础(五)
    Java基础(四)
    Java基础(三)
    Java基础(二)
    Java基础
    阿里技术专员《并发编程技术分享》
  • 原文地址:https://www.cnblogs.com/Alicia-meng/p/13551564.html
Copyright © 2020-2023  润新知