2013-10-14 5 views
9

पर आधारित रनटाइम पर इंजेक्शन कैसे बदलें, निम्नलिखित समस्या का अनुमान है जो मुझे सामना कर रहा है।गिस: एक (गतिशील वेब प्रॉपर्टी)

सोचें कि हमारे पास कुछ नियमों के साथ एक पासवर्ड सत्यापनकर्ता है।

public interface RuleChecker{ 

    //Checks for a password strenght, returns 10 
    //for strong or 0 for soft password. 
    int check(String pass); 
} 

और फिर हमारे पास कई कार्यान्वयन हैं, हमारी सेवा केवल 8 अंकों से अधिक होने पर पासवर्ड स्वीकार करेगी।

public class NoCheck implements RuleChecker { 
    public int check(String pass){return 10;} 
} 

public class LengthCheck implements RuleChecker{ 
    ... 
} 
public class AlphanumericCheck implements RuleChecker{ 
    ... 
} 
public class AlphaAndLenghtCheckAdapter implements RuleChecker{ 
    ... 
} 

लेकिन परीक्षण प्रयोजनों के लिए, हम आवेदन जहाँ हम "व्यवस्थापक" उन नियमों, और चुन सकते हैं कि करने के लिए के भीतर एक वेब सेवा को लागू करना चाहते हैं।

public class PasswordCheckService{ 

    private RuleChecker checker; 

    @Inject 
    public PasswordCheckService(final RuleChecker checker){ 
     this.checker = checker; 
    } 

    public boolean checkPassword(String password){ 
     return checker.check(password) > 8; 
    } 
} 

तो, क्या गुइस में रनटाइम में बदलने के लिए कोई तरीका है, इंजेक्शन में एक सेवा है?

उदाहरण:

हम आवेदन शुरू कर दिया और डिफ़ॉल्ट रूप से LengthCheck चुना गया है और आवेदन पर इंजेक्शन, वेबसाइट पर हम NoCheck चेकबॉक्स का चयन करें और विकल्प बचाने के लिए, जो डेटाबेस में संग्रहीत किया जाता है, मैं Guice के लिए कॉन्फ़िगर कर सकते हैं स्वचालित रूप से उस बीन को बदल दें जो सेवा पहले इंजेक्शन थी? तो अब से और नए पासवर्ड पर कोई जांच नहीं होगी?

-

अब के रूप में, मैं उन विषयों

Google Guice and varying injections at runtime पाया है लेकिन मुझे नहीं पता है कि प्रदाताओं उस तरह मेरी समस्या फिट बैठता है।

Guice runtime dependency parameters reinjection यह अच्छा सवाल कुछ समान बात कर रहा है, लेकिन जो मैं देख रहा हूं वह नहीं।

guice: runtime injection/binding at command line यह मेरी समस्या का सबसे नज़दीकी है लेकिन वह केवल "रनटाइम" शुरू करने पर करता है और उस समय इसे बदलता नहीं है।

कोई मदद करता है?

धन्यवाद!

पहली टिप्पणी की नोक का उपयोग करके मैंने इस पीओसी को लागू किया लेकिन अभी भी काम नहीं करता है, अगर आप एक और बटन चुनते हैं तो सेवा बीन अपडेट नहीं होता है। https://bitbucket.org/ramonboza/guicedynamicconfig

+0

अच्छा प्रश्न:

आप इस तरह अपने खेतों और सेवाओं की घोषणा करने के लिए है। मैं कुछ ऐसा ही करने की कोशिश कर रहा हूं। – tom

उत्तर

4

प्रत्येक क्षेत्र प्रकार (प्रवेश, पासवर्ड, जन्म तिथि ...) के लिए एक प्रदाता बनाएं, जिसका पैरामीटर के साथ वापस जाने के लिए कार्यान्वयन बदलने के लिए।

public class MyModule extends AbstractModule { 

    public void configure() { 
     bind(RuleChecker.class).annotatedWith(named("password")).toProvider(PasswordRuleCheckerProvider.class); 
     bind(RuleChecker.class).annotatedWith(named("login")).toProvider(LoginRuleCheckerProvider.class); 
    } 
} 

public static class PasswordRuleCheckerProvider implements Provider<RuleChecker> { 

    private static CheckType type = CheckType.ALPHANUMERIC; 
    // static type setter. 

    public RuleChecker get() { 
     // it would even be better if you could use singletons here. 
     switch(type) { 
      case LENGTH: 
       return new LengthCheck(); 
      case ALPHANUMERIC: 
       return new AlphanumericCheck(); 
      case ALPHALENGTH: 
       return new AlphaAndLenghtCheckAdapter(); 
      case NONE: 
      default: 
       return NoCheck(); 
     } 
    } 
} 
// Almost same provider for your LoginRuleCheckerProvider. You could do something generic. 

अपने व्यवस्थापक अनुभाग में आप "प्रकार" मान बदलते हैं, इसलिए आपके नियम बदल जाएंगे। यह एनोटेशन के लिए धन्यवाद, फ़ील्ड के सीमित सेट को प्रभावित कर सकता है। उदाहरण के लिए: PasswordRuleCheckerProvider.setType(CheckType.LENGTH);। केवल @Named('password') वाले फ़ील्ड को प्रभावित करेगा।

public abstract class DynamicService { 
    protected void updateService() { 
     // Reinject with the new implementations the members. 
     App.getInjector().injectMembers(this); 
    } 
} 

public class PasswordCheckService extends DynamicService { 
    @Inject 
    @Named("password") 
    private RuleChecker passwordChecker; 

    public void changePasswordCheckType(CheckType type) { 
     PasswordRuleCheckerProvider.setType(type); 
     // Reinject, so you have your new implementation. 
     updateService(); 
    } 

    // [...] 
} 
+0

मैं एक PoC अपने सन्निकटन कोशिश करने के लिए करते हैं gonnna हूँ;), घंटे (दोपहर का भोजन समय अब ​​xD) – RamonBoza

+0

Updated विषय के एक जोड़े में वापस करने की उम्मीद है, नहीं, कोई भाग्य के साथ POC कार्यान्वित जाँच https://bitbucket.org/ramonboza/guicedynamicconfig – RamonBoza

+0

स्थानीय स्तर पर यह काम कर पाने में कामयाब रहे। मैंने पोस्ट अपडेट किया है। आपको केवल निर्भरताओं को फिर से लोड करना होगा और अपने प्रदाता में फ़ील्ड 'टाइप' स्थिर रखना होगा। –

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