ASP.NET Core

ASP.NET Core (previously ASP.NET 5) 改变了以前依赖注入框架集成进ASP.NET的方法. 以前, 每个功能 - MVC, Web API, 等. - 都有它自己的 "依赖解析器(dependency resolver)" 机制并且只是'钩子'钩住的方式有些轻微的区别. ASP.NET Core 通过 Microsoft.Extensions.DependencyInjection 引入了 conforming container 机制, 包含了请求生命周期作用域, 服务注册等等的统一概念.

在 ASP.NET Core 3.0, 引入了 "generic app hosting" 机制, 它可以应用在非 ASP.NET Core 应用中.

Autofac

中文官网:https://autofaccn.readthedocs.io/

入门

  • Nuget引入 Autofac.Extensions.DependencyInjection 包.
  • 在你的 Program.Main 方法内, 将Autofac附加给托管机制.(见下例)
  • 在 Startup 类的 ConfigureServices 方法中用其他库提供的扩展方法注册东西到 IServiceCollection .
  • 在 Startup 类的 ConfigureContainer 方法中直接注册东西到Autofac ContainerBuilder.
  • IServiceProvider 会自动替你创建, 因此你无需做任何事只要 注册东西 即可.

ASP.NET Core 3.0+generic hosting

ASP.NET Core 1.1 - 2.2 使用方法, 你可以调用 WebHostBuilder 的 services.AddAutofac()

在ASP.NET Core 3.0托管方式发生了变化 并且需要不同的集成方式. 你不能在从 ConfigureServices 中返回 IServiceProvider, 也不能再将你的service provider factory加入到service collection.

下面是ASP.NET Core 3+ 和 .NET Core 3+ generic hosting support的集成方式:

Program类

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

Startup类

添加方法 ConfigureContainer

public void ConfigureContainer(ContainerBuilder builder)
{
// 在这里添加服务注册
builder.RegisterType<TopicService>();
}

配置方法命名约定

  • Configure, ConfigureServices, 和 ConfigureContainer 方法都支持基于你应用中 IHostingEnvironment.EnvironmentName 参数的环境特定命名约定. 默认地, 名称为 Configure, ConfigureServices, 和 ConfigureContainer.
  • 如果你想要环境特定设置, 你可以把环境名称放在 Configure 部分后面, 类似 ConfigureDevelopment, ConfigureDevelopmentServices, 和 ConfigureDevelopmentContainer. 如果方法并不以匹配的环境名称显示, 它会回到默认方法.

这意味着你不必使用 Autofac配置在生产环境和开发环境之间切换; 你可以在 Startup 中以编程形式设置.

public void ConfigureDevelopmentContainer(ContainerBuilder builder)
{ }
public void ConfigureProductionContainer(ContainerBuilder builder)
{
// Add things to the ContainerBuilder that are only for the
// production environment.
}

这是ASP.NET Core应用托管的一个功能,它并不是Autofac的行为. ASP.NET Core中的StartupLoader类 是在应用启动时定位调用方法的.

控制器作为服务

默认地, ASP.NET Core 会从容器中解析控制器参数,但不会从中解析控制器 . 这并不是个问题但它意味着:

  • 控制器 的生命周期归框架管理, 而非请求生命周期.
  • 控制器构造方法参数 归请求生命周期管理.
  • 在控制器注册时做的特别的连结 (如属性注入) 将不会生效.

通过在用service collection注册MVC时指定 AddControllersAsServices() , 你可以改变这个行为. 这么做可以在service provider factory调用 builder.Populate(services) 时自动注册控制器类型到 IServiceCollection.

public void ConfigureServices(IServiceCollection services)
{
//services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>()); //或者将Controller加入到Services中,这样写上面的代码就可以省略了
services.AddControllersWithViews().AddControllersAsServices();
}

如果需要在Controller中使用属性注入,需要在ConfigureContainer中添加如下代码

