.Net Core5.0中Autofac依赖注入整合多层,项目中可直接用
一、配置Autofac替换内置DI
1.安装Nuget包:Autofac,Autofac.Extensions.DependencyInjection

2.Program.cs中CreateHostBuilder方法后加上.UseServiceProviderFactory(new AutofacServiceProviderFactory()) ; 告诉程序要使用Autofac。

3.Startup.cs中增加方法ConfigureContainer(ContainerBuilder containerBuilder),实例注入的地方,配置完成。
/// <summary>
/// Autofac注册服务的地方,Autofac会自动调用
/// </summary>
/// <param name="containerBuilder"></param>
public void ConfigureContainer(ContainerBuilder containerBuilder)
{ }
二、构造函数注入
新建IUserService,类UserService,控制器UserController
public interface IUserService
{
public string GetUserName();
}
public class UserService
{
public string GetUserName()
{
return "张三";
}
}
public class UserController : Controller
{
private readonly IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService;
}
public IActionResult Index()
{
string name = _userService.GetUserName();
return Content(name);
}
}
在上面的ConfigureContainer方法把UserService注入进来,默认是瞬时注入
瞬时注入:containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerDependency();;
单例注入:containerBuilder.RegisterType<UserService>().As<IUserService>().SingleInstance();
生命周期注入: containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();
/// <summary>
/// Autofac注册服务的地方,Autofac会自动调用
/// </summary>
/// <param name="containerBuilder"></param>
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
//注册服务
containerBuilder.RegisterType<UserService>().As<IUserService>();
}
访问/User/Index,_userService成功注入,正确获取结果。

三、属性注入
1.把UserController改成属性注入形式,属性注入有一个问题,就是那些属性需要注入?全部注入没必要,父类也有很多属性,要按需注入,给属性增加一个自定义特性标识说明需要注入。
public class UserController : Controller
{
[AutowiredProperty]
private IUserService userService { get; set; }
public IActionResult Index()
{
string name = userService.GetUserName();
return Content(name);
}
}
2.新增自定义特性类AutowiredPropertyAttribute.cs
[AttributeUsage(AttributeTargets.Property)]//为了支持属性注入,只能打到属性上
public class AutowiredPropertyAttribute : Attribute
{
}
3.增加识别特性类AutowiredPropertySelector.cs
/// <summary>
/// IPropertySelector:查看属性上是否标记某一个特性
/// </summary>
public class AutowiredPropertySelector : IPropertySelector
{
public bool InjectProperty(PropertyInfo propertyInfo, object instance)
{
//判断属性的特性是否包含自定义的属性,标记有返回true
return propertyInfo.CustomAttributes.Any(s => s.AttributeType == typeof(AutowiredPropertyAttribute));
}
}
4.因为Controller 默认是由 Mvc 模块管理的,需要把控制器放到IOC容器中,在Startup.cs的ConfigureServices中增加
//让控制器实例由容器创建
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

5.把容器注册到IOC容器,在Startup.cs的ConfigureContainer()增加
//获取所有控制器类型并使用属性注入
Type[] controllersTypeAssembly = typeof(Startup).Assembly.GetExportedTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
containerBuilder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector());

6.验证结果,新增一个接口IOrderService.cs和一个实现类OrderService.cs做对比
public interface IOrderService
{
public string CreateOrder();
} public class OrderService : IOrderService
{
public string CreateOrder()
{
return "下单成功";
}
}
把UserController改成
public class UserController : Controller
{
[AutowiredProperty]
private IUserService userService { get; set; } private IOrderService orderService { get; set; }//不加属性注入标识
public IActionResult Index()
{
string name = userService.GetUserName();
return Content(name);
}
}
注入方法ConfigureContainer()增加
containerBuilder.RegisterType<OrderService>().As<IOrderService>();
运行程序,能看到增加了注入标识的userService注入成功,没加标识的orderService没有注入。

四、批量注入
实际项目中那么多需要注入的类,一个个写注册就不太现实了,需要一个可以批量注入的方法。
1.新建三个空接口IScopeDenpendency.cs,ISingletonDenpendency.cs,ITransitDenpendency.cs
/// <summary>
/// 瞬时注入
/// </summary>
public interface ITransitDenpendency
{
}
/// <summary>
/// 单例注入标识
/// </summary>
public interface ISingletonDenpendency
{
}
/// <summary>
/// 生命周期注入标识
/// </summary>
public interface IScopeDenpendency
{
}
2.把上面要注入的类实现上面的接口

