2011-09-22 87 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