0

私はGoogle Guiceにかなり慣れていません。

nexus がいくつかのクラスを注入する nexus プラグインを作成しています。たとえば、クラス Aに注入されるクラスを言います。

クラス A が注入される前に、インスタンス化された別のクラス Bがあり、その中にオブジェクト (obj など) が初期化されるメソッドがあります。

この初期化されたオブジェクトをクラス A に渡す必要があります。

通常、インスタンス化が私たちの管理下にある場合、私は次のようにします

A a = new A();

A.setObject(obj);

しかし、クラスがシステムによって注入されることを考えると、この初期化されたオブジェクトをこのクラス A に渡す方法がわかりません。

4

1 に答える 1

1

私が正しく理解していれば、次のようなものがあります

public class C {
}

public class A {
    private C c;

    public void setC(C c) {
        this.c = c;
    }
}

public class B {
    private final C c;

    public B() {
        this.c = new C();
    }

    public C getC() {
        return this.c;
    }
}

public class Main {
    public static void main(String[] args) {
        B b = new B();
        A a = new A();

        C c = b.getC();
        a.setC(c);
    }
}

この設計は DI の原則に従っていないため、リファクタリングする必要があります。Guice にインスタンスを作成させる必要がありCます。その場合、次のようなものがあります

public class C {
}

public class A {
    private final C c;

    @Inject
    A(C c) {
        this.c = c;
    }
}

public class B {
    private final C c;

    @Inject
    B(C c) {
        this.c = c;
    }
}

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector();
        A a = injector.getInstance(A.class);
        B b = injector.getInstance(B.class);
    }
}

ここでは、 とCの両方に自動的に注入しています。AB

コードをリファクタリングできない場合は、プロバイダーの使用を検討してください

public class AProvider extends Provider<A> {
    private final B b;

    @Inject
    AProvider(B b) {
        this.b = b;
    }

    @Override
    public A get() {
        A a = new A();
        C c = b.getC();
        a.setC(c);
        // Or, better
        // A a = new A(b.getC());
        return a;
    }
}

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                bind(A.class).toProvider(AProvider.class);
            }
        });
        A a = injector.getInstance(A.class);
    }
}

この場合、プロバイダーを使用して依存関係を作成Aおよび設定します。C

しかし、それだけでは不十分な場合もあります (たとえば、B.getC()動作がユーザー入力に依存する場合)。その場合、Assisted Inject拡張機能を使用する必要があります。

public interface AFactory {
    public A create(C c);
}

public class A {
    private final C c;
    private final Other other;

    @Inject
    A(@Assisted C c, Other other) {
        this.c = c;
        this.other = other;
    }
}

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new AbstractModule() {
            @Inject
            protected void configure() {
                install(new FactoryModuleBuilder()
                    .build(AFactory.class));
            }
        });

        B b = injector.getInstance(B.class);
        C c = b.getC(someUserInput);
        AFactory af = injector.getInstance(AFactory.class);
        A a = af.create(c);
    }
}

最後の例では、呼び出しによって 2 つのオブジェクトが注入されます。1 つA目は指定したもの、2 つ目は Guice によって自動的に解決されるクラスのインスタンスです。言い換えれば、補助注入を使用すると、依存関係の一部を自分で解決し、残りの部分を Guice で解決するクラスをインスタンス化できます。af.create(c)cOther

于 2013-09-05T18:22:43.937 に答える