3.新增一个IocManger类
/// <summary>
/// 批量注入扩展
/// </summary>
/// <param name="builder"></param>
/// <param name="assembly"></param>
public static void BatchAutowired(this ContainerBuilder builder, Assembly assembly)
{ var transientType = typeof(ITransitDenpendency); //瞬时注入
var singletonType = typeof(ISingletonDenpendency); //单例注入
var scopeType = typeof(IScopeDenpendency); //单例注入
//瞬时注入
builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(transientType))
.AsSelf()
.AsImplementedInterfaces()
.InstancePerDependency()
.PropertiesAutowired(new AutowiredPropertySelector());
//单例注入
builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(singletonType))
.AsSelf()
.AsImplementedInterfaces()
.SingleInstance()
.PropertiesAutowired(new AutowiredPropertySelector());
//生命周期注入
builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(scopeType))
.AsSelf()
.AsImplementedInterfaces()
.InstancePerLifetimeScope()
.PropertiesAutowired(new AutowiredPropertySelector()); }
4.把注入类ConfigureContainer改成
/// <summary>
/// Autofac注册服务的地方,Autofac会自动调用
/// </summary>
/// <param name="containerBuilder"></param>
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
//获取所有控制器类型并使用属性注入
Type[] controllersTypeAssembly = typeof(Startup).Assembly.GetExportedTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
containerBuilder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector()); //批量自动注入,把需要注入层的程序集传参数
containerBuilder.BatchAutowired(typeof(UserService).Assembly);
containerBuilder.BatchAutowired(typeof(UserRepository).Assembly);
}
5.防止startup.cs代码过多,建一个Module把注入代码搬走,新建AutofacRegisterModule.cs类把ConfigureContainer的代码移过去
public class AutofacRegisterModule:Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
//获取所有控制器类型并使用属性注入
Type[] controllersTypeAssembly = typeof(Startup).Assembly.GetExportedTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
builder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector()); //批量自动注入,把需要注入层的程序集传参数
builder.BatchAutowired(typeof(UserService).Assembly);
builder.BatchAutowired(typeof(UserRepository).Assembly);
}
}
ConfigureContainer的代码变成
/// <summary>
/// Autofac注册服务的地方,Autofac会自动调用
/// </summary>
/// <param name="containerBuilder"></param>
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterModule<AutofacRegisterModule>();
}
五、手动获取实例
手动获取实例的场景有静态帮助类中获取实例,例如redisHelper中获取注入的配置文件中的连接字符串
1.在上面的IocManager类中增加
private static object obj = new object();
private static ILifetimeScope _container { get; set; } public static void InitContainer(ILifetimeScope container)
{
//防止过程中方法被调用_container发生改变
if (_container == null)
{
lock (obj)
{
if (_container == null)
{
_container = container;
}
}
}
}
/// <summary>
/// 手动获取实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T Resolve<T>()
{
return _container.Resolve<T>();
}
2.在Startup.cs的Configure()中增加
//获取Autofac容器上下文信息
IocManager.InitContainer(app.ApplicationServices.GetAutofacRoot());
3.验证,新建一个DataHelper.cs类
public class DataHelper
{
//手动注入UserService
private static IUserService userService = IocManager.Resolve<IUserService>();
public static string GetData()
{
return userService.GetUserName();
}
}
修改UserController用DataHelper的方法成功获取数据

六、其它用法
1.不用接口,直接注入实例
public class UserService :ITransitDenpendency
{
public string GetUserName()
{
return "张三";
}
}

2.一接口多实现
public class UserService :IUserService
{
public string GetUserName()
{
return "张三";
}
} public class User2Service : IUserService
{
public string GetUserName()
{
return "张三2号";
}
}

最后:源码地址:https://github.com/weixiaolong325/.NetCore5.0AutofacDemo
演示项目结构:

