2011-10-04 77 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