.Net Core使用Unity替换原生DI
一、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配置文件节点图。
代码如下:
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的问题。希望大家有问题可以交流共勉。我的测试代码。
.Net Core使用Unity替换原生DI的更多相关文章
- net core天马行空系列:原生DI+AOP实现spring boot注解式编程
写过spring boot之后,那种无处不在的注解让我非常喜欢,比如属性注入@autowire,配置值注入@value,声明式事物@Transactional等,都非常简洁优雅,那么我就在想,这些在n ...
- ASP.NET CORE 学习之原生DI实现批量注册
以前使用Autofac的时候,只需一句AsImplementInterfaces()就可以很轻松实现批量注册功能.而asp.net core内置的DI框架没有现成的批量注册方法,考虑到替换Autofa ...
- ASP.NET Core 3.0 原生DI拓展实现IocManager
昨天.NET Core 3.0 正式发布,创建一个项目运行后发现:原来使用的Autofac在ConfigureServices返回IServiceProvider的这种写法已经不再支持.当然Autof ...
- NET Core开发-获取所有注入(DI)服务
NET Core开发-获取所有注入(DI)服务 获取ASP.NET Core中所有注入(DI)服务,在ASP.NET Core中加入了Dependency Injection依赖注入. 我们在Cont ...
- asp.net core 自定义 Policy 替换 AllowAnonymous 的行为
asp.net core 自定义 Policy 替换 AllowAnonymous 的行为 Intro 最近对我们的服务进行了改造,原本内部服务在内部可以匿名调用,现在增加了限制,通过 identit ...
- C++ 实例练习-替换原生数组
C++ 实例练习-替换原生数组 main.cpp #include <stdio.h> #include "intarray.h" int main(int argc, ...
- 从我做起[原生DI实现模块化和批量注入].Net Core 之一
实现模块化注册 .Net Core实现模块化批量注入 我将新建一个项目从头开始项目名称Sukt.Core. 该项目分层如下: Sukt.Core.API 为前端提供APi接口(里面尽量不存在业务逻辑, ...
- ASP.NET Core中的ActionFilter与DI
一.简介 前几篇文章都是讲ASP.NET Core MVC中的依赖注入(DI)与扩展点的,也许大家都发现在ASP.NET CORE中所有的组件都是通过依赖注入来扩展的,而且面向一组功能就会有一组接口或 ...
- ASP.NET Core开发-获取所有注入(DI)服务
获取ASP.NET Core中所有注入(DI)服务,在ASP.NET Core中加入了Dependency Injection依赖注入. 我们在Controller,或者在ASP.NET Core程序 ...
随机推荐
- jenkins集成caliper"
1.jenkins安装caliper-ci插件(Caliper CI Plugin) 2.编写microbench 最简便的办法就是作为单元测试来跑(这样就不用在jenkins里配置跑microben ...
- Paxos可容错的一致性协议
一致性问题要求多个process对一个值达成一致.基于消息传递的分布式系统中,在不考虑消息篡改等拜占庭错误的情况下,Paxos可以解决在进程退出,消息延迟,丢失,重复等异常发生的环境中对某个值达成一致 ...
- java虚拟机---内存
java虚拟机---内存 Java虚拟机,即JVM,负责运行java程序,每个java程序都运行在一个具体jvm实例上.Java虚拟机的体系架构分为:类装载子系统.运行时数据区.执行引擎.类装载子系统 ...
- RESET MASTER和RESET SLAVE使用场景和说明
[前言]在配置主从的时候经常会用到这两个语句,刚开始的时候还不清楚这两个语句的使用特性和使用场景. 经过测试整理了以下文档,希望能对大家有所帮助: [一]RESET MASTER参数 功能说明:删除所 ...
- python基础_类型_list
#list 类似数组array,以[]扩起来逗号分隔 a = ['a','b','c'] #常用函数 a.append('c') #在list最后增加一个元素,结果是['a','b','c','c'] ...
- Redis 入门之基础
1.安装 redis-windows redis服务端下载 redis客户端下载 redis官网 redis中文网 1.1 Window下安装 redis-server.exe redis.windo ...
- APP分析之海豚睡眠
APP分析之海豚睡眠 产品:海豚睡眠 引文 由于笔者暑假经常晚睡,导致在习惯性失眠.长时间睡眠不足,导致头脑反应迟钝,还整日无精打采,不知所措.一个偶然的机会,在一个燥热的夜晚,眼看又是一个不眠之夜, ...
- 谈谈 C++ 中的右值引用
转自:https://liam0205.me/2016/12/11/rvalue-reference-in-Cpp/ 最近在改 XGBoost 的代码.XGBoost 在代码中使用了很多来自 C++1 ...
- 在jupyter notebook中运行R语言
要想在jupyter notebook中运行R语言其实非常简单,按顺序安装下面扩展包即可: install.package('repr','IRdisplay','evaluate','crayon' ...
- F2eTest程序快捷方式安装到桌面
按照http://f2etest.***.com/install页面上介绍的:安装快捷方式到Windows桌面 (Win7)部分的介绍进行安装. 其中第三步的https连接需要在f2etest的c ...