在Autofac中注册回调,并在回调中再次构建容器



我有一个dotnet核心应用程序。我的Startup.cs在Autofac中注册类型/实现。我的一个注册需要以前访问服务。

var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterSettingsReaders(); // this makes available a ISettingsReader<string> that I can use to read my appsettings.json
containerBuilder.RegisterMyInfrastructureService(options => 
{
options.Username = "foo" //this should come from appsettings
});
containerBuilder.Populate(services);
var applicationContainer = containerBuilder.Build();

难题是,当我必须使用.RegisterMyInfrastructureService时,我需要使用之前注册的ISettingsReader<string>(Autofac容器尚未构建(。

我读到了关于在autofac容器构建完成后使用回调进行注册以执行某些操作的文章。所以我可以做这样的事情:

builder.RegisterBuildCallback(c =>
{
var stringReader = c.Resolve<ISettingsReader<string>>();
var usernameValue = stringReader.GetValue("Username");
//now I have my username "foo", but I want to continue registering things! Like the following:
containerBuilder.RegisterMyInfrastructureService(options => 
{
options.Username = usernameValue 
});
//now what? again build?
});

但问题是,在我想使用该服务之后,我不想做像启动服务或类似的事情,而是继续注册需要我现在能够提供的设置的东西

我可以简单地在回调结束时再次调用builder.Build(),以便在没有任何问题的情况下简单地重建容器吗?这看起来有点奇怪,因为构建器已经构建好了(这就是执行回调的原因(。

使用autofac解决这种困境的最佳方法是什么?

更新1:我读过类似builder的东西。Update((现在已经过时,因为容器应该是不可变的。这证实了我的怀疑,即建造一个容器、增加更多注册并再次建造并不是一个好的做法。

换句话说,我可以理解,使用寄存器构建回调不应该用于注册其他东西。但是,问题仍然存在:如何处理这些问题?

这个讨论问题解释了很多内容,包括如何解决必须更新容器的问题。我将在这里进行总结,但在这个问题中有很多信息是没有意义的,无法尝试全面复制。

  • 熟悉注册组件和传递参数的所有方法。不要忘记诸如已解析的参数、可以动态放置参数的模块等等
  • Lambda注册几乎解决了我们所看到的每一个问题。如果您需要注册一些提供配置的东西,然后在以后将该配置用作不同注册的一部分,那么lambdas将是巨大的
  • 考虑中间接口,比如创建一个由ISettingsReader<string>支持的IUsernameProviderIUsernameProvider可以是lambda(解析某些设置、读取特定设置等(,然后下游组件可以直接获取IUsernameProvider

这类问题很难回答,因为如果你利用lambdas和参数之类的东西,有很多方法可以解决必须构建/重建/重新重建容器的问题-没有"最佳实践",因为它总是取决于你的应用程序和你的需求。

就我个人而言,我通常会从lambda方法开始。

相关内容

  • 没有找到相关文章

最新更新