//如果需要在Controller中使用属性注入,需要在ConfigureContainer中添加如下代码
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();

在Controller中使用

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
private readonly TopicService _service;
private readonly IServiceProvider _provider; public TopicService Service { get; set; } public TestController(TopicService service, IServiceProvider provider)
{
_service = service;
_provider = provider;
} [HttpGet("{id}")]
public async Task<Result> GetTopics(int id)
{
// 构造函数注入
return await _service.LoadWithPosts(id);
} [HttpGet("Get/{id}")]
public async Task<Result> GetTopics2(int id)
{
// 属性注入
return await Service.LoadWithPosts(id);
}
}

这样就控制器就可以使用服务了。

多租户支持

由于ASP.NET Core想要早早地生成请求生命周期作用域, 这会导致多租户支持无法达到开箱即用的效果. 有时用于识别租户身份的 IHttpContextAccessor , 也无法被及时地构建. Autofac.AspNetCore.Multitenant 包就是用于解决这个问题的.

为了启用多租户支持:

  • 添加 Autofac.AspNetCore.Multitenant NuGet包引用.
  • 在 Program.Main 中构建web host时调用 UseServiceProviderFactory 和 AutofacMultitenantServiceProviderFactory. 提供一个配置租户的回调.
  • 在 Startup.ConfigureServices 和 Startup.ConfigureContainer 中注册进入 根容器(root container) 的东西(那些非租户特有的).
  • 在回调中 (如Startup.ConfigureMultitenantContainer) 构建你的多租户容器.

下面是Autofac给的一个示例:

public class Program
{
public static async Task Main(string[] args)
{
var host = Host
.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacMultitenantServiceProviderFactory(Startup.ConfigureMultitenantContainer))
.ConfigureWebHostDefaults(webHostBuilder => webHostBuilder.UseStartup<Startup>())
.Build(); await host.RunAsync();
}
}

... Startup 类似这样:

public class Startup
{
// Omitting extra stuff so you can see the important part...
public void ConfigureServices(IServiceCollection services)
{
// This will all go in the ROOT CONTAINER and is NOT TENANT SPECIFIC.
services.AddMvc(); // This adds the required middleware to the ROOT CONTAINER and is required for multitenancy to work.
services.AddAutofacMultitenantRequestServices();
} public void ConfigureContainer(ContainerBuilder builder)
{
// This will all go in the ROOT CONTAINER and is NOT TENANT SPECIFIC.
builder.RegisterType<Dependency>().As<IDependency>();
} public static MultitenantContainer ConfigureMultitenantContainer(IContainer container)
{
// This is the MULTITENANT PART. Set up your tenant-specific stuff here.
var strategy = new MyTenantIdentificationStrategy();
var mtc = new MultitenantContainer(strategy, container);
mtc.ConfigureTenant("a", cb => cb.RegisterType<TenantDependency>().As<IDependency>());
return mtc;
}
}

