引入Wukong让你的系统瞬间具备IOC能力
【Github源码】
本文重点要说的是如何通过引入Wukong第三方包让自己的系统能够拥有IOC容器能力,但在具体讲解步骤之前,还是想先简单的介绍一下什么是IOC以及它存在的意义;同时也就能清楚Wukong能为大家解决哪些问题。
一、IOC的用途和意义?
IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”;也有的地方叫做“依赖注入(Dependency Injection)”。
作者的理解IOC是一种基于工厂模式的更高级的对象获取模式;使用该方法,可以将通过new方法创建对象实例的传统方式;替换为通过IOC容器获取对象实例。通过使用IOC容器消除了对象之间的依赖强耦合,实现了对象之间的解耦,使得系统更灵活、更易扩展和维护。
1. 传统的对象获取方式
传统方式必须在项目中显示引入对象所在程序集,同时在需要对象的位置进行显示创建。
Person p = new Person();
p.SetName("张三");
2. IOC容器获取对象方式
而IOC方式,项目只需要显示引入Wukong依赖包,其他需要的对象通过IOC容器进行获取;IOC和各个对象之间完全是弱引用,只会在IOC获取真实对象实例时,才会去相应位置搜索对象定义并创建实例。
dynamic p = Wukong.GetObject("CodeM.Test.Person");
p.SetName("张三");
二、如何引入Wukong依赖
1. Package Manager
Install-Package Wukong -Version 2.0.5
2. .NET CLI
dotnet add package Wukong --version 2.0.5
3. PackageReference
<PackageReference Include="Wukong" Version="2.0.5" />
4. Paket CLI
paket add Wukong --version 2.0.5
三、如何通过Wukong获取对象实例
Wukong提供了两种获取对象的方式,一种是通过类全名称,二是通过配置方式获取。
1. 通过类全名称获取对象实例
Wukong提供了GetObject、GetObject
2. 通过配置方式获取对象实例
通过配置方式更加灵活,系统扩展和维护无需重新编译;同时能够在配置时,为对象属性进行赋值和初始化操作;并且支持配置对象间的依赖引用。
dynamic person = Wukong.GetObjectById("person");
同样,Wukong也为通过配置方式获取对象实例提供了GetObjectById、GetObjectById
四、对象配置文件定义
对象配置文件采用XML格式,支持对象构造方法定义、属性赋值定义;构造参数和属性值类型支持字符串、数值、布尔、日期时间等常用简单类型,以及枚举 、列表、数组、对象引用等复杂类型。
<?xml version="1.0" encoding="utf-8" ?>
<objects>
<object id="father" class="TestExample.Person">
<constructor-arg>"张三"</constructor-arg>
<constructor-arg type="TestExample.Sex">Male</constructor-arg>
</object>
<object id="mother" class="TestExample.Person">
<constructor-arg>"李四"</constructor-arg>
<constructor-arg type="TestExample.Sex">Female</constructor-arg>
</object>
<object id="intParents" class="TestExample.Person">
<constructor-arg ref="father"></constructor-arg>
<constructor-arg ref="mother"></constructor-arg>
</object>
</objects>
更多详细对象配置文件的规则请查看完整Github说明文档
五、通过Wukong获取对象是如何找到对象所在程序集的
前面讲到传统方式使得对象之间依赖性太强,耦合严重;造成这个问题的原因有两个:一是在每个使用对象的位置都需要通过new方法创建实例;二是所有使用到的对象都必须在项目中引用对象所在的包。
那么当我们指定了类的全名称之后,Wukong是如何通过类全名称找到相应的类定义信息并创建实例的呢?Wukong有两种方法实现上述目的:一是像传统方法一样将对象所在的第三方包进行显示引用,但这种方式会导致引用之间的强耦合性;同时对于系统的扩展性不是很友好;因此并不推荐;第二种方式是将第三方包程序集文件放到系统运行目录或其他指定目录即可,该种方式灵活已扩展,且方便系统运行中的热更新,推荐使用该方法。
当使用第二种方法时,如果将第三方包程序集文件放在系统运行目录中,不需要做额外工作,即可通过Wukong正常获取到其中的对象实例;假如因为某种原因需要将程序集文件放到其他指定目录中,此时需要使用Wukong提供的方法AddSearchPath将目录添加到搜索范围内,Wukong才能够正常获取到对象实例。
// 指定Wukong创建对象实例时,在如下路径中搜索对象定义
Wukokng.AddSearchPath("c:\\libs");
六、常用方法说明
1. 添加程序集搜索路径(默认只在应用执行目录中搜索)
定义:
public static void AddSearchPath(string path)
参数:
path: 搜索路径,绝对路径。
返回:
无
2. 根据类全名称获取对象实例
定义:
public static object GetObject(string classFullName, params object[] args)
参数:
classFullName: 类全名称。
args: 对象构造参数数组。
返回:
生成的对象实例。
3. 根据类全名称获取指定类型的对象实例
定义:
public static T GetObject<T>(string classFullName, params object[] args)
参数:
classFullName: 类全名称。
args: 对象构造参数数组。
返回:
指定类型的对象实例。
4. 以单例模式根据类全名称获取对象实例
定义:
public static object GetSingleObject(string classFullName, params object[] args)
参数:
classFullName: 类全名称。
args: 对象构造参数数组。
返回:
生成的对象实例,相同构造参数多次调用返回同一实例。
5. 以单例模式根据类全名称获取指定类型的对象实例
定义:
public static T GetSingleObject<T>(string classFullName, params object[] args)
参数:
classFullName: 类全名称。
args: 对象构造参数数组。
返回:
指定类型的对象实例,相同构造参数多次调用返回同一实例。
6. 根据配置文件Id获取对象实例
定义:
public static object GetObjectById(string objectId)
参数:
objectId: 配置文件中对象Id
返回:
生成的对象实例。
7. 根据配置文件Id获取指定类型对象实例
定义:
public static T GetObjectById<T>(string objectId)
参数:
objectId: 配置文件中对象Id
返回:
指定类型的对象实例。
8. 以单例模式根据配置文件Id获取对象实例
定义:
public static object GetSingleObjectById(string objectId)
参数:
objectId: 配置文件中对象Id
返回:
对象实例,多次调用返回同一实例。
9. 以单例模式根据配置文件Id获取指定类型的对象实例
定义:
public static T GetSingleObjectById<T>(string objectId)
参数:
objectId: 配置文件中对象Id
返回:
指定类型的对象实例,多次调用返回同一实例。