2011-08-12 58 views
3

我想使用spring在xml配置中創建一個包含謂詞和func對象的構造函數的對象。 Predicate和Func參數應該指向另一個配置對象的方法。 Spring.net如何實現這一點?我沒能找到文檔中的溶液或暗示...如何在Spring.net中注入Predicate和Func

樣本構造將是:

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

回答

0

我解決了這個問題,使用了一箇中間的「工廠」,它受到了kip的啓發,但在構造函數中保留了需要謂詞和func的對象(上例中的MyClass)。這個解決方案在MyClass的實現之外保留了在春天處理委託的「問題」(與kip的建議相反,但感謝您的回答)。

這是我配置這種情況的方法(使用基於對象的工廠模式在Spring.Net中設置委託)。

的MyDelegator類謂詞/ FUNC一個樣本實現使用 (對象這裏,但可能是別的配件謂詞/ FUNC PARAMS):

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) 
    { 
     ... 
    } 
} 

...那麼你需要一個容器與謂詞和或FUNC對象(可以 在單獨的班,太)...

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> 

現在你可以使用在你的配置這個隨時隨地的對象與謂詞/ FUNC (無需改變需要謂詞/ FUNC類)

<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已經具備了這樣的通用的解決方案......

+0

ouch ..我目前正在尋找類似的東西 - 對使用Func 的基於spring的工廠的一般支持,但是作爲回答,顯示Spring中這些高級場景的唯一優秀解決方案是儘快擺脫Spring,開始使用一些真正的容器(即溫莎):) – Buthrakaur

+0

@Buthrakaur希望Spring.net將在未來支持這個......也許還有另一種方法來解決這個問題,在spring.net中使用表達式 – Beachwalker

2

我會說你要提取謂詞和函數,並把它們的背後接口。然後你可以在你的構造函數中使用這個接口。如果大多數情況下使用構造函數注入,則將依賴項指定爲接口或類型。在你的例子中的構造函數使用2個實例變量(在這種情況下指向一個方法)。

您可以創建這樣一個接口:

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

而使用這個接口作爲構造PARAM,它給你,你可以有你的「其他配置對象實現這個接口完全相同的結果。

+0

這似乎是一個選項,但這需要定義一個額外的接口,而不需要接口。此外,這不是一個直接的解決方案,而是增加了更多的複雜性。我只想在構造函數/屬性注入中使用委託/方法(指針)。在代碼中連接這個非常容易,但我不知道這是如何在春季工作的。 – Beachwalker

+1

你不需要什麼?有一個描述依賴關係的接口比僅僅具有一個函數要好得多。您應該使用接口來描述依賴關係以及函數在做什麼,而不僅僅是調用被注入的函數,而您根本就沒有任何知識。該接口使得抽象清晰並告訴你什麼是依賴關係。 – thekip

+0

...以這種方式使用接口不會解決問題。 「如何定義」春天的func參數。這使您可以選擇創建一個具有作爲構造函數參數的對象的類,並且Get * -Methods可以返回一些內容。該代碼將侵入該策略的實施。 – Beachwalker

3

也可以使用內Spring.net的DelegateFactoryObject創建代表(動作,Func鍵,謂語是唯一特別代表):

<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,以便通過工廠方法轉發委託。