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>
posted @ 2020-08-24 00:21  C余L小R鱼  阅读(779)  评论(0编辑  收藏  举报