dotNET Core 3.X 使用 Autofac 来增强依赖注入

在上一篇《dotNET Core 3.X 依赖注入》中简单介绍了 dotNET Core 框架本身的依赖注入功能,大部分情况下使用框架的依赖注入功能就可以满足了,在一些特殊场景下,我们就需要引入第三方的注入框架。

为什么要使用 Autofac?

如果您在之前的 dotNET Framwork 时代使用过依赖注入,那么对 Autofac 一定不会陌生,在 dotNET Core 中也可以很方便的使用 Autofac,之所以使用第三方注入框架,是因为能提供更多的功能:

  • 属性注入

  • 批量注入

  • 动态代理的 AOP 功能

在 dotNET Core 中使用 Autofac

在 dotNET Core 2.x 和 3.x 中使用 Autofac 是有区别的,所以下面分别介绍在两个版本中的简单使用。

2.x

1、创建 dotNET Core 2.1 版本的 WebAPI 项目
2、创建 IUserService 接口和 UserService 类:

public interface IUserService
{string GetUserName();
}
public class UserService: IUserService
{public string GetUserName(){return "oec2003";}
}

3、创建 UserController,在构造函数中添加依赖注入:

[Route("api/[controller]/[action]")]
[ApiController]
public class UserController: ControllerBase
{private readonly IUserService _userService;public UserController(IUserService userService){_userService = userService;}public string GetUserName(){return _userService.GetUserName();}
}

4、添加 Autofac.Extensions.DependencyInjection 的 NuGet 引用

5、修改 Startup 类的 ConfigureServices 方法:

public IServiceProvider ConfigureServices(IServiceCollection services)
{services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);//创建 Autofac 容器var containerBuilder = new ContainerBuilder();containerBuilder.Populate(services);//将 UserService 类作为 IUserService 的实现进行注册containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();var container = containerBuilder.Build();//接管内置的容器return new AutofacServiceProvider(container);
}

3.x

1、创建 dotNET Core 3.x 的项目和相关类,参考上面的一到四步

2、修改 Program 类,使用 AutofacServiceProviderFactory 来替代创建服务提供程序的工厂:

public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });

3、修改 Startup 类,在该类中添加 ConfigureContainer 方法,和ConfigureServices 方法一样,框架也是通过命名约束来进行执行的:

public void ConfigureContainer(ContainerBuilder builder)
{builder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();
}

Autofac 的增强功能

下面的所有示例全部在 dotNET Core 3.1 版本中完成。

属性注入

dotNET Core 框架本身的依赖注入只支持构造函数和 FromSerice 的方式,Autofac 可以支持属性的注入。

使用属性注入很简单,在注册类型时调用 PropertiesAutowired 方法即可,具体步骤如下:

1、调整 UserController ,以属性的方式来定义 IUserService:

public class UserController: ControllerBase
{public IUserService UserService { get; set; }public string GetUserName(){return UserService.GetUserName();}
}

2、修改 Startup 类的 ConfigureServices 方法,添加 AddControllersAsServices 方法的调用:

public void ConfigureServices(IServiceCollection services)
{services.AddControllers().AddControllersAsServices();
}

3、修改 Startup 类的 ConfigureContainer :

public void ConfigureContainer(ContainerBuilder builder)
{builder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();var controllerBaseType = typeof(ControllerBase); builder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType).PropertiesAutowired();
}
  • 只要在 Controller 中需要做属性注入的时候,才需要在 ConfigureServices 方法中添加对 AddControllersAsServices 方法的调用;

  • PropertiesAutowired 方法添加在使用属性的注入类型中,比如上面代码是在 Controller 中使用属性,所以 PropertiesAutowired 添加对所有 Controller注册的后面;

  • 如果在 UserService 类以属性的方式对 IDeptService 引用,注册的方式如下:

public void ConfigureContainer(ContainerBuilder builder)
{builder.RegisterType<DeptService>().As<IDeptService>().InstancePerLifetimeScope();builder.RegisterType<UserService>().As<IUserService>().PropertiesAutowired().InstancePerLifetimeScope();
}

批量注册

其实上面的代码中已经涉及到了批量注册,就是对所有的 Controller 进行注册:

var controllerBaseType = typeof(ControllerBase); 
builder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType).PropertiesAutowired();
  • 所有的 Controller 都是继承自基类 ControllerBase,先获取基类的类型;

  • 找到 Program 类所在的程序集中所有实现了 ControllerBase 的类型进行注册。

再来看另一种情况,上面例子中创建 UserServicce 服务,现在再创建 DeptService 服务类:

public interface IDeptService
{string GetDeptName();
}
public class DeptService:IDeptService
{public string GetDeptName(){return "产品部";}
}

