配置了对抽象类定义的Autofac委托工厂 [英] Configuring an Autofac delegate factory that's defined on an abstract class

查看:1040
本文介绍了配置了对抽象类定义的Autofac委托工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个C#项目。我试图摆脱,有一个大的开关语句工厂类。



我想配置Autofac能够构造基于参数的依赖关系,由此允许Autofac取厂的地点。



我看了看 DelegateFactories页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<>(...)则可以键入一个登记的值(对象

例如:

  builder.RegisterType< SprocketWidget>()
.Keyed<窗​​口小部件>(WidgetType.Sproket)
.InstancePerD​​ependency();

builder.RegisterType< WhizbangWidget>()
.Keyed<窗​​口小部件>(WidgetType.Whizbang)
.InstancePerD​​ependency();



然后你只需要 IIndex℃的依赖; WidgetType,窗口小部件> 来模仿工厂的行为

 公共类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委托工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