I'm currently implementing an IoC setup API for internal use (heavily inspired to Autofac's module system).
We have Modules which are configurable via a strongly typed configuration, and
I want a module to be able to require other modules, so I can have a "composition-root"-like main module, that is going to bootstrap the whole application.
public interface IModule<TConfig>
{
TConfig Config { get; }
void Load(ContainerBuilder builder);
void LoadExtraModules(ModuleRegister register);
}
I'm currently designing the ModuleRegisterclass. What I want to be able to do is similar to this:
public class MyModule : ModuleBase<ApplicationConfiguration>
{
public void LoadExtraModules(ModuleRegister register)
{
register.Module<SqlModule>().WithConfig(new SqlConfiguration() { ... });
}
}
public class SqlModule : ModuleBase<SqlConfiguration>
{
public void Load(ContainerBuilder builder)
{
// configuration code.
}
}
What I would like is to have Intellisense somehow suggest that SqlConfiguration is the right configuration type for SqlModule, but I'm failing to do that: I would like to express a type parameter akin to
// ... inside an helper ExtraModulesRegister<TModule> class
public void WithConfig<TConfig>(TConfig configuration)
where TModule : IModule<TConfig>
{
...
}
but obviously I can only express constraints to TConfig, not to TModule.
The only solution I found is to use an Extension Method like the following:
public static void WithConfig<TConfig, TModule>(this ExtraModulesRegister<TModule> register,
TConfig configuration)
where TModule : IModule<TConfig>, new()
{
register.LoadModule<TModule, TConfig>(configuration);
}
so I can express two type constraints, one of which on the already defined generic parameter TModule.
I can (almost) freely change the design of everything.
Any suggestion is appreciated.