Estoy luchando con la forma de organizar mis registros de componentes Autofac en módulos dado que algunos de los módulos tienen dependencias.Módulos Autofac con sus propias dependencias
he implementado una abstracción de datos de configuración (es decir web.config) en una interfaz:
interface IConfigurationProvider
{
T GetSection<T>(string sectionName)
where T : System.Configuration.ConfigurationSection;
}
junto con implementaciones para ASP.NET (WebConfigurationProvider
) y aplicaciones "escritorio" (ExeConfigurationProvider
) .
Algunos de mis módulos autofac continuación, requieren una IConfigurationProvider
como un parámetro de constructor, pero algunos no lo hacen:
class DependentModule : Module
{
public DependentModule(IConfigurationProvider config)
{
_config = config;
}
protected override void Load(ContainerBuilder builder)
{
var configSection = _config.GetSection<CustomConfigSection>("customSection");
builder.RegisterType(configSection.TypeFromConfig);
}
private readonly IConfigurationProvider _config;
}
class IndependentModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(/* other stuff not based on configuration */);
}
}
Dado que el método RegisterType()
extensión no acepta un delegado de registro (Func<IComponentContext, T>
), al igual que lo hace Register()
, no puedo registrar el IConfigurationProvider
por adelantado y luego resolverlo cuando voy a registrar el tipo especificado en la configuración, algo así como:
// this would be nice...
builder.RegisterType(c => c.Resolve<IConfigurationProvider>().GetSection<CustomConfigSection>("sectionName").TypeFromConfig);
Esto significa que Necesito poder registrar los módulos con y sin una dependencia en IConfigurationProvider
.
Es obvio cómo crear una instancia de forma manual cada módulo y registrarlo:
IConfigurationProvider configProvider = ...;
var builder = new ContainerBuilder();
builder.RegisterModule(new DependentModule(configProvider));
builder.RegisterModule(new IndependentModule());
using (var container = builder.Build())
{
...
}
Pero no desea crear una instancia manualmente mis módulos - Quiero escanear montajes de módulos y registrar de forma automática (como se discutió in this question) Así que tengo que usar la reflexión para escanear el ensamblaje para los tipos IModule
, y usar Activator.CreateInstance
para hacer instancias registrables. Pero, ¿cómo sé si pasar o no un IConfigurationProvider
como parámetro de constructor? ¿Y qué sucede cuando otros módulos tienen dependencias adicionales o diferentes?
Tiene que haber una forma más directa de llevar a cabo la tarea básica: registrar un tipo especificado en alguna configuración proporcionada a través de una interfaz, ¿verdad? Entonces, ¿cómo hago eso?
¿Resolviste esto al final? Tengo un caso muy similar, pero mi dependencia está teniendo otra dependencia (quiero obtener config de db, entonces tengo un IConfigProvider dependiente de IRepoConfig) – Learner
@Learner, originalmente implementé algo usando una combinación de Autofac y MEF modelado después de la respuesta de Jim Bolla a continuación, pero fue tremendamente compleja y la retiré antes de que pase demasiado tiempo.Ya no tengo módulos dependientes: dado que mi caso de uso primario fue la selección basada en un "Tipo", desde entonces he tomado el enfoque de * registrar * ** todos ** los candidatos, luego * resolver * basado en el propiedad proveniente de 'ConfigurationSection'. Puedo enviarte código de muestra si lo deseas. –
Ok, gracias. No creo que pueda usar ConfigurationSection/xml en mi caso. – Learner