暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ASP.NET Core中IOC使用之二(Autofac替换IOC容器)

码农游乐场 2021-09-08
1263

Autofac

Autofac 是一款超赞的.NET IoC 容器 . 它管理类之间的依赖关系, 从而使 应用在规模及复杂性增长的情况下依然可以轻易地修改 . 它的实现方式是将常规的.net类当做组件处理。

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

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 应用中。

入门

  • 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 会从容器中解析控制器参数,但不会从中解析控制器。这并不是个问题但它意味着:

  • 控制器的生命周期归框架管理, 而非请求生命周期。

  • 控制器构造方法参数 归请求生命周期管理。

  • 在控制器注册时做的特别的连结 (如属性注入) 将不会生效。

通过在用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);
}
}

复制

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

具体用法和高级应用,可以参考Autofac官网。

文章转载自码农游乐场,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论