I have a simple basic configuration for Autofac , which uses JSON configuration file :
var config = new ConfigurationBuilder();
config.AddJsonFile("autofac.json",false,true); //notice reloadOnChange
// Register the ConfigurationModule with Autofac.
var module = new ConfigurationModule(config.Build());
var builder = new ContainerBuilder();
builder.RegisterModule(module);
// Set the dependency resolver to be Autofac.
_container = builder.Build();
Here is the JSON :
{
"defaultAssembly": "AutoFacConfigFile",
"components": [
{
"type": "AutoFacConfigFile.ConsoleOutput",
"services": [
{
"type": "AutoFacConfigFile.IOutput"
}
],
"instanceScope": "single-instance",
"injectProperties": true
}
]
}
The ConsoleOutput
writes the exact input string :
public class ConsoleOutput : IOutput
{
public void Write(string content)
{
Console.WriteLine(content);
}
}
However , The ConsoleOutput2
writes the exact input string + "222222222":
public class ConsoleOutput2 : IOutput
{
public void Write(string content)
{
Console.WriteLine(content+"22222222222");
}
}
I want to see that if I change form ConsoleOutput
to ConsoleOutput2
, then I'll see the different output on runtime, that's why I created a loop :
static void Main(string[] args)
{
AutofacExt.InitAutofac();
var writer = AutofacExt.GetFromFac<IOutput>();
Get(writer).Wait();
}
public static async Task Get(IOutput writer)
{
for (int i = 0; i < 100; i++)
{
await Task.Delay(1000);
writer.Write("s");
}
}
However, even if I change the JSON file, when the loop is running, I don't see a new response. I only see the old response :
Question:
Why does changing from ConsoleOutput
to ConsoleOutput2
doesn't reflects the change?
I expect:
"s"
"s"
"s"
-- file changed and saved here --
"s2222222222"
"s2222222222"
"s2222222222"
Autofac doesn't provide or own the configuration builder. It's not "Autofac's reloadOnChange
", it's "Microsoft.Extensions.Configuration's reloadOnChange
."
Autofac will read configuration provided in that format, however, once the container is built, that's it. There is no "tie" or anything between the container contents and the configuration after that.
Containers are effectively immutable. Updating the container is being removed for a variety of reasons and it's these same reasons the container isn't rebuilt on configuration change.
If you need to change the contents on configuration change, you'll need to do that in your application code.
That's easier said than done, especially as the app is running and things may be holding references to objects resolved from the old container. That's actually a big reason this isn't supported. I have no guidance in how to accomplish that and would actively argue against it.
Again, check out this discussion if you're interested in more on why containers are immutable.