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

2.Program.cs中加上
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
//在这里写注入代码 });

二、构造函数注入
新建IUserService,类UserService
public interface IUserService
{
public string GetUserName();
}
public class UserService:IUserService
{
public string GetUserName()
{
return "张三";
}
}
在上面的ConfigureContainer方法把UserService注入进来,默认是瞬时注入
瞬时注入:containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerDependency();;
单例注入:containerBuilder.RegisterType<UserService>().As<IUserService>().SingleInstance();
生命周期注入: containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();

注入试下是否注入成功

调用成功,证明注入成功
三、属性注入
1.把HomeController改成属性注入形式,属性注入有一个问题,就是那些属性需要注入?全部注入没必要,父类也有很多属性,要按需注入,给属性增加一个自定义特性标识说明需要注入。
public class HomeController : Controller
{
[AutowiredProperty]
private IUserService userService { get; set; }
public IActionResult Index()
{
string name = userService.GetUserName();
return View();
}
}
2.新增自定义特性类AutowiredPropertyAttribute.cs
[AttributeUsage(AttributeTargets.Property)]//为了支持属性注入,只能打到属性上
public class AutowiredPropertyAttribute: Attribute
{
}
3.增加识别特性类AutowiredPropertySelector.cs
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容器中,在Program.cs中增加
//让控制器实例由容器创建
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
5.把容器注册到IOC容器,在Program.cs的ConfigureContainer()增加
//获取所有控制器类型并使用属性注入
Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
containerBuilder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector());

验证:

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

3.新增一个IocManager类
/// <summary>
/// Ioc管理
/// </summary>
public static class IocManager
{
/// <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改成

5.防止Program.cs代码过多,建一个Module把注入代码搬走,新建AutofacRegisterModule.cs类把ConfigureContainer的代码移过去
public class AutofacRegisterModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{ //获取所有控制器类型并使用属性注入
Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
builder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector());
//批量自动注入,把需要注入层的程序集传参数,注入Service层的类
builder.BatchAutowired(typeof(UserService).Assembly);
//注入其它层的containerBuilder.BatchAutowired(typeof(其它层的任务一个类).Assembly);
}
}
ConfigureContainer的代码变成

五、手动获取实例
手动获取实例的场景有静态帮助类中获取实例,例如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.在Program.cs中增加

3.验证,新建一个DataHelper.cs类
public class DataHelper
{
//手动注入UserService
private static IUserService userService = IocManager.Resolve<IUserService>();
public static string GetData()
{
return userService.GetUserName();
}
}

成功获取到值,证明从容器中获取成功。
六、其它用法
1.不用接口,直接注入实例
public class UserService :ITransitDenpendency
{
public string GetUserName()
{
return "张三";
}
}

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

.NET7 中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 ...
- 在 xunit 测试项目中使用依赖注入
在 xunit 测试项目中使用依赖注入 Intro 之前写过几篇 xunit 依赖注入的文章,今天这篇文章将结合我在 .NET Conf 上的分享,更加系统的分享一下在测试中的应用案例. 之所以想分享 ...
- 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搭建博客系统(二)测试添加数据、集成Autofac依赖注入
PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.测试仓储层.业务层是否能实现对数据库表的操作 1.在52MVCBlog.IRepository程序集下创建IsysUserInf ...
- 在C#中使用依赖注入
依赖注入(Dependency Injection,缩写为DI)是一种实现(Inversion of Control,缩写为IoC)的方法.在编写C#代码时,使用这种方法能够解决一些场景的需求.本系列 ...
- 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)
相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transient(一) 深入理解net core中的依赖注入.Singleton.Scoped.Transient ...
- asp.net mvc4 简单使用Autofac依赖注入小结
1,首先使用 NuGet下载适当的Autofac版本 文件一,Autofac.3.5.2 文件二,Autofac.Mvc4.3.1.0 1,接口类 public interface IReposito ...
随机推荐
- 【JavaScript快速排序算法】不同版本原理分析
说明 快速排序(QuickSort),又称分区交换排序(partition-exchange sort),简称快排.快排是一种通过基准划分区块,再不断交换左右项的排序方式,其采用了分治法,减少了交换的 ...
- TypeScript 学习总结
TypeScript JavaScript 语言 面向对象编程语言 面向脚本编程 是否支持可选参数 支持 不支持 是否支持静态类型 支持 不支持 是否支持接口 支持 不支持 TS:是JS的超集,即对J ...
- Qt源码阅读(三) 对象树管理
对象树管理 个人经验总结,如有错误或遗漏,欢迎各位大佬指正 @ 目录 对象树管理 设置父对象的作用 设置父对象(setParent) 完整源码 片段分析 对象的删除 夹带私货时间 设置父对象的作用 众 ...
- [灾备]独立磁盘阵列(RAID)技术
本文是对3个月前临时出差前往客户现场,安装交付我司大数据产品时使用的一项硬件级的灾备技术的简要复盘. 1 独立磁盘阵列--RAID:概述 1.1 定义 RAID := Redundant Arrays ...
- JUC(五)Callable
Callable接口 创建线程的几种方式 继承Thread类 实现Runnable接口 通过Callable接口 线程池 使用Runnable接口无法获取到线程返回的结果,因此在jdk1.5后java ...
- Linux内存和磁盘管理(入门)
关于对Linux系统的内存和磁盘的操作 内存和磁盘使用率 查看内存使用率: free.top 查看磁盘使用率: fdisk.df.du free 以KB为单位: $ free total used f ...
- GPT-NER:通过大型语言模型的命名实体识别
讲在前面,chatgpt出来的时候就想过将其利用在信息抽取方面,后续也发现了不少基于这种大语言模型的信息抽取的论文,比如之前收集过的: https://github.com/cocacola-lab/ ...
- vue上传文件(原生方法)
前言: 组件库的文件上传不适合项目,这里我们利用input标签实现文件上传 首先input type=file 标签是这个亚子的,而且样式不能改,我们利用css的方法,将一个定位到这个下面来,然后i ...
- Python 项目:外星人入侵--第三部分
1.项目内容: 在屏幕左上角添加一个外星人,并指定合适的边框,根据第一个外星人的边距和屏幕尺寸计算屏幕上可容纳多少个外星人. 让外星人群向两边和下方移动,直到外星人被全部击落,有外星人撞到飞船,或有外 ...
- 2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实现视频缩放(Scaling)功能。
2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实现视频缩放(Scaling)功能. 答案2023-05-04: 这段代码实现了使用 libswscale 库 ...