【问题标题】:How to inject Predicate and Func in Spring.net如何在 Spring.net 中注入 Predicate 和 Func
【发布时间】:2011-08-12 10:59:51
【问题描述】:

我想使用 spring 创建一个对象,其构造函数包含 xml 配置中的谓词和 func 对象。 Predicate 和 Func 参数应该指向另一个配置对象的方法。使用 Spring.net 怎么可能?我无法在文档中找到解决方案或提示...

一个示例构造函数是:

MyClass(Predicate<TInput> condition, Func<TInput, TOutput> result)

【问题讨论】:

    标签: .net dependency-injection spring.net predicate func


    【解决方案1】:

    也可以使用 Spring.net 中的 DelegateFactoryObject 来创建委托(Action、Func、Predicate 只是特殊的委托):

      <object type="Spring.Objects.Factory.Config.DelegateFactoryObject, Spring.Core">
        <property name="DelegateType" value="System.Action"/>
        <property name="TargetObject" ref="MyTarget" />
        <property name="MethodName" value="MyDelegate" />
      </object>
    

    因此,您不再需要创建像上面提到的 MySpringConfigurationDelegateObjectContainer 这样的构造来通过工厂方法转发委托。

    【讨论】:

      【解决方案2】:

      我会说你必须提取谓词和函数并将它们放在接口后面。然后你可以在你的构造函数中使用这个接口。如果您在大多数情况下使用构造函数注入,则将依赖项指定为接口或类型。您示例中的构造函数使用 2 个实例变量(在本例中指向一个方法)。

      你可以创建一个这样的界面:

      public interface IInterface<TInput, TOutput>
      {
          bool GetOutput(TInput item);
          TOutput GetResult(TInput item);
      }
      

      并将此接口用作构造函数参数,它为您提供完全相同的结果,因为您可以让您的“其他配置对象”实现此接口。

      【讨论】:

      • 这似乎是一个选项,但这需要定义一个不需要接口的额外接口。此外,这不是一个直接的解决方案,而是增加了更多的复杂性。我只想在构造函数/属性注入中使用委托/方法(指针)。在代码中连接它很容易,但我不知道这在春天如何工作。
      • 不需要它是什么意思?拥有一个描述依赖关系的接口比仅仅拥有一个函数要好得多。您应该使用接口来描述依赖项是什么以及函数正在做什么,而不是仅仅调用一个注入的函数并且您根本不知道。接口使抽象清晰,并告诉你依赖是什么。
      • ... 以这种方式使用接口并不能解决问题。 “如何定义”spring中的func参数。这使您可以选择创建一个具有对象作为构造函数参数的类,并且 Get*-Methods 可以返回一些东西。这段代码会侵入策略的执行。
      【解决方案3】:

      我使用受 thekip 建议启发的中间“工厂”解决了该问题,但未触及构造函数中需要谓词和函数的对象(上例中的 MyClass)。此解决方案将在 Spring 中处理代表的“问题”保留在 MyClass 的实现之外(与 thekip 的建议相反,但感谢您的回答)。

      这是我配置这种情况的方法(在 Spring.Net 中设置委托,使用基于对象的工厂模式)。

      MyDelegator 类是谓词/函数使用的示例实现 (此处的对象,但可以是其他任何适合谓词/函数参数的东西):

      public class MyDelegator
      {
          // for the predicate Predicate<TInput> condition, implemented with object
          public bool Condition(object input) 
          {
              ...
          }
      
          //for the Func<TInput, TOutput> result, implemented with object
          public object Evaluate(object input) 
          {
              ...
          }
      }
      

      ... 那么你需要一个带有谓词和或函数的对象的容器(可以 也要分班)...

      public class MySpringConfigurationDelegateObjectContainer
      {
          private readonly Predicate<object> condition;
          private readonly Func<object, object> evaluate;
      
          public MySpringConfigurationDelegateObjectContainer(MyDelegator strategy)
          {
              condition = strategy.Condition;
              evaluate = strategy.Evaluate;
          }
      
          public Predicate<object> GetConditionMethod()
          {
              return condition;
          }
      
          public Func<object, object> GetEvaluateMethod()
          {
              return evaluate;
          }
      }
      

      ...这可以通过这种方式在 Spring.Net xml 中进行配置

        <!-- a simple container class, just has the object with the method to call -->
        <object id="Container" type="MySpringConfigurationDelegateObjectContainer">
          <constructor-arg name="myDelegateObject">
            <!-- put the object with the delegate/func/predicate here -->
            <object type="MyDelegator" />
          </constructor-arg>
        </object>
      

      现在您可以在配置中的任何位置使用它来处理带有谓词/函数的对象 (无需更改需要谓词/函数的类)

        <object id="NeedAPredicateAndFuncInConstructor" type="...">
          ...
          <constructor-arg name="condition">
            <object factory-method="GetConditionMethod" factory-object="Container" />
          </constructor-arg>
          <constructor-arg name="result">
            <object factory-method="GetEvaluateMethod" factory-object="Container" />
          </constructor-arg>
          ...
        </object>
      

      就是这样。有什么建议可以改进这个解决方案吗?也许,Spring.net 已经有一个通用的解决方案......

      【讨论】:

      • ouch.. 我目前正在寻找类似的东西 - 使用 Func 对基于 spring 的工厂的通用支持,但正如您的回答所示,在 Spring 中这些高级场景的唯一好的解决方案是尽快摆脱 Spring 并开始使用一些真正的容器(即 Windsor):)
      • @Buthrakaur 希望 Spring.net 将来能对此提供支持......也许还有另一种方法可以使用 spring.net 中的表达式来解决这个问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多