使用静态工厂是依赖注入的有效模式吗?

时间:2015-02-04 12:45:28

标签: c# design-patterns dependency-injection

我正在创建一个内部框架,有一点我想提供一个良好的可扩展性,支持一种依赖注入。

以下是我在.NET / C#中过滤模块的简化示例。想象一下,有一个过滤器处理器组件,它接受List个对象,每个对象代表一个过滤条件。然后它的任务是将这些“翻译”为表达式并将其应用于任何IQueryable。有一些简单的fitler类型,例如ColumnFilter,它引用了一个字段名,一个运算符和一些操作数。但是,我想提供一种方法,让消费者使用自定义过滤条件扩展过滤器处理机制。所以我介绍一个界面:

public interface IFilterProcessor {
  Expression Process(FilterContext filter);
}

其中FilterContext包含当前处理的过滤器,根ParameterExpression,根IQueryable的类型等信息,对此示例不重要。

然后在某个时刻,我们可以定义一个新的过滤条件,并为其提供相应的IFilterProcessor,并在那里实现条件的转换。

这就是我的想法,我会将可扩展性点作为静态可注册的工厂,如下所示:

public class FilterProcessor {

  public static readonly Dictionary<Type, Func<IFilterProcessor>> ProcessorFactories = new ... 
    {
       {typeof(ColumnFilter), () => new ColumnFilterProcessor() }
    };

  ...
  public Expression Process(object filterCondition) {
    if (filterCondition == null) return null;
    var factory = ProcessorFactories.GetValueOfDefault(filterCondition.GetType()); // my custom Dictionary extension to avoid exceptions and return null if no key found
    if (factory == null) return null;
    using (var processor = factory()) {
      return processor.Process(filterCondition);
    }
  }
  ...
}

然后在应用程序的入口点,我可以“注册”我的自定义过滤条件处理器,如下所示:

FilterProcess.ProcessorFactories[typeof(MyCustomCondition)] = () => ... get from Ninject for example ...;

使用这种模式背后的想法是核心框架不必知道有关扩展的任何信息,类似于某些“插件”系统。

请注意,这是非常简化的,为清楚起见,省略了很多内容。实际上,例如我的过滤器可以分组,嵌套等等,整个很复杂。

现在我的问题是: 我已经阅读了很长时间的设计模式,特别是DI,但没有找到任何与此类似的例子。这是一个有效且全球接受的模式吗?如果有,有人可以指出任何有关它的反对意见吗?最后,如果这是一个有效的模式,它是否有一个名称?

1 个答案:

答案 0 :(得分:1)

通过使用该属性设置处理器,您似乎在询问(http://en.wikipedia.org/wiki/Hollywood_principle)。

我认为你可以在一个更经典的&#39;中取得同样的结果。 DI方式:让FilterProcessor依赖于IFilterProcessor的枚举,然后让IoC框架通过按惯例注册IFilterProcessors来为您解决和注入。