在Autofac中注册回调并在回调中再次构建容器 [英] Register callback in Autofac and build container again in the callback

查看:575
本文介绍了在Autofac中注册回调并在回调中再次构建容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a dotnet core application. My Startup.cs registers types/implementations in Autofac. One of my registrations needs previous access to a service.

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容器)。

The dilemma is, by the time I have to .RegisterMyInfrastructureService I need to have available the ISettingsReader<string> that was registered just before (Autofac container hasn't been built yet).

我正在阅读有关在构造autofac容器后向回调注册以执行某些操作的信息。所以我可以做这样的事情:

I was reading about registering with callback to execute something after the autofac container has been built. So I could do something like this:

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?
});

但问题是,在我要使用该服务后,不要做启动服务或类似于,但要继续注册需要我现在能够提供的设置的

but the problem is that after I want to use the service not to do something like starting a service or similar but to continue registering things that required the settings I am now able to provide.

我可以简单地再次致电在回调的末尾显示builder.Build(),以便仅重建容器而不会出现任何问题?这似乎有点奇怪,因为已经构建了构建器(这就是执行回调的原因)。

Can I simply call again builder.Build() at the end of my callback so that the container is simply rebuilt without any issue? This seems a bit strange because the builder was already built (that's why the callback was executed).

用autofac处理这一难题的最佳方法是什么?

What's the best way to deal with this dilemma with autofac?

更新1:我读到诸如builder.Update()之类的东西现在已经过时了,因为容器应该是不可变的。这证实了我的怀疑,即建立容器,添加更多注册并再次构建不是一个好习惯。

UPDATE 1: I read that things like builder.Update() are now obsolete because containers should be immutable. Which confirms my suspicion that building a container, adding more registrations and building again is not a good practice.

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

In other words, I can understand that using a register build callback should not be used to register additional things. But then, the question remain: how to deal with these issues?

推荐答案

此讨论问题解释了很多内容,包括解决必须更新容器的方法。我将在这里进行总结,但是在该问题中有大量信息无法尝试全部复制。

This discussion issue explains a lot including ways to work around having to update the container. I'll summarize here, but there is a lot of information in that issue that doesn't make sense to try and replicate all over.


  • 熟悉所有注册组件的方式并传递参数。不要忘记诸如解析参数,可以动态放置参数的模块之类的东西。

  • Lambda注册几乎解决了我们所遇到的所有问题。如果您需要注册提供配置的内容,然后稍后将该配置用作其他注册的一部分,则lambda将会非常庞大​​。

  • 考虑中间接口,例如创建<$ c $由 ISettingsReader< string> 支持的c> IUsernameProvider 。 IUsernameProvider 可以是lambda(解析某些设置,读取特定设置等),然后下游组件可以使用 IUsernameProvider
  • Be familiar with all the ways you can register components and pass parameters. Don't forget about things like resolved parameters, modules that can dynamically put parameters in place, and so on.
  • Lambda registrations solve almost every one of these issues we've seen. If you need to register something that provides configuration and then, later, use that configuration as part of a different registration - lambdas will be huge.
  • Consider intermediate interfaces like creating an IUsernameProvider that is backed by ISettingsReader<string>. The IUsernameProvider could be the lambda (resolve some settings, read a particular one, etc.) and then the downstream components could take an IUsernameProvider directly.

这类问题很难回答,因为其中有 个利用lambda和参数之类的方法来构建/重建/重新构建容器的方法-没有最佳实践,因为它始终取决于您的应用和您的需求。

These sorts of questions are hard to answer because there are a lot of ways to work around having to build/rebuild/re-rebuild the container if you take advantage of things like lambdas and parameters - there's no "best practice" because it always depends on your app and your needs.

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

Me, personally, I will usually start with the lambda approach.

这篇关于在Autofac中注册回调并在回调中再次构建容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