问题描述
我工作的一个C#项目。我试图摆脱,有一个大的开关
语句工厂类。
我想配置Autofac能够构造基于参数的依赖关系,由此允许Autofac取厂的地点。
我看了看,但我无法弄清楚如何将模式应用到一个抽象类。这里的展示情况的一些代码:
公共枚举WidgetType
{
链轮,
whizbang的
}
公共类SprocketWidget:小工具
{
}
公共类WhizbangWidget:小工具
{
}
公共抽象类的Widget
{
公共委托的Widget厂(widgetType widgetType);
}
公共类WidgetWrangler
{
公共小部件小部件{搞定;私人集; }
公共WidgetWrangler(IComponentContext背景下,WidgetType widgetType)
{
VAR widgetFactory = context.Resolve< Widget.Factory>();
的Widget = widgetFactory(widgetType);
}
}
我想,如果我是说新WidgetWrangler(背景下,WidgetType.Sprocket)
,其小部件
属性将是一个 SpocketWidget
。
当我尝试,我得到的错误,指出 Widget.Factory
未注册。这是否代表工厂模式与抽象类的工作,如果是这样,有另一种方式做到这一点?
什么你正在寻找的是 IIndex<,>
关系类型
如果您注册的子类有。 .Keyed<>(...)
则可以键入一个登记的值(对象
)。 p>
例如:
builder.RegisterType< SprocketWidget>()
.Keyed<窗口小部件>(WidgetType.Sproket)
.InstancePerDependency();
builder.RegisterType< WhizbangWidget>()
.Keyed<窗口小部件>(WidgetType.Whizbang)
.InstancePerDependency();
然后你只需要 IIndex℃的依赖; WidgetType,窗口小部件> 。code>来模仿工厂的行为
公共类SomethingThatUsesWidgets
{
私人只读IIndex< WidgetType,窗口小部件> _widgetFactory;
公共SomethingThatUsesWidgets(IIndex< WidgetType,窗口小部件> widgetFactory)
{
如果(widgetFactory == NULL)抛出ArgumentNullException(widgetFactory);
_widgetFactory = widgetFactory;
}
公共无效DoSomething的()
{
//简单的用法:
小部件小部件= widgetFactory [WidgetType.Whizbang]
//安全使用:
的Widget WIDGET2 = NULL;
如果(widgetFactory.TryGetValue(WidgetType.Sprocket,出WIDGET2))
{
//做的东西
}
}
}
这是一个使用依赖注入的方式,如果你只是想解决工厂:
VAR厂= Container.Resolve< IIndex< WidgetType,窗口小部件>>();
I'm working on a C# project. I'm trying to get rid of a Factory class that has a large switch
statement.
I want to configure Autofac to be able to construct a dependency based on a parameter, thereby allowing Autofac to take the place of the Factory.
I've looked at the DelegateFactories page of the Autofac wiki, but I can't figure out how to apply the pattern to an abstract class. Here's some code showing the situation:
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);
}
}
I'd like it if I were to say new WidgetWrangler(context, WidgetType.Sprocket)
, its Widget
property would be a SpocketWidget
.
When I try this, I get errors stating that Widget.Factory
is not registered. Does this delegate factory pattern not work with abstract classes, and if so, is there another way to accomplish this?
What you're looking for is the IIndex<,>
Relationship Type.
If you register your sub-classes with .Keyed<>(...)
you can key a registration to a value (object
).
For example:
builder.RegisterType<SprocketWidget>()
.Keyed<Widget>(WidgetType.Sproket)
.InstancePerDependency();
builder.RegisterType<WhizbangWidget>()
.Keyed<Widget>(WidgetType.Whizbang)
.InstancePerDependency();
Then you only require a dependency of IIndex<WidgetType,Widget>
to mimic factory behaviour.
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
}
}
}
That's using Dependency Injection approach, if you just want to resolve the factory:
var factory = Container.Resolve<IIndex<WidgetType,Widget>>();
这篇关于配置了对抽象类定义的Autofac委托工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!