A little late I know but I thought it might be nice to answer the question rather than just quote scripture about how multiple composition roots are evil...
Is this going to register that module twice if my app registers the modules of lib2 and lib3?
Tested with Autofac 4.8.1 and it does:
public class Lib1Module: Module
{
protected override void Load(ContainerBuilder builder)
{
Console.WriteLine("Registering Lib1Module");
// Register Types...
}
}
public class Lib2Module: Module
{
protected override void Load(ContainerBuilder builder)
{
Console.WriteLine("Registering Lib2Module");
builder.RegisterModule<Lib1Module>();
// Register Types...
}
}
public class Lib3Module: Module
{
protected override void Load(ContainerBuilder builder)
{
Console.WriteLine("Registering Lib3Module");
builder.RegisterModule<Lib1Module>();
// Register Types...
}
}
public class Program
{
public void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterModule<Lib2Module>();
builder.RegisterModule<Lib3Module>();
using(var container = builder.Build())
{
// Do Stuff
}
}
}
Outputs:
Registering Lib2Module
Registering Lib1Module
Registering Lib3Module
Registering Lib1Module
You can use the Properties dictionary on an IComponentRegistry/ContainerBuidler (The Module base class internally creates the Container builder it passes to Load with the properties from the IComponentRegistry - source) to work around this and force single registrations for modules, if the Load Method of Lib1Module is changed to:
protected override void Load(ContainerBuilder builder)
{
if (builder.Properties.ContainsKey(GetType().AssemblyQualifiedName))
{
return;
}
builder.Properties.Add(GetType().AssemblyQualifiedName, null);
Console.WriteLine("Registering Lib1Module");
// Register Types...
}
Then the output becomes:
Registering Lib2Module
Registering Lib1Module
Registering Lib3Module
Obviously if Lib2Module/Lib3Module can then become dependencies of other modules similar code would have to be put into their Load method and similarly if any modules used AttachToRegistrationSource and/or AttachToComponentRegistration and wanted to make sure they were run only once they would also need the check. Alternatively (and probably preferably if this is something you need to do a lot) you could create your own class implementing IModule and do the check within Configure.
I have definitely made use of this pattern in production code to keep the amount of repetition down where I have multiple entry points with their own composition roots (e.g a web api, a web app and a recurring console app) that nonetheless share a large chunk of code and I can live with that making me a persona non grata among DI purists.