使用 autofac 代替 asp .net core 默认的 IOC 容器,可实现属性注入。

之前的使用方式不受影响。

源码已开源:

dotnet-campus/Autofac.Annotation: Autofac 扩展,使用 Attribute 进行服务注册与属性注入

更丰富的功能,可以看这里:

yuzd/Autofac.Annotation: Autofac extras library for component registration via attributes 用注解来load autofac 摆脱代码或者xml配置和java的spring的注解注入一样的体验

使用效果示例

向容器中注入服务

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 这一个文件中,代码会变得很难看。

这里的示例中,定义了 BaseServiceRegisterModulePropertiesAutowiredModule ,分别写服务注入的代码,和属性注入的配置代码。

具体实现

下面把后面要说明的四个类都列出来:

    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 的属性注入的更多相关文章

  1. Hangfire&Autofac与ASP.NET CORE注入失败

    Hangfire.Autofac与ASP.NET CORE注入失败 项目里面使用了Hangfire,因为之前没用过吧,遇到了个问题,就是使用了ico容器后,再用Hangfire总是注入不上对象,总是后 ...

  2. ASP.NET Core之依赖注入

    本文翻译自:http://www.tutorialsteacher.com/core/dependency-injection-in-aspnet-core ASP.NET Core支持依赖注入,依赖 ...

  3. 几十行代码实现ASP.NET Core自动依赖注入

    在开发.NET Core web服务的时候,我们习惯使用自带的依赖注入容器来进行注入. 于是就会经常进行一个很频繁的的重复动作:定义一个接口->写实现类->注入 有时候会忘了写Add这一步 ...

  4. Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入

    首先看下Demo2的结构     然后下面一步步将Autofac集成到mvc中. 首先,定义Model Product.cs public class Product { public int Id ...

  5. Asp.net core自定义依赖注入容器,替换自带容器

    依赖注入 在asp.net core程序中,众所周知,依赖注入基本上贯穿了整个项目,以通用的结构来讲解,控制器层(Controller层)依赖业务层(Service层),业务层依赖于仓储层(Repos ...

  6. 【ASP.NET Core】依赖注入高级玩法——如何注入多个服务实现类

    依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来.服务类型的实例转由容器自动管理,无需我们在代码中显式处理. 因此,有了依 ...

  7. asp.net core 系列 4 注入服务的生存期

    一.服务的生存期 在容器中每个注册的服务,根据程序应用需求都可以选择合适的服务生存期,ASP.NET Core 服务有三种生存期配置: (1) Transient:暂时生存期,在每次请求时被创建. 这 ...

  8. asp.net core ioc 依赖注入

    1.生命周期 内置的IOC有三种生命周期: Transient: Transient服务在每次被请求时都会被创建.这种生命周期比较适用于轻量级的无状态服务. Scoped: Scoped生命周期的服务 ...

  9. (2)ASP.NET Core 依赖关系注入(服务)

    1.前言 面向对象设计(OOD)里有一个重要的思想就是依赖倒置原则(DIP),并由该原则牵引出依赖注入(DI).控制反转(IOC)及其容器等老生常谈的概念,初学者很容易被这些概念搞晕(包括我在内),在 ...

随机推荐

  1. 快速搞懂.NET 5/.NET Core应用程序的发布部署

    .NET Framework时代,.NET 应用程序大多直接部署运行在Windows服务器上,当然也可以通过Mono部署运行在Linux上.无论部署exe,还是IIS站点.或是Windows Serv ...

  2. print函数与转义字符

    一.print函数 作用:1.输出数字. print(520) 2.输出字符串.(注意:输出字符串要添加单引号.双引号或三引号,告诉编译器可直接输出,不用分析) print('you are so b ...

  3. HBuilderX All In One

    HBuilderX All In One uni-app https://uniapp.dcloud.io/quickstart-hx 目录结构 一个uni-app工程,默认包含如下目录及文件: $ ...

  4. 如何使用 js 检测页面上全局变量

    如何使用 js 检测页面上全局变量 js 检测页面全局变量脚本 <!DOCTYPE html> <html lang="zh-Hans"> <head ...

  5. 阅文集团 招聘官网 bug

    阅文集团 招聘官网 bug https://join.yuewen.com/ 前端开发 zxx.jpg 张鑫旭 https://qidian.gtimg.com/yuewen/join/css/ima ...

  6. position: absolute; not work

    position: absolute; not work https://stackoverflow.com/questions/11928294/css-position-absolute-with ...

  7. Node.js & LTS

    Node.js & LTS 2020 https://nodejs.org/en/about/releases/ https://raw.githubusercontent.com/nodej ...

  8. Masterboxan INC :个股出现疯涨,投资者需警惕股市泡沫

    随着标普500指数自去年三月以来的暴涨,引发了很多亏损企业股价飙升,同时许多场外投资者盲目跟风,加剧了个股的疯涨.对于此现象,美国万事达资产管理有限公司不得不多次发文提醒投资者:个股出现疯涨,投资者需 ...

  9. BGV上线两天价格超过880美金,下一个YFI已到来!

    BGV自上线以来就备受币圈关注,众多投资者纷纷表示看好BGV.BGV也不负众望,在上线交易所第二天,价格就迎来了暴涨,最高价格为888.88美金,超越了当前以太坊的价值.而这也迎来了币圈众多投资者的一 ...

  10. HQYJ嵌入式学习笔记——C语言复习day1

    第一天:Linux命令 vim操作 第二天:数据类型 运算符 顺序语句第三天:分支语句 循环语句第四天:循环语句 数组第五天:数组第六天:指针第七天:函数 数组与指针第八天:数组指针第九天:递归 第十 ...