一、DIP、IOC、DI

  面对对象设计原则可以帮助我们开发出更好的程序,其中有一个依赖倒置原则DIP并由此引申出IOC、DI等概念。就先粗略的了解一下:

* DIP(依赖倒置原则):程序要依赖于抽象接口,不要依赖于具体实现。
* IOC(控制反转):面对对象编程中的一种设计思想。
* DI(依赖注入):组件之间依赖关系由容器在运行期决定。
  总的来说控制反转(IoC)是依赖倒置原则(DIP)的实现思路;依赖注入(DI)又是IoC的一种实现方式。

二、Unity

  Unity容器(Unity)是一个轻量级,可扩展的依赖注入容器。它有助于构建松散耦合的应用程序,并为开发人员提供以下优势:

* 简化对象创建,尤其是对于分层对象结构和依赖项
* 抽象要求; 这允许开发人员在运行时或配置中指定依赖关系,并简化横切关注点的管理
* 通过将组件配置推迟到容器来提高灵活性
* 服务定位能力; 这允许客户端存储或缓存容器
* 实例和类型拦截
* 按惯例注册
三、Unity替换.Net Core原生DI

  关于Unity替换.Net Core原声DI我发现在网上的中文资料基本没有,所以我在Unity的Gitbub上找到了相关的内容,希望可以给大家带来帮助。

  我的是.Net
Core2.2首先需要通过Nuget引入Unity(5.10.2)和Unity.Microsoft.DependencyInjection(5.10.1)这里需要注意版本,我原先Unity引用5.10.3的就运行报错了。

  在Program.cs文件中的CreateWebHostBuilder中添加UseUnityServiceProvider()方法即可替换.Net
Core的原生DI容器,具体如下:
private static IUnityContainer _container; public static void Main(string[]
args) { _container= new UnityContainer(); ConfigureContainer(_container);
CreateWebHostBuilder(args).Build().Run(); }public static IWebHostBuilder
CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args)
.UseUnityServiceProvider(_container) .UseStartup<Startup>(); public static void
ConfigureContainer(IUnityContainer _container) {         //注册对象关系 }
 四、Unity的二种对象关系注册

  1、代码实现

  使用代码主要分为以下两步:

* 创建一个UnityContainer对象。
* 通过UnityContainer对象的RegisterType方法来注册对象与对象之间的关系     IUnityContainer
_container =new UnityContainer();     _container.RegisterType<IPhone,
NubiaPhone>();     _container.RegisterType<IPhone, MiPhone>("Mi");
    _container.RegisterType<IEarPhone, NubiaEarPhone>();
   2、使用配置文件

  
使用配置文件需要引用Unity.Configuration,由于项目庞大的情况下配置文件会变得很多,所以我这里单独拿出来一个文件进行配置。主要分为以下三步:

* 在配置文件中<configSections> 配置节下unity注册。
* 在<configuration> 配置节下添加Unity配置信息。
* 在代码中读取配置信息,并将配置载入到UnityContainer中。
  配置文件如下:
<?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=
"IEarPhone" type="Xu.UnityDemo.Interface.IEarPhone,Xu.UnityDemo" /> <typeAlias
alias="IPhone" type="Xu.UnityDemo.Interface.IPhone,Xu.UnityDemo" /> <typeAlias
alias="NubiaPhone" type="Xu.UnityDemo.Model.NubiaPhone,Xu.UnityDemo" />
<typeAlias alias="MiPhone" type="Xu.UnityDemo.Model.MiPhone,Xu.UnityDemo" />
<typeAlias alias="NubiaEarPhone" type="
Xu.UnityDemo.Model.NubiaEarPhone,Xu.UnityDemo" /> <typeAlias alias="MiEarPhone"
type="Xu.UnityDemo.Model.MiEarPhone,Xu.UnityDemo" /> </typeAliases>
<containers> <container name="IOCcontainer"> <type type="IPhone" mapTo="MiPhone"
name="Mi"></type > <type type="IPhone" mapTo="NubiaPhone"></type > <type type="
IEarPhone" mapTo="NubiaEarPhone"></type > </container> </containers> </unity>
</configuration>

   主要用到两个节点<typeAlias>和<type>。<typeAlias>节点的alias是别名在<type>节点中的type使用,type是“命名空间+对象名,所在程序集名称”。<type>节点的type是“需要映射的对象”mapTo是“映射的目标对象”name是“标识名”在多个类继承同个接口的时候区分使用。其余的节点如图
Unity配置文件节点图 <https://www.cnblogs.com/xwc1996/gallery/image/238437.html>。

  代码如下:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename= Directory.GetCurrentDirectory() + "
/Config/UnityIocConfig.xml"; Configuration configuration =
ConfigurationManager.OpenMappedExeConfiguration(fileMap,
ConfigurationUserLevel.None); UnityConfigurationSection section=
(UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
//获取特定配置节下已命名的配置节<container name="IOCcontainer">下的配置信息
section.Configure(_container,"IOCcontainer");
 五、三种依赖注入

  1、构造函数注入

  构造函数注入是最常用的一种注入方式,如下:
private IPhone _iPhone; private IUnityContainer _container; public
ValuesController(IUnityContainer container, IPhone iPhone) { _container=
container; _iPhone= iPhone; }

   此处我在ValuesController控制器写了一个构造函数,container注入的对象就是在UseUnityServiceProvider()方法中传入的Unity容器对象,我们通过Resolve<T>()方法可以直接使用。iPhone也会被注入NubiaPhone类。当然也可以在别的类中使用如下:
[InjectionConstructor] public NubiaPhone(IEarPhone earPhone) { earPhone.Color
="blue"; }
   当存在多个构造函数的时候,如果有[InjectionConstructor]特性标记则使用此构造函数,否则选择参数最多的那个。

  2、属性注入

  属性注入需要在属性上标记[Dependency]特性,[Dependency]可以指定一个name标识名来指定注入属性的具体对象。
[Dependency("name")] public IEarPhone _iEarPhone { set; get; }
  3.方法注入

  方法注入需要标记[InjectionMethod]特性,使用和构造函数注入相似。
[InjectionMethod] public void Init(IEarPhone iEarPhone) { _iEarPhone =
iEarPhone; }
 六、总结

  很多内容我没有细讲,因为很多东西内容都在园中可以找到,我主要是为了解决Unity替换Net Core原生DI的问题。希望大家有问题可以交流共勉。
我的测试代码 <file:/C:/Users/LINYUE/Desktop/Xu.UnityDemo.rar>。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信