私は Dagger 2 で以下を設定しようとしています:
AnEventFinderには 2 つの部分があります: aTriggerFinderと an のArgFinderそれぞれには、多くの依存関係を持つ複雑なオブジェクトである多くの異なる実装があります。以下のコード サンプルは、別のオブジェクトに依存するEventFinderwith サンプルTriggerFinderとを正常にビルドします。ただし、モデル間でシングルトンとして共有したい非常に大きく、高価な定数オブジェクトです。の現在の実装では、 2 回ロードされます。メソッドをとしてマークしようとすると、次のエラーが発生します。ArgFinderWordNetWordNetWithWordNetEventFinderComponentWordNet@ProvidesWordNetModule@Singleton
Error: ArgFinderUsingWordNetComponent (unscoped) may not reference scoped bindings:
@Singleton @Provides WordNet WordNetModule.provideWordNet()
しかし、注釈をコンポーネントのツリーの上に伝播@Singletonしても、他のエラーが発生するだけです。これを行う正しい方法はどうなりますか?
完全なコード:
import org.junit.Test;
import javax.inject.Inject;
import javax.inject.Named;
import dagger.Component;
import dagger.Module;
import dagger.Provides;
// WordNet - this is the expensive shared resource we would
// like to make a singleton
class WordNet {
final String path;
public WordNet(@Named("path") String path) {
System.out.println("Loading Fake wordnet from " + path);
this.path = path;
}
}
@Module
class WordNetModule {
final String path;
public WordNetModule(String path) {
this.path = path;
}
// uncommenting the line below causes errors
//@Singleton
@Provides
public WordNet provideWordNet() {
return new WordNet(path);
}
}
interface TriggerFinder {
}
class TriggerFinderUsingWordnet implements TriggerFinder {
WordNet wordNet;
@Inject
public TriggerFinderUsingWordnet(WordNet wordNet) {
this.wordNet = wordNet;
}
}
@Module(includes = WordNetModule.class)
class TriggerFinderWithWordnetModule {
@Provides
public TriggerFinder provideTriggerFinder(TriggerFinderUsingWordnet triggerFinder) {
return triggerFinder;
}
}
interface ArgFinder {
}
class ArgFinderUsingWordnet implements ArgFinder {
WordNet wordNet;
@Inject
public ArgFinderUsingWordnet(WordNet fakeWordNet) {
this.wordNet = fakeWordNet;
}
}
@Module(includes = WordNetModule.class)
class ArgFinderWithWordNetModule {
@Provides
public ArgFinder provideArgFinder(ArgFinderUsingWordnet argFinder) {
return argFinder;
}
}
// the composite object we wish to create
class EventFinder {
private final TriggerFinder triggerFinder;
private final ArgFinder argFinder;
@Inject
public EventFinder(TriggerFinder triggerFinder, ArgFinder argFinder) {
this.triggerFinder = triggerFinder;
this.argFinder = argFinder;
}
}
// components to wire everything together
interface ArgFinderComponent {
ArgFinder argFinder();
}
interface TriggerFinderComponent {
TriggerFinder triggerFinder();
}
@Component(modules = ArgFinderWithWordNetModule.class)
interface ArgFinderUsingWordNetComponent extends ArgFinderComponent {
}
@Component(modules = TriggerFinderWithWordnetModule.class)
interface TriggerFinderUsingWordNetComponent extends TriggerFinderComponent {
}
interface EventFinderComponent {
EventFinder eventFinder();
}
@Component(dependencies = {ArgFinderUsingWordNetComponent.class,
TriggerFinderUsingWordNetComponent.class})
interface WithWordNetEventFinderComponent extends EventFinderComponent {
}
public class DaggerComponentTest {
@Test
public void withWordNetTest() {
final WordNetModule wordNetModule = new WordNetModule("myPath");
DaggerWithWordNetEventFinderComponent.builder()
.argFinderUsingWordNetComponent(
DaggerArgFinderUsingWordNetComponent.builder().wordNetModule(wordNetModule).build())
.triggerFinderUsingWordNetComponent(
DaggerTriggerFinderUsingWordNetComponent.builder().wordNetModule(wordNetModule).build())
.build().eventFinder();
}
}