IOC、DI<5> Unity、AOP、延迟获取对象、检索容器中注册信息

在这里插入图片描述
在这里插入图片描述

Unity.InterceptionExtension.ICallHandler实现一个操作日志记录功能

其它跟上一次一样
在这里插入图片描述

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration" />
  
  </configSections>
  
  <unity>
    <typeAliases>
    <typeAlias  alias="IPhone" type="ZEN.Interface.IPhone,ZEN.Interface"></typeAlias >
     <typeAlias  alias="IWork" type="ZEN.Interface.IWork,ZEN.Interface"></typeAlias >
     <typeAlias  alias="IPower" type="ZEN.Interface.IPower,ZEN.Interface"></typeAlias >
    <typeAlias  alias="ICar" type="ZEN.Interface.ICar,ZEN.Interface"></typeAlias >
  <typeAlias  alias="Phone" type="ZEN.Service.Phone,ZEN.Service"></typeAlias >
     <typeAlias  alias="Work" type="ZEN.Service.Work,ZEN.Service"></typeAlias >
     <typeAlias  alias="Power" type="ZEN.Service.Power,ZEN.Service"></typeAlias >
          <typeAlias  alias="Car" type="ZEN.Service.TeslaCar,ZEN.Service"></typeAlias >
  </typeAliases>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration" />
    <containers>
      <container name="testContainer">
         <extension type="Interception"/>
         <register type="IPhone" mapTo="Phone" />
         <register type="IPower" mapTo="Power" />
        <register type="ICar" mapTo="Car" name="tesla" >
            <property name="work" dependencyType="IWork" />
            <property name="phone" dependencyType="IPhone" />
          <method name="InitIphone">
            <param name="_power" type="IPower" />
            <param name="val" type="int" value="33"/>
          </method>
          <policyInjection></policyInjection>
           <interceptor type="InterfaceInterceptor"/>
          <!--<interceptionBehavior type="IOC.Common.IOC_AOP.AOP, IOC.Common"/>-->
        </register>
         <register type="IWork" mapTo="Work" />     
       
       
      </container>
    </containers>
  </unity>
</configuration>

在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Interception.PolicyInjection.Pipeline;

namespace IOC.Common.IOC_AOP
{
    class SimpleCallHandler : ICallHandler
    {
        public int Order {
            get;
            set;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            Console.WriteLine(input.Target.GetType().Name);
            return getNext()(input, getNext);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Interception.PolicyInjection.Pipeline;
using Unity.Interception.PolicyInjection.Policies;

namespace IOC.Common.IOC_AOP
{
  
    public class SimpleCallHandlerAttribute : HandlerAttribute
    {        
        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new SimpleCallHandler() { Order=this.Order};
        }
    }
}

在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IOC.Common.IOC_AOP;
namespace ZEN.Interface
{
    public interface ICar
    {

        [SimpleCallHandler]
        void GetName();
        void GetPrice();
        void GetMaxSpeed();
    }
}

在这里插入图片描述
在这里插入图片描述

对IUnityContainer 进行封装

走指定构造函数

就不需要加特性啦
这样既可完成对象注册的同时对构造函数参数进行注入,此时还有另外一个需求,就是虽然在注册的时候已经对构造函数参数进行了初始化
在Unity中,已经帮我们解决了这个问题,我们可以通过ParameterOverride和ParameterOverrides来实现,其中ParameterOverride是针对一个参数,而ParameterOverrides是针对参数列表,有关注册参数初始化及参数重载的全部代码如下:

1、在使用ParameterOverride方法来重载参数时,如果注册的参数是一个具体的对象就需要使用OnType这个扩展方法来指定对应的类型,否则会报错。

2、在使用ParameterOverrides进行重载参数时,可以使用如上面代码的方式进行指定,但是同样需要使用OnType来指定,不过这个的OnType指定的类型是注册的对象类型。

注册类型同时初始化构造函数参数并重载调用

在这里插入图片描述
》》如果初始化是三个参数的构造函数, Resolve解析,是2个参数,只会替换对应的两个参数。
在这里插入图片描述
在这里插入图片描述
》》集合初始化器 赋值
在这里插入图片描述

》》配置文件
在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Linq;
using Unity;
using System.Configuration;
using System.IO;
using Microsoft.Practices.Unity.Configuration;
using Unity.Resolution;

namespace IOC.Common.IOC_AOP
{
    public class ZenUnityContainerHelper
    {
        private IUnityContainer container;
        public IUnityContainer Container {
            private set {
                container = value;
            }
            get {
                return Container;
            }
        }
        public ZenUnityContainerHelper()
        {
            this.container = new UnityContainer() ;
            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);           
            section.Configure(container, "testContainer");
        }

        public T GetServer<T>()
        {
            return container.Resolve<T>();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="configName">配置文件中指定的name,对于同一个接口,多个实现情况</param>
        /// <returns></returns>
        public T GetServer<T>(string configName)
        {
            return container.Resolve<T>(configName);
        }
        /// <summary>
        /// 返回构结函数带参数
        /// </summary>
        /// <typeparam name="T">依赖对象</typeparam>
        /// <param name="parameterList">参数集合(参数名,参数值)</param>
        /// <returns></returns>
        public T GetServer<T,M>(Dictionary<string, object> parameterList)
        {
            var list = new ParameterOverrides();
            foreach (KeyValuePair<string, object> item in parameterList)
            {
                list.Add(item.Key, item.Value);
            }
            return container.Resolve<T>(list.OnType<M>());
        }
        /// <summary>
        /// 返回构结函数带参数
        /// </summary>
        /// <typeparam name="T">依赖对象</typeparam>
        /// <param name="ConfigName">配置文件中指定的文字(没写会报异常)</param>
        /// <param name="parameterList">参数集合(参数名,参数值)</param>
        /// <returns></returns>
        public T GetServer<T,M>(string configName, Dictionary<string, object> parameterList)
        {
           

            var list = new ParameterOverrides();
            foreach (KeyValuePair<string, object> item in parameterList)
            {
                list.Add(item.Key, item.Value);
               
            }
           
            return container.Resolve<T>(configName,
               list.OnType<M>());

        }
    }
}

》》》 使用封装

