Unity实现IOC容器

测试代码链接
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。IoC可以认为是一种全新的设计模式

在面向对象编程中对象之间的耦合关系是无法避免的,也是必要的,这是协同工作的基础。伴随应用规模越来越庞大,对象之间的依赖关系也越来越复杂,对象之间耦合度越来越高。对于应用功能的修改和扩展必然会出现牵一发而动全身的情形。
在这里插入图片描述
耦合关系不仅会出现在对象与对象之间,也会出现在软件系统的各模块之间,以及软件系统和硬件系统之间。如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson 1996年提出了IOC理论,用来实现对象之间的“解耦”,目前这个理论已经被成功地应用到实践当中。

IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。
在这里插入图片描述
由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。

IoC模式,系统中通过引入实现了IoC模式的IoC容器,即可由IoC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分离。其中一个特点就是通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。

IoC是一个很大的概念,可以用不同的方式实现。其主要形式有两种:
依赖查找:容器提供回调接口和上下文条件给组件。EJB和Apache Avalon 都使用这种方式。这样一来,组件就必须使用容器提供的API来查找资源和协作对象,仅有的控制反转只体现在那些回调方法上,容器将调用这些回调方法,从而让应用代码获得相关资源。

依赖注入:组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责的组件的装配,它会把符合依赖关系的对象通过JavaBean属性或者构造函数传递给需要的对象。通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);将依赖关系作为构造函数参数传入的做法称为构造器注入(Constructor Injection)

优缺点:
IoC最大的好处是什么?因为把对象生成放在了XML里定义,所以当我们需要换一个实现子类将会变成很简单(一般这样的对象都是实现于某种接口的),只要修改XML就可以了,这样我们甚至可以实现对象的热插拔(有点像USB接口和SCSI硬盘了)。
IoC最大的缺点是什么?(1)生成一个对象的步骤变复杂了(事实上操作上还是挺简单的),对于不习惯这种方式的人,会觉得有些别扭和不直观。(2)对象生成因为是使用反射编程,在效率上有些损耗。但相对于IoC提高的维护性和灵活性来说,这点损耗是微不足道的,除非某对象的生成对效率要求特别高。(3)缺少IDE重构操作的支持,如果在Eclipse要对类改名,那么你还需要去XML文件里手工去改了,这似乎是所有XML方式的缺憾所在。

在这里插入图片描述
分层架构是软件开发基本的要求,上图简单展示了ioc这种设计手段在分层架构中的扮演的角色(一个对象的容器,对象工厂)。
DIP依赖倒置原则:系统架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖,依赖抽象,而不是细节
贯彻依赖倒置原则,左边能抽象,右边实例化的时候不能直接用抽象,所以需要借助一个第三方

高层本来是依赖低层,但是可以通过工厂(容器)来决定细节,去掉了对低层的依赖
IOC控制反转:把高层对低层的依赖,转移到第三方决定,避免高层对低层的直接依赖(是一种目的)那么程序架构就具备良好扩展性和稳定性
DI依赖注入:是用来实现IOC的一种手段,在构造对象时,可以自动的去初始化,构造函数注入,属性注入,方法注入,不管是构造对象,还是注入对象,这里都是靠反射做到的,有了依赖注入,才可能做到无限层级的依赖抽象,才能做到控制反转。

通过以上文字简单了解了什么是IOC,下面将使用unity实现简单的ioc案例

NuGet包管理器安装Unity version=“5.8.6”

IOC工厂类

using Microsoft.Practices.Unity.Configuration;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Resolution;

namespace IOC.Factory
{
    public class UnityIocHelper
    {
        #region 构造方法
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="containerName">容器名称</param>
        private UnityIocHelper(string containerName)
        {
            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            if (containerName == "IOCcontainer")
            {
                _container = new UnityContainer();
                section.Configure(_container, containerName);
            }
            else if (section.Containers.Count > 1)
            {
                _container = new UnityContainer();
                section.Configure(_container, containerName);
            }
        }
        #endregion

        #region 属性
        /// <summary>
        /// 容器
        /// </summary>
        private readonly IUnityContainer _container;

        /// <summary>
        /// 容器实例
        /// </summary>
        private static readonly UnityIocHelper instance = new UnityIocHelper("IOCcontainer");

