Register callback in Autofac and build container again in the callback

做~自己de王妃 提交于 2019-12-24 19:28:39

问题


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();

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).

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.

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).

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

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?


回答1:


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.

  • 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.

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.

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



来源:https://stackoverflow.com/questions/53045767/register-callback-in-autofac-and-build-container-again-in-the-callback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!