给定以下代码:
public interface IMyContext
{
string subtype { get; set; }
}
public class MyContext : IMyContext
{
public string subtype { get; set; }
}
public interface IMyExporter
{
string Export();
}
public class MyExporterXML : IMyExporter
{
public string Export()
{
return "";
}
}
public class MyExporterJson : IMyExporter
{
public string Export()
{
return "";
}
}
public class MyExporterFactory
{
private IMyContext context;
public MyExporterFactory(IMyContext context)
{
this.context = context;
}
public IMyExporter Create()
{
switch (context.subtype)
{
case "JSON" :
return new MyExporterJson();
default:
return new MyExporterXML();
}
}
}
public class MyService
{
private IMyContext context;
private IMyExporter exporter;
public MyService(IMyContext context, IMyExporter exporter)
{
this.context = context;
this.exporter = exporter;
}
public string Extractdata()
{
return exporter.Export();
}
}
[TestClass]
public class UnitTest2
{
[TestMethod]
public void TestMethod1()
{
var container = new WindsorContainer();
container.Register(Component.For<IMyContext>().ImplementedBy<MyContext>());
container.Register(Component.For<MyExporterFactory>());
container.Register(Component.For<MyService>());
container.Register(Component.For<IMyExporter>().UsingFactoryMethod(kernel => kernel.Resolve<MyExporterFactory>().Create()));
var context = container.Resolve<IMyContext>();
var service = container.Resolve<MyService>();
context.subtype = "JSON";
service.Extractdata();
}
}有没有办法在实际使用时解决MyService中的注入导出器??即。在运行上面的代码时,解析的导出器是MyExporterXML,但由于context.subtype = "JSON“设置,我真的希望它是MyExporterJson。但是,在设置子类型之前解析导出器...
我知道Castle::Windsor有一种叫做基于委托的工厂,但我就是想不出如何使用它……
任何帮助都将不胜感激,TIA
Søren
发布于 2011-10-07 20:22:45
使用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")注册的,您可能希望确保代码始终使用小写名称(或者在ExporterComponentSelector中使用context.subtype.ToLower() )。
https://stackoverflow.com/questions/7651390
复制相似问题