2013-10-14 4 views
9

以下は私が直面している問題の概算です。Guice:(動的ウェブプロパティ)に基づいて実行時のインジェクションを変更する方法

いくつかのルールを持つパスワードバリデータがあると考えてください。

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

は、しかし、テスト目的のために、私たちは、「管理者」これらのルール、そしてが持っているものを選択することができ、アプリケーション内のWebサービスを実装したいです。

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

Guiceには実行時に変更する方法がありますか?サービスには注入がありますか?

例:

は、私たちは、アプリケーションを起動し、デフォルトでLengthCheckは、アプリケーション上で選択し、注入され、我々はNOCHECK]チェックボックスを選択して、データベースに保存されているオプションは、保存するウェブサイトで、私はへのGuiceを設定することができますサービスが以前に注入したBeanを自動的に変更しますか?今から、新しいパスワードのチェックはありませんか?

- 今のよう

、私はこれらのトピック

Google Guice and varying injections at runtime

発見したしかし、私はプロバイダのようなものが私の問題に合うかどうかを知るいけません。

Guice runtime dependency parameters reinjection この素晴らしい質問は、私が探しているものではなく、類似のものを話すことです。

guice: runtime injection/binding at command line これは私の問題に最も近いですが、彼は「ランタイム」を起動するだけで、それを変更しません。

助けてください?

ありがとうございました!

最初のコメントのヒントを使用してこのPOCを実装しましたが、まだ動作しません。別のボタンを選択して変更すると、サービスBeanは更新されません。 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

私はgonnnaあなたの近似を試みるためにPoCをしています;)、数時間(昼食時xD)に戻ることを願って – RamonBoza

+0

更新されたトピックは、運がないPOCを実装しました https://bitbucket.org/ramonboza/guicedynamicconfig – RamonBoza

+0

ローカルで動作するように管理しました。私は投稿を更新しました。依存関係をリロードして、プロバイダのフィールドタイプを静的に保つだけで済みます。 –

関連する問題