配置在抽象类上定义的Autofac委托工厂
问题描述:
我正在开发一个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
未注册。这是否委托工厂模式不适用于抽象类,如果是这样,是否有另一种方法来实现这一点?
答
您要找的是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>>();
+1'IIndex'绝对是办法,考虑到OP指定的枚举。不过,我会更新您的示例,将工厂存储在成员变量中并在方法调用中使用它。这使初始化阶段与运行阶段相分离,大大减少了时序问题。请参阅此处的调制解调器示例:http://code.google.com/p/autofac/wiki/TypedNamedAndKeyedServices –
我已经更新了示例,以便更多地了解如何使用此示例。最初的例子只是一个快速查看实现代码。 – Aren
这个答案是一个很大的帮助,谢谢! – neontapir