I've encountered a strange issue with using Autofac. I have a module whose Load
method looks like this:
builder.RegisterType<Foo>().As<IFoo>();
// ...
AddSomethingToAList(bar);
// ...
Where AddSomethingToAList
does exactly what it says on the tin, adding a resource to a static list. It's used to keep track of some metadata and is kept inside the module because this metadata is directly related to the types being registered for dependency injection.
Then my code has a setup method that looks like:
var builder = new ContainerBuilder();
builder.RegisterModule(myModule);
foreach(var whatever in previouslyAddedToList)
{
doSomething(whatever);
}
So as you can see, we register the module (which I expect to call Load
for that module) and then we do some stuff with the list that got added to when the module was loaded.
Here's the weird part: the list is getting processed before anything is added to it. This is completely unexpected (if the code was synchronous and deterministic). It's as though modules are being processed asynchronously. If instead of builder.RegisterModule(myModule)
I just call myModule.Load(builder)
, then it works entirely as expected.
Nothing in the documentation says that it's async and it seems very out of place. I followed this behavior by placing breakpoints inside the module's Load
method and at the point of processing the list.
So what the heck is RegisterModule
doing that causes this unusual order of execution? Why? How do I stop it?
Everything in Autofac is registered internally as a series of callbacks. When you call RegisterModule, the ContainerBuilder adds a lambda for calling Load on the module.
The ContainerBuilder keeps all of these callbacks until you call Build, when they finally execute. That's why you don't see the Load method called immediately.
There is no way to change this.
Instead, I would strongly recommend only using modules to register dependencies and not have any side effects.