1

私は Google Guice を初めて使用し、特定のシナリオでの使用方法について頭を悩ませようとしています。私はかなり複雑なサービス クライアントを構築していますが、(私は信じています) Builder パターンを正しくインスタンス化する必要があります。このクライアントは最終的に独自の JAR ライブラリにパッケージ化されるため、内部で DI を処理するように Guice を使用したいと考えています。以下は、私のコードの大幅に簡略化されたバージョンです。

public interface MyClient {
    public FizzResource getFizzResource();
    public BuzzResource getBuzzResource();
    public FooResource getFooResource();
}

public class MyClientImpl implements MyClient {
    // See below
}

public class GetFizzCommand {
    // omitted for brevity
}

public class GetBuzzCommand {
    // omitted for brevity
}

public class GetFooCommand {
    // omitted for brevity
}

public interface FizzResource {
    Fizz getFizz(Long fizzId);
}

public class FizzResourceImpl implements FizzResource {
    private GetFizzCommand getFizzCommand;

    @Override
    Fizz getFizz(Long fizzId) {
        return getFizzCommand.doGetFizz(fizzId);
    }
}

public interface BuzzResource {
    Buzz getBuzz(Long buzzId);
}

public class BuzzResourceImpl implements BuzzResource {
    private GetBuzzCommand getBuzzCommand;

    @Override
    Buzz getBuzz(Long buzzId) {
        return getBuzzCommand.doGetBuzz(buzzId);
    }
}

public interface FooResource {
    Foo getFoo(Long fooId);
}

public class FooResourceImpl implements FooResource {
    private GetFooCommand getFooCommand;

    @Override
    Foo getFoo(Long fooId) {
        return getFooCommand.doGetFoo(fooId);
    }
}

ご覧のとおり、階層/依存グラフは次のとおりです。

  • MyClient*ResourceImplsを注入する必要があります
  • それぞれにインスタンス*ResourceImplを注入する必要があります*Command

意図された使用例は、MyClientimpl の構築を次のように簡単にすることです。

MyClient myClient = MyClientImpl.Builder("myservice.example.org", 8080L, getWidget())
    .withAuth("user", "password")
    .withHttps()
    .withFailureStrategy(someFailureStrategy)
    // ...etc.
    .build();

MyClientImplそこで、 、その内部ビルダー、および私の Guice モジュールに対する私の最善の試みを次に示します。

public class BaseClient {
    private String uri;
    private long port;
    private Widget widget;

    // ctor, getters and setters
}

public class MyClientImpl extends BaseClient implements MyClient {
    @Inject
    private FizzResource fizzResource;

    @Inject
    private BuzzResource buzzResource;

    @Inject
    private FooResource fooResource

    public MyClientImpl(String uri, long port, Widget widget) {
        super(uri, port, widget);
    }

    public static class Builder {
        private String uri;
        private long port;
        private Widget widget;

        Builder(String uri, long port, Widget widget) {
            super();

            setUri(uri);
            setPort(port);
            setWidget(widget);
        }

        // Lots of methods on the builder setting lots of MyClient-specific properties
        // that I have omitted here for brevity.

        MyClient build() {
            Injector injector = Guice.createInjector(new MyClientModule(this));
            return injector.getInstance(MyClient.class);
        }
    }
}

public class MyClientModule extends AbstractModule {
    private MyClientImpl.Builder builder;

    public MyClientModule(MyClientImpl.Builder builder) {
        super();

        setBuilder(builder);
    }

    @Override
    protected void configure() {
        MyClientImpl myClientImpl = new MyClientImpl(builder.getUri(), builder.getPort(), builder.getWidget());

        bind(MyClient.class).toInstance(myClientImpl);
    }
}

しかし、私の人生では、次の方法/場所がわかりません。

  • *Commands を s にバインドし*ResourceImplます。と
  • *ResourceImplMyClientImplインスタンスにバインドします

何か案は?

4

1 に答える 1