How do I tell Dagger 2 which implementation to instantiate based on X?

戏子无情 提交于 2019-12-01 16:32:59

Rather than Lazy<T>, do option 1 with Provider<T>. Lazy<T> is just a Provider<T> that memoizes locally (with the necessary double-checked locking), but because you know you'll only call one Provider exactly once, you can just inject the Provider instead and skip the synchronization overhead.

@Provides
FooInterface provideFooImplementation(
        Provider<FooImpl1> impl1,
        Provider<FooImpl2> impl2,
        ...,
        Provider<FooImpl10> impl10) {
    switch(state) {
        case STATE_1:
            return impl1.get();
        case STATE_2:
            return impl2.get();
        ...
        case STATE_10:
            return impl10.get();
    }
}

Option 2 will work, but you'll effectively skip the dependency wiring that Dagger could easily do for you, and Option 3 won't work as stated because your @Component annotation needs your list of modules to be a compile-time constant for your Dagger code generation to work.

(A variant of Option 3 could work if your binding were to a constant or a zero-dependency class of one form or another, because then you could pass in an arbitrary subclass of your Module into your Component builder. However, Dagger can only analyze the bindings in the superclass module, and you'd have trouble if your @Provides method implementations take different parameters as yours would, so the switch is the best and clearest alternative I can think of.)

A possible solution would be using @Named("foo") annotation in conjunction with favoring component provision method over manual injection, which would however mean that your state would be independent from the module itself, and you'd be the one to make your choice

@Component(modules={FooModule.class})
public interface AppComponent {
    @Named("STATE_1")
    FooInterface fooImpl1();
    @Named("STATE_2")
    FooInterface fooImpl2();
    ...
    @Named("STATE_10")
    FooInterface fooImpl10();
}

@Module
public FooImpl1Module {
    @Provides
    @Named("STATE_1")
    FooInterface provideFooImpl1(Context context) {
        return new FooImpl1(context);
    }

    @Provides
    @Named("STATE_2")
    FooInterface provideFooImpl2(Context context) {
        return new FooImpl2(context);
    }

    ...

    @Provides
    @Named("STATE_10")
    FooInterface provideFooImpl10(Context context) {
        return new FooImpl10(context);
    }
}

Then you can call

FooInterface fooInterface = component.fooImpl1();
HecticAF

Have you tried something like this?

public class hectic extends Iam {

    String tokenizer heccas = new string tokenizer();
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!