2013-10-14 28 views
9

Aşağıdaki, karşılaştığım sorunun yaklaşık bir yaklaşımıdır.Guice: Bir dinamik (dinamik web özelliği) temel alınarak çalışma zamanında enjeksiyon nasıl değiştirilir

Bazı kurallara sahip bir parola doğrulayıcımız olduğunu düşünelim. o 8 puan üzerinde ise

public interface RuleChecker{ 

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

Sonra birkaç uygulamaları var, hizmetimiz sadece şifreyi kabul eder.

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

Ama test amacıyla, biz "admin" bu kurallar ve sahip hangilerinin seçebilirsiniz uygulama içinde bir webcoder uygulamak istiyoruz.

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; 
    } 
} 

Yani, bir hizmetin var olduğu anda, çalışma zamanında değiştirmek için Guice'de herhangi bir yolu var mı?

Örnek: Biz uygulamayı başlatan ve varsayılan olarak LengthCheck web sitesinde biz veritabanına saklandığı seçenekleri nocheck onay kutusunu işaretleyin ve kaydedin, uygulamaya seçilir ve enjekte edilir

, ben Guice yapılandırabilirsiniz Servisin daha önce enjekte ettiği fasulyeyi otomatik olarak değiştirir mi? Bundan böyle yeni şifrelerle ilgili herhangi bir kontrol olmayacak mı?

- şimdi gelince

, ben bu konular

Google Guice and varying injections at runtime

bulduk Ama sağlayıcıların bu tür sorunumu uyuyor bilmiyorum.

Guice runtime dependency parameters reinjection Bu güzel soru benzer bir şey konuşuyor, ama baktığım şey değil.

guice: runtime injection/binding at command line Bu, benim sorunuma en yakın olanıdır ancak yalnızca "çalışma zamanı" işlemini başlatmakta ve zaman içinde değişmez.

Herhangi bir yardımcı olur mu?

Teşekkür ederiz!

İlk yorumun ipucunu kullanarak, bu POC'yi uyguladım ancak yine de çalışmıyor, başka bir düğmeyi değiştirirseniz, hizmet çekirdeği güncelleştirilmez. https://bitbucket.org/ramonboza/guicedynamicconfig

+0

İyi soru:

Böyle alanlarınızı ve hizmetler beyan etmek zorunda. Çok benzer bir şey yapmaya çalışıyorum. – tom

cevap

4

dönmek için uygulamayı değiştirmek için bir parametre ile, her alan türü (giriş, şifre, doğum tarihi ...) için bir sağlayıcı oluşturun. Kurallarınızın değişecek böylece, "tip" değerini değiştirmek Yönetici bölümünde

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. 

. Ek açıklamalar sayesinde sınırlı bir alan grubunu etkileyebilir. Örneğin: PasswordRuleCheckerProvider.setType(CheckType.LENGTH);. Sadece @Named('password') ile alanları etkileyecektir.

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

Yaklaşımınızı denemek için bir PoC uyguladım;), birkaç saat içinde geri gelmeyi umuyorum (şimdi xD öğle yemeği zamanı) – RamonBoza

+0

Güncellenen konu, POC'u şanssız uyguladı, https://bitbucket.org/ramonboza/guicedynamicconfig – RamonBoza

+0

Yerel olarak çalışmak için yönetiliyor. Yayını güncelledim. Bağımlıları yeniden yüklemeniz ve sağlayıcınızdaki 'type' (statik) alanını tutmanız gerekir. –

İlgili konular