一、配置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依赖注入整合多层,项目中可直接用的更多相关文章

  1. 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, ...

  2. ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下

    先简单了解一这个几个 名词的意思. 控制反转(IOC) 依赖注入(DI) 并不是某种技术. 而是一种思想.一种面向对象编程法则 什么是控制反转(IOC)?  什么是依赖注入(DI) 可以点击下面链接 ...

  3. ASP.NET Core 在 JSON 文件中配置依赖注入

    前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...

  4. 转载:ASP.NET Core 在 JSON 文件中配置依赖注入

    在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等)时候,都是提供了专有的接口以供使用第三方的依赖注入组件,比如我们常用的会使用 Autofac.Untiy.Stri ...

  5. ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings,及.NET Core控制台项目中读取AppSettings

    问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...

  6. 从零开始,搭建博客系统MVC5+EF6搭建框架(2),测试添加数据、集成Autofac依赖注入

    一.测试仓储层.业务层是否能实现对数据库表的操作 1.创建IsysUserInfoRepository接口来继承IBaseRepository父接口 namespace Wchl.WMBlog.IRe ...

  7. .NET CORE——Console中使用依赖注入

    我们都知道,在 ASP.NET CORE 中通过依赖注入的方式来使用服务十分的简单,而在 Console 中,其实也只是稍微绕了个小弯子而已.不管是内置 DI 组件或者第三方的 DI 组件(如Auto ...

  8. 如何在.NET Core控制台程序中使用依赖注入

    背景介绍 依赖注入(Dependency Injection), 是面向对象编程中的一种设计原则,可以用来减低代码之间的耦合度.在.NET Core MVC中 我们可以在Startup.cs文件的Co ...

  9. 【干货】利用MVC5+EF6搭建博客系统(二)测试添加数据、集成Autofac依赖注入

    PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.测试仓储层.业务层是否能实现对数据库表的操作 1.在52MVCBlog.IRepository程序集下创建IsysUserInf ...

  10. 在C#中使用依赖注入

    依赖注入(Dependency Injection,缩写为DI)是一种实现(Inversion of Control,缩写为IoC)的方法.在编写C#代码时,使用这种方法能够解决一些场景的需求.本系列 ...

随机推荐

  1. Vite + React 组件开发实践

    简介: 毫不夸张的说,Vite 给前端带来的绝对是一次革命性的变化.或者也可以说是 Vite 背后整合的 esbuild . Browser es modules.HMR.Pre-Bundling 等 ...

  2. [FAQ] mogodb Robo3T 客户端全屏后 怎么退出全屏

    mongodb 的 Robo3T 客户端: 如果是不小心全屏了,不用担心,按 F11 恢复. 如果想要全屏,也是按 F11. Link:https://www.cnblogs.com/farwish/ ...

  3. [Contract] openzeppelin/cli 开发, 部署, 升级智能合约

    Install Dependency $ npm init $ npm install @openzeppelin/cli Setup project $ npx openzeppelin init ...

  4. Windows 官方提供的触屏硬件延迟测量方法

    本文记录微软 Windows 官方在 Windows Hardware Lab Kit 提供的触屏硬件延迟测量方法 Overview of measuring Touch Down Hardware ...

  5. 大模型_2.2:Prompt示例

    1.行业洞察分析 行业洞察分析的方法论:使用麦肯锡工作法可以快速了解一个行业. Step1:通过搜索分析几十个与该行业相关的关键词,覆盖该行业的上下游,以获取全面的信息. Step2:阅读一些行业最新 ...

  6. 圈子社交系统--在线了解前后端,APP小程序H5,三端源码交付-多重玩法,新奇有趣。

    圈子论坛社区系统,含完整的后台PHP系统.功能:小程序授权登陆,H5和APP,手机号登陆,发帖,建圈子.发活动.圈主可置顶推荐帖子,关注.点赞.评论.交流等.可作为圈子贴吧等自媒体. 一款全开源支持免 ...

  7. 使用可视化工具redis-desktop-manager管理查询缓存。

    AnotherRedisDesktopManager https://gitee.com/qishibo/AnotherRedisDesktopManager/releases 下载windows版本 ...

  8. golang cron定时任务简单实现

    目录 星号(*) 斜线(/) 逗号(,) 连字符 (-) 问好 (?) 常用cron举例 使用说明 golang 实现定时服务很简单,只需要简单几步代码便可以完成,不需要配置繁琐的服务器,直接在代码中 ...

  9. DNS(6) -- DNS子域实现

    目录 1. DNS子域 1.1 子域授权环境说明 1.2 子域授权实现 1.2.1 主域DNS服务器配置 1.2.2 子域DNS服务器配置 1.3 DNS转发域 1.3.1 DNS转发域概述 1.3. ...

  10. [4]自定义Lua解析器管理器-------演化脚本V0.7

    [4]自定义Lua解析器管理器-------演化脚本V0.7 使用自定义委托来调用lua脚本中的多返回值函数和长参数类型的函数. 先看代码,依旧是上篇文章中所贴的脚本.新增调用两个函数testFunc ...