        /// <summary>
        /// UnityIoc容器实例
        /// </summary>
        public static UnityIocHelper Instance
        {
            get { return instance; }
        }
        #endregion

        #region 获取对应接口的具体实现类
        /// <summary>
        /// 获取实现类(默认映射)
        /// </summary>
        /// <typeparam name="T">接口类型</typeparam>
        /// <returns>接口</returns>
        public T GetService<T>()
        {
            return _container.Resolve<T>();
        }
        /// <summary>
        /// 获取实现类(默认映射)带参数的
        /// </summary>
        /// <typeparam name="T">接口类型</typeparam>
        /// <param name="parameter">参数</param>
        /// <returns>接口</returns>
        public T GetService<T>(params ParameterOverride[] parameter)
        {
            return _container.Resolve<T>(parameter);
        }
        /// <summary>
        /// 获取实现类(指定映射)带参数的
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="parameter"></param>
        /// <returns>接口</returns>
        public T GetService<T>(string name, params ParameterOverride[] parameter)
        {
            return _container.Resolve<T>(name, parameter);
        }
        #endregion

        #region 判断接口是否被注册了
        /// <summary>
        /// 判断接口是否被实现了
        /// </summary>
        /// <typeparam name="T">接口类型</typeparam>
        /// <returns>bool</returns>
        public bool IsResolve<T>()
        {
            return _container.IsRegistered<T>();
        }
        /// <summary>
        /// 判断接口是否被实现了
        /// </summary>
        /// <typeparam name="T">接口类型</typeparam>
        /// <param name="name">映射名称</param>
        /// <returns></returns>
        public bool IsResolve<T>(string name)
        {
            return _container.IsRegistered<T>(name);
        }
        #endregion
    }
}

接口层
在这里插入图片描述

业务层
在这里插入图片描述
对象的依赖注入只需要标识对应的特性,并在配置文件中添加对应对象的配置,就能实现相互依赖对象的自动构造。
在这里插入图片描述

将要用ioc容器构造的对象由配置文件配置
在这里插入图片描述
使用对象时将不用显示初始化
在这里插入图片描述
在这里插入图片描述

利用ioc工厂配置,对于拥有共同接口的业务扩展,只需要修改配置文件并添加扩展业务的dll文件即可直接使用,不用修改原始代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过AOP对扩展对象IOC.ServiceExt.Phonex增加异常和日志处理
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 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 版权声明:本文为博主原创文章,转载请附上博文链接!
Unity中使用IoC(Inversion of Control,控制反转)容器可以帮助我们更好地管理和组织代码,提高代码的可测试性和可维护性。下面是在C# Unity中使用IoC容器的一些基本知识: 1. 什么是IoC容器IoC容器是一个用于管理对象创建和依赖注入的工具。它实现了控制反转的原则,将对象的创建和依赖关系的解析交给容器来负责,而不是由应用程序手动管理。 2. 如何在Unity中使用IoC容器Unity框架本身就提供了一个轻量级的IoC容器,可以通过安装Unity NuGet包来使用。可以使用容器注册和解析依赖关系,以及进行对象的生命周期管理。 3. 如何注册依赖关系? 可以使用Unity容器的RegisterType方法或RegisterInstance方法来注册依赖关系。RegisterType方法用于注册接口和实现的映射关系,RegisterInstance方法用于注册单例对象。 4. 如何解析依赖关系? 可以使用Unity容器的Resolve方法来解析依赖关系。当需要一个对象时,可以通过容器解析该对象及其依赖的所有对象。 5. 如何进行对象的生命周期管理? Unity容器提供了不同的生命周期管理选项,如Transient、Singleton、PerThread等。可以根据需求选择适合的生命周期管理方式。 6. 如何在Unity中使用IoC容器实现依赖注入? 可以将依赖的接口作为构造函数的参数,在需要使用该接口的地方使用依赖注入。Unity容器会自动解析依赖关系并注入相应的实现对象。 使用IoC容器可以减少手动管理对象创建和依赖关系的工作量,提高代码的可测试性和可维护性。但需要注意合理使用IoC容器,避免滥用导致代码复杂性增加。建议深入学习IoC容器的原理和使用方法,以更好地应用于实际项目中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值