2011-09-22 84 views
4

我正在開發一個C#項目。我試圖擺脫一個有大switch聲明的工廠類。配置在抽象類上定義的Autofac委託工廠

我想配置Autofac能夠基於參數構建依賴關係,從而允許Autofac取代Factory。

我看過DelegateFactories page of the Autofac wiki,但我無法弄清楚如何將模式應用到抽象類。這裏的展示情況的一些代碼:

public enum WidgetType 
{ 
    Sprocket, 
    Whizbang 
} 

public class SprocketWidget : Widget 
{ 
} 

public class WhizbangWidget : Widget 
{ 
} 

public abstract class Widget 
{ 
    public delegate Widget Factory(WidgetType widgetType); 
} 

public class WidgetWrangler 
{ 
    public Widget Widget { get; private set; } 

    public WidgetWrangler(IComponentContext context, WidgetType widgetType) 
    { 
     var widgetFactory = context.Resolve<Widget.Factory>(); 
     Widget = widgetFactory(widgetType); 
    } 
} 

我想,如果我是說new WidgetWrangler(context, WidgetType.Sprocket),其Widget財產將是一個SpocketWidget

當我嘗試此操作時,出現錯誤,指出Widget.Factory未註冊。這是否委託工廠模式不適用於抽象類,如果是這樣,是否有另一種方法來實現這一點?

回答

13

您要找的是IIndex<,>關係類型。

如果您使用.Keyed<>(...)註冊您的子課程,您可以將註冊鍵值爲一個值(object)。

例如:

builder.RegisterType<SprocketWidget>() 
    .Keyed<Widget>(WidgetType.Sproket) 
    .InstancePerDependency(); 

builder.RegisterType<WhizbangWidget>() 
    .Keyed<Widget>(WidgetType.Whizbang) 
    .InstancePerDependency(); 

然後你只需要IIndex<WidgetType,Widget>依賴模仿工廠的行爲。

public class SomethingThatUsesWidgets 
{  
    private readonly IIndex<WidgetType,Widget> _widgetFactory; 
    public SomethingThatUsesWidgets(IIndex<WidgetType,Widget> widgetFactory) 
    { 
     if (widgetFactory == null) throw ArgumentNullException("widgetFactory"); 
     _widgetFactory = widgetFactory; 
    } 

    public void DoSomething() 
    { 
     // Simple usage: 
     Widget widget = widgetFactory[WidgetType.Whizbang]; 

     // Safe Usage: 
     Widget widget2 = null; 
     if(widgetFactory.TryGetValue(WidgetType.Sprocket, out widget2)) 
     { 
      // do stuff 
     } 
    } 
} 

這是使用依賴注入的方法,如果你只是想解決工廠:

var factory = Container.Resolve<IIndex<WidgetType,Widget>>(); 
+0

+1'IIndex'絕對是辦法,考慮到OP指定的枚舉。不過,我會更新您的示例,將工廠存儲在成員變量中並在方法調用中使用它。這使初始化階段與運行階段相分離,大大減少了時序問題。請參閱此處的調制解調器示例:http://code.google.com/p/autofac/wiki/TypedNamedAndKeyedServices –

+0

我已經更新了示例,以便更多地瞭解如何使用此示例。最初的例子只是一個快速查看實現代碼。 – Aren

+0

這個答案是一個很大的幫助,謝謝! – neontapir