配置在抽象类上定义的Autofac委托工厂

时间:2011-09-22 23:09:31

标签: c# delegates factory autofac

我正在开发一个C#项目。我正试图摆脱具有大switch语句的Factory类。

我想配置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未注册。这个委托工厂模式是否不适用于抽象类,如果是,还有另一种方法可以实现吗?

1 个答案:

答案 0 :(得分: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>>();