我有我想注入的NetworkDataSource
。我想使用构造函数注入,因为我是此类的所有者:
public class NetworkDataSource {
@Inject
public NetworkDataSource(String url, String method) {
this.url = url;
this.method = method;
}
}
问题是,当触发Service
时,会从BroadcastIntent
中检索此构造函数的参数(即依赖项)。因此,我的问题是,如何将从Service
检索到的这些参数提供给我的NetworkDataSource
构造函数注入?
Service
看起来像这样:
public class Service extends IntentService {
// I would like to inject NetworkDataSource
//@Inject
//NetworkDataSource netWorkDataSource;
public String url;
public String method;
@Override
protected void onHandleIntent(Intent workIntent) {
url = workIntent.getStringExtra("url");
method = workIntent.getStringExtra("method");
}
............
............
networkDataSource.myMethod();
}
谢谢。
答案 0 :(得分:2)
这是一个棘手的问题,因为您会认为Dagger主要解决了现在不再需要引入“ Factory”类来重新配置行为的问题。
但是,实际上,您仍然仍然需要使用“ Factory”类来创建具有动态构造函数参数的对象,这些对象是在运行时获取的。
所以:
public class NetworkDataSource {
@Inject
public NetworkDataSource(String url, String method) {
this.url = url;
this.method = method;
}
}
将会
@Singleton
public class NetworkDataSourceFactory {
private final OkHttpClient okHttpClient;
private final Gson gson;
@Inject
public NetworkDataSourceFactory(OkHttpClient okHttpClient, Gson gson) {
this.okHttpClient = okHttpClient;
this.gson = gson;
}
public NetworkDataSource create(String url, String method) {
return new NetworkDataSource(okHttpClient, gson, url, method);
}
}
然后,您现在可以注入NetworkDataSourceFactory
,并在收到参数时创建一个NetworkDataSource
:
@Inject NetworkDataSourceFactory factory;
....
networkDataSource = factory.create(url, method);
假设您可以使用AutoFactory
帮助创建工厂,但是我还没有使用过,我只知道它存在于这个特定用例中。
编辑:您也可以签出https://github.com/square/AssistedInject来解决此问题。
答案 1 :(得分:1)
让我们一步一步地做。 (所有代码都将位于kotlin
中)
首先,您拥有
class NetworkDataSource(val url: String, val method: String)
,并且需要使用匕首 module 来创建
@Module
class NetworkModule {
@Provides
fun dataSource(@Named("url") url: String,
@Named("method") method: String): NetworkDataSource {
return NetworkDataSource(url, method)
}
}
之后,您需要使用匕首 component
@Component(modules = [NetworkModule::class])
interface NetworkComponent {
fun inject(service: Service)
@Component.Builder
interface Builder {
@BindsInstance
fun url(@Named("url") url: String): Builder
@BindsInstance
fun method(@Named("method") method: String): Builder
fun build(): NetworkComponent
}
}
现在您可以将其注入Service
class Service : IntentService {
@Inject
lateinit var netWorkDataSource: NetworkDataSource
override protected fun onHandleIntent(workIntent: Intent) {
val url = workIntent.getStringExtra("url")
val method = workIntent.getStringExtra("method")
DaggerNetworkComponent.builder()
.url(url)
.method(method)
.build()
.inject(this)
}
}
就是这样。
答案 2 :(得分:0)
我认为这是不可能的,因为您只能在dagger 2中提供可用的数据源,所以我建议您在这种情况下不要使用依赖注入,因为在构建项目时您的数据不可用