Reputation: 11
I'm poking around with Dagger2 and its built-in AssisedInject annotation. The tutorial available at dagger.dev shows an example where the factory method returns a concrete class but I would have expected the factory to return an interface for which an implementation binding is defined in some module.
class MyDataService {
@AssistedInject
MyDataService(DataFetcher dataFetcher, @Assisted Config config) {}
}
// ---
@AssistedFactory
public interface MyDataServiceFactory {
MyDataService create(Config config);
}
In Google Guice, e.g. I can create a module with a factory module builder to tie together interface and implementation:
install(new FactoryModuleBuilder()
.implement(Payment.class, RealPayment.class)
.build(PaymentFactory.class));
Isn't that possible with Dagger2 AssistedInject? I'm pretty new to Dagger, perhaps I misunderstood the concept at that point. Any help is very much appreciated!
Upvotes: 1
Views: 334
Reputation: 50538
Yes it's possible:
Annotated your parameter that you want to be assisted, then declare a factory (can be abstract or interface) inside your concrete implementation that implements another Factory
interface that returns the interface you want to bind, but now you return your concrete implementation by overriding the interface Factory return type
interface RequestSetFactory {
fun create(address: String): RequestSet
}
class MyRequestSet @AssistedInject constructor(
@Assisted private val deviceAddress: String,
) : RequestSet {
@AssistedFactory
abstract class Factory : RequestSetFactory {
abstract override fun create(address : String): MyRequestSet
}
//.... impl code
}
In the binding module just add the mapping as:
@Module
abstract class RequestSetProviderBindingModule {
@Binds
@IntoMap
@StringKey(Key.MY_KEY) //<-- change this
abstract fun bindMyRequests(my: MyRequestSet.Factory): RequestSetFactory
}
Declare the provider map in your instance factory as:
typealias RequestSetProviderMap = Map<String, @JvmSuppressWildcards Provider<RequestSetFactory>>
Upvotes: 0