この質問では、Dagger2について話します。Dagger2 は、基本的にコンポーネントとモジュールで構成されています。次に例を示します。
私はインターフェースを持っていると仮定します:
public interface MyCoolService {
void run();
}
可能な実装:
public class MyCoolServiceImpl {
@Override
void run() {}
}
Dagger2 生成を使用して、実装をインターフェイスにリンクできます。
@Component(modules = {MyModule.class})
@Singleton
public interface Component {
MyCoolService getMyCoolService();
}
と
@Module
public class MyModule {
@Provides @Singleton
MyCoolService provideMyCoolService() {
return new MyCoolServiceImpl();
}
}
これは、Dagger2 の簡単な紹介でした。ここで、次のインターフェースがあるとします。
public interface MySecondCoolService {
void doCoolStuff();
}
コード内の実装はありませんMySecondCoolServiceImpl
。MySecondCoolService
代わりに、@JustForCoolStuff
フィールドとメソッドをマークする注釈があります。MySecondCoolServiceImpl
これらすべての注釈を収集し、どの実装を生成する注釈プロセッサを作成しましたMySecondCoolService
。
MySecondCoolService
注釈プロセッサが実行される前に、コンパイラは新しいインターフェイスを認識します。したがって、コンポーネントを次のように変更できます。
@Component(modules = {MyModule.class})
@Singleton
public interface Component {
MyCoolService getMyCoolService();
MySecondCoolService getMySecondCoolService();
}
問題は、コードにまだ実装がなくMySecondCoolService
、注釈プロセッサによって生成される実装の名前がわからないことです。したがって、 で正しい実装を使用してインターフェイスを配線することはできませんMyModule
。私にできることは、新しいモジュールを生成するように注釈プロセッサを変更することです。私の注釈プロセッサは、次のようなモジュール ( MyGeneratedModule
)を生成できます。
@Module
public class MyGeneratedModule {
@Provides @Singleton
MySecondCoolService provide MySecondCoolService() {
return new MySecondCoolServiceImpl();
}
}
再度MyGeneratedModule
、注釈プロセッサによって生成されます。注釈プロセッサを実行する前にアクセスできません。また、名前もわかりません。
問題は次のとおりです。注釈プロセッサは、Dagger2 が考慮すべき新しいモジュールがあることを Dagger2 に通知する必要があります。注釈プロセッサはファイルを変更できないため、@Component(modules = {MyModule.class})
注釈を拡張して次のように変更することはできません。@Component(modules = {MyModule.class, MyGeneratedModule.class})
MyGeneratedModule
プログラムでdagger2依存関係グラフに追加する方法はありますか? 上記で説明したように、注釈プロセッサはどのようにしてインターフェイスと実装の間に新しい配線が必要であることを Dagger2 に伝えることができますか?
Foray: Google GuiceとGoogle Gin でそのようなことができることは知っています。それを行うプロジェクトがGWTPです。そこにプレゼンターがあります:
public class StartPagePresenter extends ... {
@NameToken("start")
public interface MyProxy extends ProxyPlace<StartPagePresenter> {
}
...
}
インターフェイスへの@NameToken
注釈がありProxyPlace
ます。AbstractPresenterModule
プレゼンターとプロキシを使用してビューを配線します。
public class ApplicationModule extends AbstractPresenterModule {
bindPresenter(StartPagePresenter.class,
StartPagePresenter.MyView.class, StartPageView.class,
StartPagePresenter.MyProxy.class);
...
}
ご覧のとおり、MyProxy
インターフェイスの実装は指定されていません。Generator によって作成された実装 (アノテーション プロセッサに似ていますが、GWT 用)。そこでジェネレーターはの実装を生成し、StartPagePresenter.MyProxy
それをガイド/ジン システムに追加します。
public class StartPagePresenterMyProxyImpl extends com.gwtplatform.mvp.client.proxy.ProxyPlaceImpl<StartPagePresenter> implements buddyis.mobile.client.app.start.StartPagePresenter.MyProxy, com.gwtplatform.mvp.client.DelayedBind {
private com.gwtplatform.mvp.client.ClientGinjector ginjector;
@Override
public void delayedBind(Ginjector baseGinjector) {
ginjector = (com.gwtplatform.mvp.client.ClientGinjector)baseGinjector;
bind(ginjector.getPlaceManager(),
ginjector.getEventBus());
presenter = new CodeSplitProvider<StartPagePresenter>( ginjector.getbuddyismobileclientappstartStartPagePresenter() );
...
}
}