修改 Startup 类的 ConfigureContainer 方法来实现批量注册:

public void ConfigureContainer(ContainerBuilder builder)
{builder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope();
}

找到 Program 类所在的程序集中所有以 Service 命名的类型进行注册。更多的情况就根据实际场景举一反三了。

动态代理的 AOP 功能

使用动态代理的功能,需要引用 NuGet 包:Autofac.Extras.DynamicProxy,如下图:

AOP 的概念这里就不在赘述,和 dotNET Core 内置的拦截器(Filter、中间件)的区别是 Autofac 的 AOP 针对具体业务方法而不是 HTTP 请求。

1、创建 UserServiceInterceptor 拦截类,继承自 IInterceptor:

public class UserServiceInterceptor:IInterceptor
{public virtual void Intercept(IInvocation invocation){Console.WriteLine($"{DateTime.Now}: 方法执行前");invocation.Proceed();Console.WriteLine($"{DateTime.Now}: 方法执行后");}
}

2、修改 Startup 类中的 ConfigureContainer 方法,进行 AOP 的注册:

public void ConfigureContainer(ContainerBuilder builder)
{builder.RegisterType<UserServiceInterceptor>();builder.RegisterType<UserService>().As<IUserService>().EnableInterfaceInterceptors().InstancePerLifetimeScope();
}
  • 注册 UserServiceInterceptor 拦截器

  • 注册 UserService 服务的时候调用 EnableInterfaceInterceptors 启用拦截器

3、修改 UserService 类,添加 AOP 特性标记:

[Intercept(typeof(UserServiceInterceptor))]
public class UserService: IUserService
{//public IDeptService DeptService { get; set; }public string GetUserName(){Console.WriteLine($"{DateTime.Now}: 方法执行中");return "oec2003";//return $"oec2003({DeptService.GetDeptName()})";}
}

4、调用结果如下:

总结

本文算是抛砖引入,Autofac 还有许多的功能由于目前没有使用到,也就没有放到本文中,比如子容器等。具体使用 dotNET Core 框架自身的依赖注入,还是使用 Autofac,要看具体的场景了,当然两者也是可以并存的。

示例代码:https://github.com/oec2003/DotNetCoreThreeAPIDemo/tree/master/AutofacNetCore3.1Demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[JS-DOM]DOM概述

DOM&#xff1a; * 概念&#xff1a; Document Object Model 文档对象模型* 将标记语言文档的各个组成部分&#xff0c;封装为对象。可以使用这些对象&#xff0c;对标记语言文档进行CRUD的动态操作* W3C DOM 标准被分为 3 个不同的部分&#xff1a;* 核心 DOM - 针对任何结构…

基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…

2021年度训练联盟热身训练赛第一场 H题On Average They‘re Purple(BFS)

题意&#xff1a; 给你一些联通关系&#xff0c;问Bob先选择一些路径&#xff08;1~n&#xff09;联通&#xff0c;Alice在路径上染色&#xff0c;Bob的目的是选择一些路径使得染色变化最小&#xff0c;对于Alice来说&#xff0c;需要使得在Bob选择的&#xff08;1−n1-n1−n&…

使用请求头认证来测试需要授权的 API 接口

使用请求头认证来测试需要授权的 API 接口Intro有一些需要认证授权的接口在写测试用例的时候一般会先获取一个 token&#xff0c;然后再去调用接口&#xff0c;其实这样做的话很不灵活&#xff0c;一方面是存在着一定的安全性问题&#xff0c;获取 token 可能会有一些用户名密码…

双端队列 BFS + Chamber of Secrets CodeForces - 173B

题意&#xff1a; 一个 nmn\times mnm 的图&#xff0c;现在有一束激光从左上角往右边射出&#xff0c;每遇到 ‘#’&#xff0c;你可以选择光线往四个方向射出&#xff0c;或者什么都不做&#xff0c;问最少需要多少个 ‘#’ 往四个方向射出才能使光线在第 n 行往右边射出。 …

程序员过关斩将--作为一个架构师,我是不是应该有很多职责?

点击上方“蓝字”关注我们领取架构书籍每一个程序员都有一个架构梦。上面其实本质上是一句富有事实哲理的废话&#xff0c;要不然也不会有这么多人关注你的公众号。这些年随着“企业数字化”转型的口号&#xff0c;一大批企业奔跑在转型的路上&#xff0c;希望领先一步对手将企…

Excel使用技巧,补充中。。。

Excel表怎么把名字按字母排序 然后后面的数据也跟着变动 1、首先在excel表格的A列单元格中输入字母&#xff0c;选中需要排序的A列和B列单元格。 2、然后点击工具栏“数据”中的“排序”。 3、在弹出的对话框中的“次序”下拉框中选择“自定义序列”。 4、然后在弹出的对话…

