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

Is using static factories a valid pattern for dependency injection?

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

这是我在 .NET/C# 中的过滤模块的简化示例。假设有一个过滤器处理器组件,它接受 List 个对象,每个对象代表一个过滤条件。然后它的任务是 "translate" 这些到 Expressions 并将其应用于任何 IQueryable。有一些简单的过滤器类型,例如 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);
    }
  }
  ...
}

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

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

使用此模式背后的想法是核心框架不必知道任何关于扩展的信息,类似于某些 "plugin" 系统。

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

现在我的问题是: 我已经阅读了很长时间有关设计模式的内容,尤其是 DI,但没有找到与此类似的示例。这是一个有效的、全球接受的模式吗?如果有的话,任何人都可以指出它的任何缺点吗?最后,如果这是一个有效的模式,它有名字吗?

通过使用 属性.

设置处理器,看起来你是在问而不是在说(http://en.wikipedia.org/wiki/Hollywood_principle

我认为您可以通过更 'classic' DI 的方式实现相同的结果:使您的 FilterProcessor 依赖于 IFilterProcessor 的枚举,然后让 IoC 框架进行解析并通过注册 IFilterProcessors 为您注入。