c# - 使用静态工厂是依赖注入(inject)的有效模式吗?

标签 c# design-patterns dependency-injection

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

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

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,但没有找到与此类似的示例。这是一个有效的、全局接受的模式吗?如果有的话,任何人都可以指出它的任何缺点吗?最后,如果这是一个有效的模式,它有名字吗?

最佳答案

通过使用该属性设置处理器,看起来您是在询问而不是在告诉(http://en.wikipedia.org/wiki/Hollywood_principle)。

我认为您可以通过更“经典”的 DI 方式实现相同的结果:使您的 FilterProcessor 依赖于 IFilterProcessor 的枚举,然后让 IoC 框架执行通过按照惯例注册 IFilterProcessors 为您解析和注入(inject)。

关于c# - 使用静态工厂是依赖注入(inject)的有效模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28321779/

相关文章:

c# - 从响应流中获取 JSON 数据并将其作为字符串读取?

asp.net-mvc - asp.net mvc - 如何强制执行 Controller 层父类(super class)型

java - 在 Java 中,消息生产者应该如何标识自己?

c# - C# .Net 上 MySQL 查询中的特殊字符

c# - 穷人的 C# "lexer"

design-patterns - 如何使用依赖注入(inject)和存储库处理工作单元

c# - ASP.NET Core 中的 new Task 是如何利用依赖注入(inject)的?

design-patterns - 无法结合 Factory/DI

c# - 是否可以仅使用 C# 以编程方式生成 X509 证书?

c# - Ioc 中繁忙的构造函数——它们是代码的味道吗?