2009-10-14 18 views
20

मैं गुइस के लिए नया हूं और यहां एक बेवकूफ सवाल है। मुझे पता चला है कि हम माध्यम से एक विशेष मूल्य के लिए स्ट्रिंग के लिए बाध्य कर सकते हैं:गुइस में परिवर्तनीय करने के लिए स्ट्रिंग कैसे बांधें?

bind(String.class) 
     .annotatedWith(Names.named("JDBC URL")) 
     .toInstance("jdbc:mysql://localhost/pizza"); 

लेकिन क्या होगा अगर मैं किसी भी संभव वर्णों के लिए स्ट्रिंग बाध्य करने के लिए करना चाहते हैं?

या मैं इसे इस तरह वर्णित किया जा सकता लगता है:

मैं कैसे बदल सकते हैं "नई SomeClass (स्ट्रिंग strParameter)" Guice के साथ?

+2

उन सभी चालों के साथ DI (निर्भरता इंजेक्शन) पढ़ने कोड को कठिन बनाता है, इसका मूल लक्ष्य खो गया है। अधिकांश मामलों में निर्भरता निर्भर नहीं है, संदर्भ एक ही स्थान पर रखें। यह रखरखाव को बहुत आसान बनाता है। –

उत्तर

37

आप पहली बार SomeClass के लिए निर्माता टिप्पणी करने की जरूरत:

class SomeClass { 
    @Inject 
    SomeClass(@Named("JDBC URL") String jdbcUrl) { 
    this.jdbcUrl = jdbcUrl; 
    } 
} 

मैं कस्टम व्याख्या का उपयोग करना पसंद करते हैं, इस तरह:

class SomeClass { 
    @Inject 
    SomeClass(@JdbcUrl String jdbcUrl) { 
    this.jdbcUrl = jdbcUrl; 
    } 

    @Retention(RetentionPolicy.RUNTIME) 
    @Target({ElementType.FIELD, ElementType.PARAMETER}) 
    @BindingAnnotation 
    public @interface JdbcUrl {} 
} 

तो फिर आप अपने मॉड्यूल में एक बाध्यकारी प्रदान करने की आवश्यकता :

public class SomeModule extends AbstractModule { 
    private final String jdbcUrl; // set in constructor 

    protected void configure() { 
    bindConstant().annotatedWith(SomeClass.JdbcUrl.class).to(jdbcUrl); 
    } 
} 

फिर एक बार गुइस कुछ क्लास बनाता है, यह पैरामीटर इंजेक्ट करेगा। अक्सर

class SomeOtherClass { 
    @Inject 
    SomeOtherClass(SomeClass someClass) { 
    this.someClass = someClass; 
    } 

, जब आपको लगता है कि आप एक स्ट्रिंग इंजेक्षन करना चाहते हैं, आप एक वस्तु इंजेक्षन करना चाहते हैं: उदाहरण के लिए, यदि SomeOtherClass SomeClass पर निर्भर करता है। उदाहरण के लिए, यदि स्ट्रिंग एक यूआरएल है, तो मैं अक्सर बाध्यकारी एनोटेशन के साथ URI इंजेक्ट करता हूं।

यह सब मानते हैं कि कुछ स्थिर मूल्य है जो आप स्ट्रिंग के लिए मॉड्यूल निर्माण समय पर परिभाषित कर सकते हैं। यदि मॉड्यूल निर्माण समय पर मान उपलब्ध नहीं है, तो आप AssistedInject का उपयोग कर सकते हैं।

+0

डाउन-वोट क्यों? – NamshubWriter

0

मैं Guice के सवाल जवाब में एक समाधान खोजने के:

http://code.google.com/docreader/#p=google-guice&s=google-guice&t=FrequentlyAskedQuestions

इसके अलावा एक एनोटेशन और MyModule में एक स्ट्रिंग विशेषता परिभाषित करने के लिए, मैं रेखा के नीचे लिखने के लिए SomeClass का एक उदाहरण प्राप्त करने की आवश्यकता:

SomeClass instance = Guice.createInjector(new MyModule("any string i like to use")).getInstance(SomeClass.class); 

लेकिन मुझे याद है कि Injector.getInstance() जड़ वस्तु को छोड़कर नहीं किया जाना चाहिए, इसलिए वहाँ यह करने के लिए किसी भी बेहतर तरीका है?

18

यह विषय-वस्तु हो सकता है, लेकिन गुइस आपको आवश्यक प्रत्येक स्ट्रिंग के लिए एक स्पष्ट बाध्यकारी लिखने से कॉन्फ़िगरेशन को अधिक आसान बनाता है। तुम सिर्फ उनके लिए एक कॉन्फ़िग फ़ाइल हो सकता है:

Properties configProps = Properties.load(getClass().getClassLoader().getResourceAsStream("myconfig.properties"); 
Names.bindProperties(binder(), configProps); 

और अपने सभी config देखा इंजेक्शन के लिए तैयार है:

@Provides // use this to have nice creation methods in modules 
public Connection getDBConnection(@Named("dbConnection") String connectionStr, 
            @Named("dbUser") String user, 
            @Named("dbPw") String pw,) { 
    return DriverManager.getConnection(connectionStr, user, pw); 
} 

अब बस बनाने के अपने Java properties filemyconfig.properties अपने classpath की जड़ में साथ

dbConnection = jdbc:mysql://localhost/test 
dbUser = username 
dbPw = password 

या किसी अन्य स्रोत से प्राधिकरण जानकारी को गुणों में मर्ज करें और आप सेट हैं।