私は 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
*ResourceImpl
sを注入する必要があります- それぞれにインスタンス
*ResourceImpl
を注入する必要があります*Command
意図された使用例は、MyClient
impl の構築を次のように簡単にすることです。
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);
}
}
しかし、私の人生では、次の方法/場所がわかりません。
*Command
s を s にバインドし*ResourceImpl
ます。と*ResourceImpl
をMyClientImpl
インスタンスにバインドします
何か案は?