2012-03-31 10 views
8

सृजन के बिंदु से पारित होने वाले पैरामीटर के साथ कक्षा को पंजीकृत करना संभव है?डेल्फी - spring4d निर्भरता इंजेक्शन ढांचे में एक कन्स्ट्रक्टर के लिए तत्काल से पैरामीटर कैसे पास करें?

मैं जानता हूँ कि यह कुछ इस तरह किया जा सकता है:

GlobalContainer.RegisterType<TUserProcessor>.Implements<IUserUpgrader>. 
AsTransient.DelegateTo(
    function: TUserProcessor 
    begin 
     Result := TUserProcessor.Create(GetCurrentUser); 
    end 
); 

लेकिन वहाँ मानकों निष्पादन संदर्भ में, जहां कंटेनर पंजीकृत हो जाता है और वस्तु मिलता है intantiated जहां नहीं से आबद्ध कर रहे हैं।

ऐसा कुछ उदाहरण के लिए संभव है?

GlobalContainer.Resolve<IMathService>([FCurrentUser]); 

मैं जानता हूँ कि कुछ peoble वकील बहुत ही सरल कंस्ट्रक्टर्स के लिए है, लेकिन कई बार जब एक निर्माता पैरामीटर स्पष्ट रूप से जाने का रास्ता दिखता हैं:

  1. वस्तु का निर्माण काम करने के लिए वस्तु पैरामीटर की जरूरत है, तो संदर्भ संतुष्ट होना चाहिए। पैरामीटर भी वर्ग को देखकर उस बाधा को और अधिक स्पष्ट बनाता है।

  2. आप किसी विधि या प्रॉपर्टी में संदर्भ असाइन कर सकते हैं और यदि आप पहले असाइनमेंट किए बिना ऑब्जेक्ट का उपयोग करने का प्रयास करते हैं तो मुझे अन्य सभी तरीकों में उठाएं और अपवाद दें .. मुझे इस प्रकार के कोड को लिखना पसंद नहीं है, यह बस एक है समय की बर्बादी, केवल कन्स्ट्रक्टर पैरामीटर का उपयोग करें और वहां जांचें। कम कोड, बेहतर आईएमओ।

  3. इसके अलावा ऑब्जेक्ट को उस ऑब्जेक्ट में स्थानीय रूप से पारित किया जा रहा है जो कंटेनर (उदाहरण के लिए एक लेनदेन ऑब्जेक्ट) का उपयोग करके नई ऑब्जेक्ट बनाता है और इसमें कुछ राज्य है (यह एक नई वस्तु नहीं है जिसे मैं कंटेनर के साथ प्राप्त कर सकता हूं)।

+0

मैं 'TContainer.Resolve ' की एक अधिभार Spring4D में एक सरणी पैरामीटर को स्वीकार करने की पता नहीं है। क्या मुझे कुछ याद आती है? – menjaraz

+0

@menjaraz यह सिर्फ यह विचार था कि इसे कैसे कार्यान्वित किया जा सकता है (निश्चित रूप से इसे आरटीटीआई के साथ डोंडे किया जा सकता है) –

+0

ठीक है, यह सुविधा अनुरोध की तरह लगता है। [Spring4d Google समूह] (http://groups.google.com/group/spring4d) पर भी पोस्ट क्यों न करें? – menjaraz

उत्तर

7

मैंने एकता में संकल्प ओवरराइड जोड़ा है।

तो तुम लिख सकते हैं:

program Demo; 

{$APPTYPE CONSOLE} 

uses 
    Classes, 
    Spring.Container, 
    Spring.Container.Resolvers; 

type 
    IUserUpgrader = interface 
    ['{ADC36759-6E40-417D-B6F7-5DCADF8B9C07}'] 
    end; 

    TUser = class(TObject); 

    TUserProcessor = class(TInterfacedObject, IUserUpgrader) 
    public 
    constructor Create(AUser: TUser); 
    end; 

constructor TUserProcessor.Create(AUser: TUser); 
begin 
    Writeln('called constructor with passed user'); 
end; 

begin 
    GlobalContainer.RegisterType<TUserProcessor>.Implements<IUserUpgrader>; 
    GlobalContainer.Build; 

    GlobalContainer.Resolve<IUserUpgrader>(
    TOrderedParametersOverride.Create([TUser.Create])); 

    GlobalContainer.Resolve<IUserUpgrader>(
    TParameterOverride.Create('AUser', TUser.Create)); 

    Readln; 
end. 
0

आप इस सूत्र की जाँच कर सकते हैं: https://forums.embarcadero.com/message.jspa?messageID=440741

मैं ढांचे में इस पर एक का क्रियान्वयन किया है और मेरे कोड में इसका इस्तेमाल करते हैं। यदि आप इसे चाहते हैं, तो मैं इसे आपको भेज दूंगा। ध्यान रखें कि यह नहीं किया जा सकता है कि जब यह कोडबेस में इस तरह की कार्यक्षमता जोड़ता है तो यह कैसे किया जा सकता है। बाओक्वान का मेरा कोड है।

यह कार्यान्वयन भी संभालता है यदि आप सभी आवश्यक पैरामीटर के बिना हल करने का प्रयास करते हैं, और आपको अनुपलब्ध पैरामीटर दिखाने का अपवाद देता है।

आप इस तरह इसका इस्तेमाल:

ServiceLocator.GetService<ISomeObj>(ServiceParameters['paramname1',value1]['paramname2',value2]..); 

मूल्य TValue के रूप में संग्रहीत किया जाता है और कुछ भी हो सकता है।

अपनी कक्षा के साथ पैरामीटर का पंजीयन इस तरह विशेषताओं के साथ किया जाता है:

private 
    [ContainerParameter('paramname1')] 
    FYourValue1: ...; 
    [ContainerParameter('paramname2')] 
    FYourValue2: ..; 

तुम भी

[ContainerParameter] 
FYourValue1:.. 

कर सकते हैं लेकिन फिर अपने पैरामीटर नाम के रूप में 'FYourValue1' की है।

संबंधित मुद्दे