Ioc 之 Unity的依赖注入

  Unity是微软官方提供的一个Ioc容器,用来实现依赖注入,减少代码之间的耦合程度。使用Unity实现Ioc方式有两种,一种是使用代码方式实现,一种是利用配置文件来实现。

  我们先来看一下代码方式是如何实现的。我们先定义 IPay接口,IOrder接口,再定义WeChatPay,AliPay,Order三个类。

   /// <summary>
    /// 支付接口
    /// </summary>
    public interface IPay
    {
        string Pay();
    }

    public interface IOrder
    {
        string ToPay();
    }
    /// <summary>
    /// 微信支付
    /// </summary>
    public class WeChatPay :IPay
    {
        public string Pay()
        {
            return "微信支付";
        }
    }
    /// <summary>
    /// 支付宝支付
    /// </summary>
    public class AliPay : IPay
    {
        public string Pay()
        {
            return "支付宝支付";
        }
    }
/// <summary>
    /// 订单
    /// </summary>
    public class Order : IOrder
    {
        /// <summary>
        /// 订单支付方式
        /// </summary>
        public IPay _iPay;

        //构造函数注入:可以不写,因为Unity解析时默认会找参数最多的构造函数
        [InjectionConstructor]
        public Order(IPay iPay)
        {
            _iPay = iPay;
        }

        [Dependency]//属性注入
        public IPay _iPayProperty { get; set; }


        [InjectionMethod]//方法注入
        public void PayInit(IPay ipay)
        {
            this._iPay = ipay;
        }

        public string ToPay()
        {
            return this._iPay.Pay();
        }
    }

  接着,我们可以使用代码的方式来使用Unity

 //创建一个Unity空容器
 IUnityContainer container = new UnityContainer();

 //向Unity容器注入WeChatPay
 container.RegisterType<IPay, WeChatPay>();
 //向Unity容器注入AliPay,使用命名注册,解析的时候也需要使用命名获取实例
 container.RegisterType<IPay, AliPay>("alipay"); 

 var obj = container.Resolve<IPay>();
 Console.WriteLine(obj.Pay());
 obj = container.Resolve<IPay>("alipay");
 Console.WriteLine(obj.Pay());

 container.RegisterType<IOrder, Order>();
 //Unity解析的时候会按照:构造函数注入 --> 属性注入  --> 方法注入的顺序进行解析
 var order = container.Resolve<IOrder>();
 Console.WriteLine($"Order.ToPay: {order.ToPay()}");
 
Console.ReadLine();

  运行得到结果

  那么,Unity注入类型的生命周期有哪些呢?

//生命周期
IUnityContainer container = new UnityContainer();

//默认瞬时,每一次都是全新生成
container.RegisterType<IOrder, Order>();
container.RegisterType<IOrder, Order>(new TransientLifetimeManager());

//容器单例
container.RegisterType<IOrder, Order>(new ContainerControlledLifetimeManager());

//线程单例
container.RegisterType<IOrder, Order>(new PerThreadLifetimeManager());
var phone1 = container.Resolve<IPhone>();
var phone2 = container.Resolve<IPhone>();
Console.WriteLine(object.ReferenceEquals(phone1, phone2)); //结果为true

//分级容器单例
container.RegisterType<IOrder, Order>(new HierarchicalLifetimeManager());
IUnityContainer childContainer = container.CreateChildContainer();

//外部可释放单例
container.RegisterType<IOrder, Order>(new ExternallyControlledLifetimeManager());

//循环引用 不推荐
container.RegisterType<IOrder, Order>(new PerResolveLifetimeManager());

   接下来我们再来看下Unity使用配置文件的方式该如何实现依赖注入。我们在项目中新建一个文件夹Config,然后再创建unity.config文件。

<configuration>
  <configSections>
    <!--<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>-->
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
  </configSections>
  <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="IocContainer">
        <!-- 格式:类名,程序集名称 -->
        <register type="IocDemo.IService.IOrder,IocDemo.IService" mapTo="IocDemo.Service.Order, IocDemo.Service"/>
        <register type="IocDemo.IService.IPay,IocDemo.IService" mapTo="IocDemo.Service.AliPay, IocDemo.Service" name="alipay"/>
        <register type="IocDemo.IService.IPay, IocDemo.IService" mapTo="IocDemo.Service.WeChatPay, IocDemo.Service"/>
      </container>
    </containers>
  </unity>
</configuration>

  然后在程序中使用ExeConfigurationFileMap来装载该配置文件

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "Config\\unity.config");//找配置文件的路径
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);

IUnityContainer container = new UnityContainer();
section.Configure(container, "IocContainer");

IOrder order = container.Resolve<IOrder>();
Console.WriteLine(order.ToPay());

IPay aliPay = container.Resolve<IPay>("alipay");
Console.WriteLine(aliPay.Pay());

Console.ReadLine();

  我们也可以在配置文件中指定生命周期,构造函数初始值

  <register type="IocDemo.IService.IOrder,IocDemo.IService" mapTo="IocDemo.Service.Order,IocDemo.Service">
     <lifetime type="transient" />
     <constructor>
         <!--<param name="id" type="System.Int32" value="3" />-->
         <param name="iPay" type="IocDemo.IService.IPay,IocDemo.IService"></param>
     </constructor>
  </register>

 

转载于:https://www.cnblogs.com/jesen1315/p/11043840.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值