.Net Core5.0中Autofac依赖注入整合多层,项目中可直接用的更多相关文章
- ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下
ADO.NET 一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data → DataTable, ...
- ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下
先简单了解一这个几个 名词的意思. 控制反转(IOC) 依赖注入(DI) 并不是某种技术. 而是一种思想.一种面向对象编程法则 什么是控制反转(IOC)? 什么是依赖注入(DI) 可以点击下面链接 ...
- ASP.NET Core 在 JSON 文件中配置依赖注入
前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...
- 转载:ASP.NET Core 在 JSON 文件中配置依赖注入
在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等)时候,都是提供了专有的接口以供使用第三方的依赖注入组件,比如我们常用的会使用 Autofac.Untiy.Stri ...
- ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings,及.NET Core控制台项目中读取AppSettings
问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...
- 从零开始,搭建博客系统MVC5+EF6搭建框架(2),测试添加数据、集成Autofac依赖注入
一.测试仓储层.业务层是否能实现对数据库表的操作 1.创建IsysUserInfoRepository接口来继承IBaseRepository父接口 namespace Wchl.WMBlog.IRe ...
- .NET CORE——Console中使用依赖注入
我们都知道,在 ASP.NET CORE 中通过依赖注入的方式来使用服务十分的简单,而在 Console 中,其实也只是稍微绕了个小弯子而已.不管是内置 DI 组件或者第三方的 DI 组件(如Auto ...
- 如何在.NET Core控制台程序中使用依赖注入
背景介绍 依赖注入(Dependency Injection), 是面向对象编程中的一种设计原则,可以用来减低代码之间的耦合度.在.NET Core MVC中 我们可以在Startup.cs文件的Co ...
- 【干货】利用MVC5+EF6搭建博客系统(二)测试添加数据、集成Autofac依赖注入
PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.测试仓储层.业务层是否能实现对数据库表的操作 1.在52MVCBlog.IRepository程序集下创建IsysUserInf ...
- 在C#中使用依赖注入
依赖注入(Dependency Injection,缩写为DI)是一种实现(Inversion of Control,缩写为IoC)的方法.在编写C#代码时,使用这种方法能够解决一些场景的需求.本系列 ...
随机推荐
- 前沿分享|阿里云数据库资深技术专家 姚奕玮:AnalyticDB MySQL离在线一体化技术揭秘
简介: 本篇内容为2021云栖大会-云原生数据仓库AnalyticDB技术与实践峰会分论坛中,阿里云数据库资深技术专家 姚奕玮关于"AnalyticDB MySQL离在线一体化技术揭秘&q ...
- 7张图揭晓RocketMQ存储设计的精髓
简介: RocketMQ 作为一款基于磁盘存储的中间件,具有无限积压能力,并提供高吞吐.低延迟的服务能力,其最核心的部分必然是它优雅的存储设计. 存储概述 RocketMQ 存储的文件主要包括 Co ...
- DLF +DDI 一站式数据湖构建与分析最佳实践
简介: 本文由阿里云数据湖构建 DLF 团队和 Databricks 数据洞察团队联合撰写,旨在帮助您更深入地了解阿里云数据湖构建(DLF)+Databricks 数据洞察(DDI)构建一站式云上数据 ...
- [ELK] 生产环境中 Elasticsearch 的重要配置项
配置 Elasticsearch https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html 重要的 E ...
- WPF 对接 Vortice 调用 D2D 使用 IWICBitmap 离屏渲染
通过 Vortice 库可以使用非常底层的方式调用到 Direct2D1 进行渲染,本文将使用 D2D 离屏渲染到 IWICBitmap 上,再使用一点点反射黑科技,直接将此 IWICBitmap 对 ...
- linux安装nvm和node
linux安装nvm和node 一.环境 debian10 nodejs 二.安装 2.1 安装NVM 运行以下命令下载并运行 NVM 安装脚本: curl https://raw.githubuse ...
- 七、Doris Colocation Join
Colocation Join 是在 Doris 0.9 版本中引入的新功能.旨在为某些 Join 查询提供本地性优化,来减少数据在节点间的传输耗时,加速查询. 1.基本理论 Join 的常见连接类型 ...
- GOLANG-配置nginx反向代理端口 配置域名
目录 配置/etc/nginx/nginx.conf文件 新建/etc/nginx/conf.d/doc.haimait.conf文件 重启nginx服务 解析自己的域名到服务器的公网ip 配置/et ...
- MQTT的使用一
MQTT:物联网消息传递标准 简介 MQTT是用于物联网(IoT)的OASIS标准消息传递协议.它被设计为一种非常轻量级的发布/订阅消息传送,非常适合以较小的代码占用量和最小的网络带宽连接远程设备.如 ...
- three.js 物体要使用光线投射技术,计算是否点击位置与物体有交叉
原生 DOM 还用原生的 DOM 点击事件,要注意开启 pointerEvents CSS3DRenderer 是一个新的渲染器,需要在渲染循环调用并适配 labelRenderer.domEleme ...