2011-10-04 109 views
1

考虑下面的代码:延迟/懒解决

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注入的出口在那里的实际使用? IE浏览器。当运行上面的代码时,导出器解析为MyExporterXML,但我真的希望它是MyExporterJson,因为context.subtype =“JSON”设置。但是设置亚型之前出口商得到解决......

我知道城堡温莎::有一种叫做基于委托的工厂,但我根本无法弄清楚如何使用它....

任何帮助将不胜感激,TIA

瑟伦

回答

3

使用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); 
    } 
} 

下面是更新了自己的温莎注册代码,包括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())。

+0

是的,但我真正想要的是有正确的出口商注入我的服务.... – smolesen

+0

为什么它必须注入?为什么你不能使用工厂?说实话,在这种情况下使用工厂更强大一些。如果在调用Extractdata之前“MyService”类更改了context.subtype(出于某种原因),那么您仍然会拥有ctor的导出器。通过使用工厂解析,您可以放心,在调用Extractdata()时,您将始终根据上下文的子类型使用正确的导出器。 – PatrickSteele

+1

它不需要注入,因为编写服务的开发人员对choosine无论是one还是or oter exporter都没有任何知识,所以隐藏这个延迟的依赖关系会非常好,他只需要知道一个,它可以使用。只是认为有一种方法来控制基于延迟依赖性得到解决的问题。 – smolesen