Asp.net Core依赖注入(Autofac替换IOC容器)的更多相关文章

  1. # ASP.NET Core依赖注入解读&使用Autofac替代实现

    标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Aut ...

  2. ASP.NET Core依赖注入解读&使用Autofac替代实现【转载】

    ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Autofac实现和自定义实现扩展方法 3.1 安装Autof ...

  3. ASP.NET Core 依赖注入基本用法

    ASP.NET Core 依赖注入 ASP.NET Core从框架层对依赖注入提供支持.也就是说,如果你不了解依赖注入,将很难适应 ASP.NET Core的开发模式.本文将介绍依赖注入的基本概念,并 ...

  4. .net core 依赖注入, autofac 简单使用

    综述 ASP.NET Core  支持依赖注入, 也推荐使用依赖注入. 主要作用是用来降低代码之间的耦合度. 什么是控制反转? 控制反转(Inversion of Control,缩写为IoC),是面 ...

  5. ASP.NET Core依赖注入初识与思考

    文章首发地址 一.前言 在上一篇中,我们讲述了什么是控制反转(IoC)以及通过哪些方式实现的.这其中,我们明白了,控制反转(IoC) 是一种软件设计的模式,指导我们设计出更优良,更具有松耦合的程序,而 ...

  6. [译]ASP.NET Core依赖注入深入讨论

    原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...

  7. ASP.NET Core依赖注入最佳实践,提示&技巧

    分享翻译一篇Abp框架作者(Halil İbrahim Kalkan)关于ASP.NET Core依赖注入的博文. 在本文中,我将分享我在ASP.NET Core应用程序中使用依赖注入的经验和建议. ...

  8. 实现BUG自动检测 - ASP.NET Core依赖注入

    我个人比较懒,能自动做的事绝不手动做,最近在用ASP.NET Core写一个项目,过程中会积累一些方便的工具类或框架,分享出来欢迎大家点评. 如果以后有时间的话,我打算写一个系列的[实现BUG自动检测 ...

  9. asp.net core 依赖注入几种常见情况

    先读一篇注入入门 全面理解 ASP.NET Core 依赖注入, 学习一下基本使用 然后学习一招, 不使用接口规范, 直接写功能类, 一般情况下可以用来做单例. 参考https://www.cnblo ...

  10. ASP.NET Core依赖注入——依赖注入最佳实践

    在这篇文章中,我们将深入研究.NET Core和ASP.NET Core MVC中的依赖注入,将介绍几乎所有可能的选项,依赖注入是ASP.Net Core的核心,我将分享在ASP.Net Core应用 ...

随机推荐

  1. Chisel3 - Wire & Reg

    https://mp.weixin.qq.com/s/Y26N5P4XOr5e3uyi5XQY-w   不同于Verilog,Chisel中Wire和Reg并不是数据类型,而是数据容器,作为数据的一个 ...

  2. Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)

    833. 字符串中的查找与替换 对于某些字符串 S,我们将执行一些替换操作,用新的字母组替换原有的字母组(不一定大小相同). 每个替换操作具有 3 个参数:起始索引 i,源字 x 和目标字 y.规则是 ...

  3. Java实现 LeetCode 116 填充每个节点的下一个右侧节点指针

    116. 填充每个节点的下一个右侧节点指针 给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点.二叉树定义如下: struct Node { int val; Node *left ...

  4. Java实现 LeetCode 19删除链表的倒数第N个节点

    19. 删除链表的倒数第N个节点 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当 ...

  5. java实现第四届蓝桥杯埃及分数

    埃及分数 古埃及曾经创造出灿烂的人类文明,他们的分数表示却很令人不解.古埃及喜欢把一个分数分解为类似: 1/a + 1/b 的格式. 这里,a 和 b 必须是不同的两个整数,分子必须为 1 比如,2/ ...

  6. CVE¬-2020-¬0796 漏洞复现(本地提权)

    CVE­-2020-­0796 漏洞复现(本地提权) 0X00漏洞简介 Microsoft Windows和Microsoft Windows Server都是美国微软(Microsoft)公司的产品 ...

  7. 记 Centos zabbix-agent启动失败解决思路

    一. 环境介绍 系统版本:Centos7.4 zabbix-agent 版本:zabbix-agent 3.4.7 二. 问题现象 启动zabbix-agent时启动失败 查看zabbix-agent ...

  8. KVM NAT(网络地址转换模式)

    NAT(网络地址转换模式) 使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网.也就是说,使用NAT模式可以实现在虚拟系统里访问互联网.很显然,如果你只有一 ...

  9. R调用python模块

    明明已经安装了sctransfer,但仍然显示没有该模块 Error in py_module_import(module, convert = convert) : ModuleNotFoundEr ...

  10. js循环练习

    var a=1; while(a>0){ var b=prompt('input number'); if(b>a){ alert('big'); } else if(b<a){ a ...