向 Autofac 模块提供 IOptions

Supplying IOptions to Autofac Module

简短版本: 简而言之,我想将 IOptions<TModuleOptions>(或只是 TModuleOptions)注入 autofac 模块,但如果不手动连接选项 class(哪一种打败了这一点)。 这甚至可能吗?如何实现?

较长的版本: 我有一个使用 Autofac 作为 DI 容器的 ASP.NET Core 3.1 项目,以及一个需要一些配置选项的模块。比如名字和 URL。

在启动时我有类似的东西:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ModuleOptions>(Configuration.GetSection(ModuleOptions.ModuleSettings));
    // Stuff remove for brevity
}

public void ConfigureContainer(ContainerBuilder builder)
{
    ModuleOptions options = options; // It would be nice with a way to get this here or have it resolved "automagically".
    builder.RegisterModule(new CustomModule());
}

我尝试了不同的方法,但我真的看不出如何才能以“好”的方式去做。

我得到的壁橱是通过手动进行配置绑定,如下所示: var options = this.Configuration.GetSection("Something").Get<ModuleOptions>();

它有效,但“感觉”它不是“惯用的”.net 核心处理方式。

是否可以像我使用 MS DI 或 RegisterType(context => context.Resolve<IOptions<TModuleOptions>>()) 那样使用 DI 容器实现我想要的效果?

您不能向这样的模块提供 IOptions<T>,因为它是循环依赖。模块执行注册...但是为了解决 IOptions<T> 你需要构建容器,这意味着你不能再注册东西了。

如果您考虑一下,这实际上是正确的行为,因为 技术上 IOptions<T> 最终可能会导致注册一些不同的东西,这会影响 IOptions<T>,这会改变注册的内容,这会影响 IOptions<T>... 是的。

对于bootstrap/app启动代码,不幸的是你真的不能过度DI它。您从配置中获取选项的机制可能已经很好了。

您可以将 DI 东西放入 Startup 的原因是因为 .NET Core 托管机制在内部构建了 两个容器.第一个是超级准系统,其中包含配置、日志记录和托管功能;第二个是您作为 Startup 的一部分构建的,是您的应用程序容器。

无论如何...是的,您将获得的最好的配置阅读,我建议坚持下去。