 ZenUnityContainerHelper zenContainer= new  ZenUnityContainerHelper();

                var tesla_car = zenContainer.GetServer<ICar>("tesla");
                tesla_car.GetName();               
                var xiaomi_car = zenContainer.GetServer<ICar>("xiaomi" );
                xiaomi_car.GetName();
                Dictionary<string, object> parm = new Dictionary<string, object>();
                parm.Add("age", "一百");
                parm.Add("policy", "遥遥领先");
                var xiaomi_car1 = zenContainer.GetServer<ICar,XiaoMICar>("xiaomi2", parm);
                xiaomi_car1.GetName();
                Console.WriteLine("-----------------------------------");

配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration" />
  
  </configSections>
  
  <unity>
    <typeAliases>
    <typeAlias  alias="IPhone" type="ZEN.Interface.IPhone,ZEN.Interface"></typeAlias >
     <typeAlias  alias="IWork" type="ZEN.Interface.IWork,ZEN.Interface"></typeAlias >
     <typeAlias  alias="IPower" type="ZEN.Interface.IPower,ZEN.Interface"></typeAlias >
    <typeAlias  alias="ICar" type="ZEN.Interface.ICar,ZEN.Interface"></typeAlias >
  <typeAlias  alias="Phone" type="ZEN.Service.Phone,ZEN.Service"></typeAlias >
     <typeAlias  alias="Work" type="ZEN.Service.Work,ZEN.Service"></typeAlias >
     <typeAlias  alias="Power" type="ZEN.Service.Power,ZEN.Service"></typeAlias >
          <typeAlias  alias="Car" type="ZEN.Service.TeslaCar,ZEN.Service"></typeAlias >
      <typeAlias  alias="xiaomi" type="ZEN.Service.XiaoMICar,ZEN.Service"></typeAlias >
  </typeAliases>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration" />
    <containers>
      <container name="testContainer">
         <extension type="Interception"/>
         <register type="IPhone" mapTo="Phone" />
         <register type="IPower" mapTo="Power" />
        <register type="ICar" mapTo="Car" name="tesla" >
            <property name="work" dependencyType="IWork" />
            <property name="phone" dependencyType="IPhone" />
          <method name="InitIphone">
            <param name="_power" type="IPower" />
            <param name="val" type="int" value="33"/>
          </method>
          <policyInjection></policyInjection>
           <interceptor type="InterfaceInterceptor"/>
          <!--<interceptionBehavior type="IOC.Common.IOC_AOP.AOP, IOC.Common"/>-->
        </register>
        <register type="ICar" mapTo="xiaomi" name="xiaomi" >
          <property name="work" dependencyType="IWork" />
          <property name="phone" dependencyType="IPhone" />
          <method name="InitIphone">
            <param name="_power" type="IPower" />
          </method>
          <policyInjection></policyInjection>
          <interceptor type="InterfaceInterceptor"/>
          <!--<interceptionBehavior type="IOC.Common.IOC_AOP.AOP, IOC.Common"/>-->
        </register>
        <register type="ICar" mapTo="xiaomi" name="xiaomi2" >
          <property name="work" dependencyType="IWork" />
          <property name="phone" dependencyType="IPhone" />
          <method name="InitIphone">
            <param name="_power" type="IPower" />
          </method>
          <constructor>
            <param name="age" type="System.String"  />
            <param name="policy" type="System.String" ></param>
          </constructor>
          <policyInjection></policyInjection>
          <interceptor type="InterfaceInterceptor"/>
          <!--<interceptionBehavior type="IOC.Common.IOC_AOP.AOP, IOC.Common"/>-->
        </register>
         <register type="IWork" mapTo="Work" />     
       
       
      </container>
    </containers>
  </unity>
</configuration>

注册类型同时初始化属性并重载调用

public static void ResolveProperty()
{
    //注册对象关系时初始化对象的属性
    container.RegisterType<IXXX, XXX>(
        new InjectionProperty("Policy", "AA"),
        new InjectionProperty("Desc", "描述"));
    Console.WriteLine("-----------默认调用输出-------------");
    Console.WriteLine(container.Resolve<IXXX().Policy);
    Console.WriteLine(container.Resolve<IXXX>().Desc);
    Console.WriteLine("-----------重载后调用输出-------------");
    //以下2种写法效果是一样的,同上面的构造函数参数重载
    //var myXXX = container.Resolve<IXXX>(new PropertyOverride("Policy", "重载后"),
    //    new PropertyOverride("Desc", "重载后的描述"));
    var myXXX = container.Resolve<IXXX>(new PropertyOverrides()
    {
        {"Policy","重载后的"},
        {"Desc","重载后的描述"}
    }.OnType<MyClass>());
 
    Console.WriteLine(myXXX.Policy);
    Console.WriteLine(myXXX.Desc);
}

延迟获取对象

在这里插入图片描述

在这里插入图片描述

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值