递归函数中局部变量和全局变量

有时候会因为不注意递归函数中局部变量和全局变量&#xff0c;而导致结果和我们期望的不一致&#xff0c;递归中&#xff0c;在递归中的局部变量和全局变量&#xff0c;可以类似的看成函数调用时传递方式的按值传递&#xff08;局部变量&#xff09;和引用传递&#xff08;全局…

基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…

Azure App Service 如何在第一时间用上最新版 .NET Core

点击上方关注“汪宇杰博客” ^_^导语微软会经常对 .NET Core 发布更新&#xff0c;通常为安全补丁。这不&#xff0c;今天早上&#xff0c;.NET Core 3.1.5 更新发布了。然而 Azure App Service 自身的 .NET Core runtime 并不会在第一时间更新&#xff0c;每次都要等几周后微软…

我们是如何做DevOps的?

一、DevOps的理解DevOps的概念理解DevOps 的概念在软件开发行业中逐渐流行起来。越来越多的团队希望实现产品的敏捷开发&#xff0c;DevOps 使一切成为可能。有了 DevOps &#xff0c;团队可以定期发布代码、自动化部署、并将持续集成 / 持续交付作为发布过程的一部分。一句话概…

word文档相关使用

主要是为了记忆&#xff0c;有的时候&#xff0c;之前查阅过&#xff0c;后来使用又忘记了&#xff0c;以后碰了就陆续添加吧&#xff0c;先开一个博文 文章目录插入图片&#xff0c;显示不全的问题&#xff1a;方法一&#xff1a;方法二&#xff1a;方法三&#xff1a;在左侧显…

调试实战 —— dll 加载失败之 Debug Release争锋篇

缘起 最近&#xff0c;项目里遇到一个 dll 加载不上的问题。实际项目比较复杂&#xff0c;但是解决后&#xff0c;又是这么的简单&#xff0c;合情合理。本文是我使用示例工程模拟的&#xff0c;实际项目中另有玄机&#xff0c;但问题的本质是一样的。本文从行文上与 《调试实战…

一文说通Dotnet Core的后台任务

这是一文说通系列的第二篇&#xff0c;里面有些内容会用到第一篇中间件的部分概念。如果需要&#xff0c;可以参看第一篇&#xff1a;一文说通Dotnet Core的中间件一、前言后台任务在一些特殊的应用场合&#xff0c;有相当的需求。比方&#xff0c;我们需要实现一个定时任务、或…

2021年度训练联盟热身训练赛第五场 H题In-place Sorting+贪心构造

题意&#xff1a; 给你n个小于101810^{18}1018的大数&#xff0c;问在可以再不改变序列位置&#xff0c;之改变数值中某数位的‘9’变为‘6’或将‘6’变为‘9’&#xff0c;求的最终序列由小到大&#xff0c;且字典序最小。 题目&#xff1a; 链接&#xff1a;https://ac.n…

用.NET进行客户端Web开发?看这个Bootstrap风格的BlazorUI组件库

点击上方“Dotnet9”添加关注哦Blazor一、前言今天在下班的路上&#xff08;地铁上&#xff09;&#xff0c;站长习惯性的掏出手机&#xff0c;就收到知乎向站长推送的一篇BlazorUI组件库推荐文章&#xff0c;是码云官方的&#xff1a;原文链接[1]&#xff0c;于是我立即打开码…

[JavaWeb-XML]XML约束概述

约束&#xff1a;规定xml文档的书写规则 * 作为框架的使用者(程序员)&#xff1a;1. 能够在xml中引入约束文档2. 能够简单的读懂约束文档* 分类&#xff1a;1. DTD:一种简单的约束技术2. Schema:一种复杂的约束技术

在Asp.NET Core中如何优雅的管理用户机密数据

在Asp.NET Core中如何优雅的管理用户机密数据背景回顾在软件开发过程中&#xff0c;使用配置文件来管理某些对应用程序运行中需要使用的参数是常见的作法。在早期VB/VB.NET时代&#xff0c;经常使用.ini文件来进行配置管理&#xff1b;而在.NET FX开发中&#xff0c;我们则倾向…

基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…

别了,Docker Swarm !你好,K8s !

毫无疑问&#xff0c;Kubernetes已经成为容器编排事实标准。除了已经拥抱Kubernetes的Google、BAT、京东、奇虎360等巨头大厂外&#xff0c;更多的企业也都在向Kubernetes迁移。容器技术大势所趋&#xff0c;是互联网企业目前急需的技术人才之一&#xff0c;已成为运维工程师、…