Используйте комбинацию TypeFactoryFacility и пользовательского ITypedFactoryComponentSelector. Вот то, что должно работать в вашем случае.
Сначала создайте интерфейс для фабрики:
public interface IMyExporterFactory
{
IMyExporter GetExporter(IMyContext context);
}
Далее, используйте настраиваемый фабричный селектор компонентов, который будет использовать подтип контекста, чтобы определить имя компонента (и изменить регистрацию для именования ваших экспортеров):
public class ExporterComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
if (method.Name == "GetExporter")
{
var context = (IMyContext) arguments[0];
return context.subtype;
}
return base.GetComponentName(method, arguments);
}
}
Вот обновление вашего регистрационного кода Windsor, которое включает TypedFactoryFacility и пользовательский селектор (и он называет ваших экспортеров на основе их подтипа):
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IMyExporterFactory>().AsFactory(c => c.SelectedWith(new ExporterComponentSelector())),
Component.For<IMyExporter>().ImplementedBy<MyExporterJson>().Named("json"),
Component.For<IMyExporter>().ImplementedBy<MyExporterXML>().Named("xml"),
Component.For<IMyContext>().ImplementedBy<MyContext>(),
Component.For<MyService>()
);
Теперь ваш сервис просто получает IMyExporterFactory и использует его для разрешения экспортера:
public class MyService
{
private readonly IMyContext context;
private readonly IMyExporterFactory exporterFactory;
public MyService(IMyContext context, IMyExporterFactory exporterFactory)
{
this.context = context;
this.exporterFactory = exporterFactory;
}
public string Extractdata()
{
var exporter = exporterFactory.GetExporter(context);
return exporter.Export();
}
}
Возможно, вы захотите убедиться, что если компоненты зарегистрированы с именами в нижнем регистре ("xml", "json"), чтобы ваш код всегда использовал имена в нижнем регистре (или использовал context.subtype.ToLower () в вашем ExporterComponentSelector).