使用 autofac 实现 asp .net core 的属性注入
使用 autofac 代替 asp .net core 默认的 IOC 容器,可实现属性注入。
之前的使用方式不受影响。
源码已开源:
dotnet-campus/Autofac.Annotation: Autofac 扩展,使用 Attribute 进行服务注册与属性注入
使用效果示例
向容器中注入服务
builder.RegisterType<Counter>().As<ICounter>().InstancePerDependency().AsImplementedInterfaces();
通过属性获取服务
[Autowired] // 这个不是 autofac 自带的,是自己实现的,可以不要。见后面的详述。
private ICounter Counter { get; set; }
准备工作
- nuget 引用
<PackageReference Include="Autofac" Version="5.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="6.0.0" />
- Program.cs 文件
使用autofac的容器工厂替换系统默认的容器

- Startup.cs 文件
在 Startup 服务配置中加入控制器替换规则
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
这句的意思:使用 ServiceBasedControllerActivator 替换 DefaultControllerActivator;Controller 默认是由 Mvc 模块管理的,不在 Ioc 容器中。替换之后,将放在 Ioc 容器中。

在 Startup.cs 添加 public void ConfigureContainer(ContainerBuilder builder) 方法,这个方法会由 autofac 自动调用。
在这个方法中,进行依赖的注入和属性注入的配置。
// ConfigureContainer is where you can register things directly
// with Autofac. This runs after ConfigureServices so the things
// here will override registrations made in ConfigureServices.
// Don't build the container; that gets done for you by the factory.
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule<BaseServiceRegisterModule>();
builder.RegisterModule<PropertiesAutowiredModule>();
}
在 autofac 中,有一个 Module 的概念,可以分模块处理依赖的注入。试想,如果所有业务相关的依赖注入代码,都放在 Startup.cs 这一个文件中,代码会变得很难看。
这里的示例中,定义了 BaseServiceRegisterModule 和 PropertiesAutowiredModule ,分别写服务注入的代码,和属性注入的配置代码。
具体实现
下面把后面要说明的四个类都列出来:
public class BaseServiceRegisterModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
// Register your own things directly with Autofac, like:
builder.RegisterType<Counter>().As<ICounter>().InstancePerDependency().AsImplementedInterfaces();
}
}
public class PropertiesAutowiredModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
// 获取所有控制器类型并使用属性注入
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired(new AutowiredPropertySelector());
}
}
public class AutowiredPropertySelector: IPropertySelector
{
public bool InjectProperty(PropertyInfo propertyInfo, object instance)
{
return propertyInfo.CustomAttributes.Any(it => it.AttributeType == typeof(AutowiredAttribute));
}
}
[AttributeUsage(AttributeTargets.Property)]
public class AutowiredAttribute : Attribute
{
}
BaseServiceRegisterModule 中,向容器中注入了 ICounter 这个服务。
PropertiesAutowiredModule 中,配置了属性注入的操作。这里是关键了。
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired(new AutowiredPropertySelector());
代码还是挺直白的,需要说明
1 可以看到,属性注入并不是 autofac 自动 帮我们完成的,得自己写代码,使用反射的方式,给哪些类进行属性注入。
2 在上面的代码中,只给 ControllerBase 的子类进行了属性注入。
3 这里在 PropertiesAutowired 方法中,加了一个自定义的 AutowiredPropertySelector。
如果没有给 PropertiesAutowired 添加任何方法参数,则 autofac 会对所有属性尝试进行注入,PropertiesAutowired 的方法参数,可以指定属性选择器。
在本文的示例中,选择器的实现是:
public bool InjectProperty(PropertyInfo propertyInfo, object instance)
{
return propertyInfo.CustomAttributes.Any(it => it.AttributeType == typeof(AutowiredAttribute));
}
也就是要求属性必须显式的标明 [Autowired] 这个 Attribute。
我这里这样做的目的是为了让代码看起来更直观,哪些属性是自动注入的,哪些不是,一目了然。
最终效果
在依赖注册上(向容器中添加服务),并没有变化,还是需要手工写代码(在 Startup.cs 或者 Module 中),当然,也可以利用反射,自定义一个 Attribute,然后写一端代码自动将其注入到容器中。
在依赖注入上(从容器中获取服务),这里可以利用属性进行“自动”注入了。使用起来就是这样 ↓,比 asp.net core 中只能是构造函数注入,方便了很多。
[Autowired]
private ICounter Counter { get; set; }
尾巴
对比 spring 框架,asp.net core 的 IOC 在易用性上,感觉还是弱了不少。不过看到这篇博客:ASP.NET Core 奇淫技巧之伪属性注入 - 晓晨Master - 博客园,
觉得属性注入不可滥用的说法还是有道理的,会造成依赖关系的隐藏。
参考文章
主要参考文章:
ASP.NETCore 3.0 Autofac替换及控制器属性注入及全局容器使用 - 情·深 - 博客园
autofac 的官方示例:
autofac/Examples: Example projects that consume and demonstrate Autofac IoC functionality and integration
autofac 文档:
Welcome to Autofac’s documentation! — Autofac 5.2.0 documentation
欢迎来到 Autofac 中文文档! — Autofac 4.0 文档
其它:
ASP.NET Core 奇淫技巧之伪属性注入 - 晓晨Master - 博客园
.net core2.0下Ioc容器Autofac使用 - 焰尾迭 - 博客园
原文链接:
https://www.cnblogs.com/jasongrass/p/13457212.html
使用 autofac 实现 asp .net core 的属性注入的更多相关文章
- Hangfire&Autofac与ASP.NET CORE注入失败
Hangfire.Autofac与ASP.NET CORE注入失败 项目里面使用了Hangfire,因为之前没用过吧,遇到了个问题,就是使用了ico容器后,再用Hangfire总是注入不上对象,总是后 ...
- ASP.NET Core之依赖注入
本文翻译自:http://www.tutorialsteacher.com/core/dependency-injection-in-aspnet-core ASP.NET Core支持依赖注入,依赖 ...
- 几十行代码实现ASP.NET Core自动依赖注入
在开发.NET Core web服务的时候,我们习惯使用自带的依赖注入容器来进行注入. 于是就会经常进行一个很频繁的的重复动作:定义一个接口->写实现类->注入 有时候会忘了写Add这一步 ...
- Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入
首先看下Demo2的结构 然后下面一步步将Autofac集成到mvc中. 首先,定义Model Product.cs public class Product { public int Id ...
- Asp.net core自定义依赖注入容器,替换自带容器
依赖注入 在asp.net core程序中,众所周知,依赖注入基本上贯穿了整个项目,以通用的结构来讲解,控制器层(Controller层)依赖业务层(Service层),业务层依赖于仓储层(Repos ...
- 【ASP.NET Core】依赖注入高级玩法——如何注入多个服务实现类
依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来.服务类型的实例转由容器自动管理,无需我们在代码中显式处理. 因此,有了依 ...
- asp.net core 系列 4 注入服务的生存期
一.服务的生存期 在容器中每个注册的服务,根据程序应用需求都可以选择合适的服务生存期,ASP.NET Core 服务有三种生存期配置: (1) Transient:暂时生存期,在每次请求时被创建. 这 ...
- asp.net core ioc 依赖注入
1.生命周期 内置的IOC有三种生命周期: Transient: Transient服务在每次被请求时都会被创建.这种生命周期比较适用于轻量级的无状态服务. Scoped: Scoped生命周期的服务 ...
- (2)ASP.NET Core 依赖关系注入(服务)
1.前言 面向对象设计(OOD)里有一个重要的思想就是依赖倒置原则(DIP),并由该原则牵引出依赖注入(DI).控制反转(IOC)及其容器等老生常谈的概念,初学者很容易被这些概念搞晕(包括我在内),在 ...
随机推荐
- Codeforces13C–Sequence (区间DP)
题目大意 给定一个含有N个数的序列,要求你对一些数减掉或者加上某个值,使得序列变为非递减的,问你加减的值的总和最少是多少? 题解 一个很显然的结果就是,变化后的每一个值肯定是等于原来序列的某个值,因为 ...
- 秋招C++面试相关总结索引
C++相关 C++ part1 C++ part2 C++ part3 C++ part4 C++ part5 C++ part6 C++ part6.5 C++ part7 C++ part8 C+ ...
- 问题记录 java.lang.NoClassDefFoundError: org/dom4j/DocumentException
客户端调webservice服务产生以下错误 AxisFault faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.genera ...
- Android 如何使用 WebView 加载 HTML 字符串和处理转译字符
Android 如何使用 WebView 加载 HTML 字符串和处理转译字符 css bug 在 WebView 中编译 Web 应用 如果您希望在客户端应用中提供 Web 应用(或只是网页),则可 ...
- 微信公众号 & 付费阅读
微信公众号 & 付费阅读 付费功能 付费阅读 付费功能使用说明 1.付费功能介绍 开通了付费功能的公众号,运营者可以在编辑时对原创文章的部分或全部内容设置收费.对于付费图文,用户未付费前可免费 ...
- vue router & query params
vue router & query params vue router get params from url https://zzk.cnblogs.com/my/s/blogpost-p ...
- 倒计时2天!2021 NGK新加坡区块链峰会与你不见不散!
1月31日14时,NGK将于新加坡召开"2021 NGK新加坡区块链峰会",并将在全球开启同步直播. 据了解,本次峰会将汇聚全球二十多位顶尖区块链专家学者,与NGK灵石技术团队 ...
- NGK Global首尔站:内存是未来获取数字财富的新模式
近日,NGK路演在NGK韩国社区的积极举办下顺利落下帷幕.此次路演在首尔举行,在活动当天,NGK的核心团队成员.行业专家.投资银行精英.生态产业代表和数百名NGK韩国社区粉丝一起参加NGK Globa ...
- IdentityServer4之Authorization Code(授权码)相对更安全
前言 接着授权模式聊,这次说说Authorization Code(授权码)模式,熟悉的微博接入.微信接入.QQ接入都是这种方式(这里说的是oauth2.0的授权码模式),从用户体验上来看,交互方式和 ...
- 生成类库项目时同时生成的pdb文件是什么东东?
英文全称:Program Database File Debug里的PDB是full,保存着调试和项目状态信息.有断言.堆栈检查等代码.可以对程序的调试配置进行增量链接.Release 里的PDB是p ...