原创

asp.net core 3.1 更换依赖注入容器

asp.net core的内置容器有时候并不能满足我们所有的需求,比如微软官方就给出了一些内置容器没有提供的功能。我们如果需要这些高级功能就需要替换内置的依赖注入容器。

- 属性注入
- 基于名称的注入
- 子容器
- 自定义生存期管理
- 对迟缓初始化的 Func<T> 支持
- 基于约定的注册

asp.net core在2.x版本中的方法是修改Startup类中的ConfigureServices方法,把返回值从void改成IServiceProvider并在方法结尾返回新的容器。然而在升级到3.1后,以前替换内置依赖容器的方法是不生效的。我们知道在dotnet core 3.x退出了一个新的通用主机。默认情况下我们新创建项目的启动方法配置了这个通用主机。

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

一个简单的方法可以是用2.x版本中创建主机的方法,就是直接修改这个CreateHostBuilder为CreateWebHostBuilder。代码如下

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

另一个方法可以使用新的通用主机,但是需要容器支持。微软在文档中列出了几个提供支持的容器比如Autofac、Unity。今天是2020年8月31日Castle Windsor对通用主机的支持还停在预览版本。但是我不太熟悉Unity,下面讨论一下Autofac和Castle Windsor的集成方法。

总体来说两个容器的集成方法其实差别不大,在CreateHostBuilder方法用调用use容器的方法。Castle Windsor调用UseWindsorContainerServiceProvider(),Autofac调用UseServiceProviderFactory(new AutofacServiceProviderFactory())。

前面说过不能从ConfigureServices中返回IServiceProvider,但我们还需要一个可以操作容器的入口。在Startup中dotnet core为我们提供了ConfigureContainer方法操作容器,只不过不同容器这个方法的参数不同。

// Castle Windsor使用IWindsorContainer
public void ConfigureContainer (IWindsorContainer container)
{
    container.Install(new MyInstaller());
}

// Autofac使用ContainerBuilder
public void ConfigureContainer(ContainerBuilder builder)
{
    // Register your own things directly with Autofac, like:
    builder.RegisterModule(new MyApplicationModule());
}

最后还有一个需要注意的是Controller。现在Controller的生命周期都不归第三方依赖注入容器管理,它归asp.net core管理,包括你可能需要的属性注入都不会生效。Autofac和Castle Windsor都提供了AddControllersAsServices()方法来改变这个行为。

这就是更换依赖注入容器的一般过程。感觉dotnet core进步还是挺快的,希望未来dotnet core 5不要有太多的重大更改吧。

正文到此结束
该篇文章的评论功能已被站长关闭