如何使用Dagger2和Kotlin在AndroidStudio的其他项目模块中实现接口存储库

如何使用Dagger2和Kotlin在AndroidStudio的其他项目模块中实现接口存储库,android,android-studio,kotlin,dagger-2,dagger,Android,Android Studio,Kotlin,Dagger 2,Dagger,我希望能够在AndroidStudio的其他项目模块中获得用户位置的界面的两种不同的反应式实现 因此,具体来说,可以使用gms,也可以只使用本机android LocationManager 这是我的存储库界面: interface RxLocationRepository { @SuppressLint("MissingPermission") fun onLocationUpdate(): Observable<Location> fun stopLocationUpdate

我希望能够在AndroidStudio的其他项目模块中获得用户位置的界面的两种不同的反应式实现

因此,具体来说,可以使用gms,也可以只使用本机android LocationManager

这是我的存储库界面:

interface RxLocationRepository {

@SuppressLint("MissingPermission")
fun onLocationUpdate(): Observable<Location>

fun stopLocationUpdates()
}
它使用了一些Dagger组件,为他提供了不同对象的所有实现。 所以我想移动这个LocationClient,或者在location_核心项目模块中将其抽象化,并在AndroidStudio的每个location_gms和location_本地项目模块中移动它的实现

因此,它们中的LocationClient类将提供此RxRepository的不同实现。 目前,在每个location_gms和location_native项目模块中,我只有一个实现类,它以自己的方式实现了repository rxLocationRepository(我从上面编写的实现中移动)

问题是我不知道如何用匕首来管理这一切。 现在我在我的位置_core中使用类似的匕首,这是位置组件:

@Singleton
@Component(modules = arrayOf(LocationModule::class))
interface LocationComponent{
fun locationClient(): LocationClient

@Component.Builder
interface Builder {
    @BindsInstance
    fun context(context: Context): Builder
    fun build(): LocationComponent
 }

}
及其模块:

@Module
class LocationModule {

//some stuff

    @Provides
@Singleton
fun providesRxLocationRepository(
                                 reactiveLocationProvider: ReactiveLocationProvider,
                                 reactiveLocationRequest: LocationRequest,
                                 @Named("CONFIG_LOCATION_USE_NATIVE_API")isUsingLocationNativeApi: Boolean,
                                 locationManager: LocationManager,
                                 @Named("CONFIG_LOCATION_GEO_EVENTS_DISTANCE_METERS")geoEventsDistanceMeters: Int,
                                 @Named("CONFIG_LOCATION_GEO_EVENTS_INTERVAL_SECONDS")geoEventsIntervalSeconds: Int
): RxLocationRepository = RxLocationRepositoryImpl(
        reactiveLocationProvider,
        reactiveLocationRequest,
        isUsingLocationNativeApi,
        locationManager,
        geoEventsDistanceMeters,
        geoEventsIntervalSeconds)

//some other stuff
}
那么,如何在每个模块中编写实际的LocationClient—location_gms和location_native?如何使用Dagger提供rxLocationRepository的实现,它位于每个location_gms和location_原生项目模块中,这样我就可以在我的location_核心模块中使用接口rxLocationRepository,而不必为它的实现而烦恼,因为它将位于每个项目模块中

当然,我必须指出,我想这3个模块永远不会在一起,我想每个构建变体中都会有2个模块。 因此,我必须在location_核心项目模块build.gradle中摆脱对google服务的依赖

更新

如何在我的位置_core中没有匕首组件,我在测试中使用它,如:

val component=DaggerLocationTestInstrumentalComponent.builder().context(InstrumentationRegistry.getContext()).build()
val database=component.testDatabase()
val locationManager=component.locationClient().nexoLocationManager

当然,我必须指出,我想这3个模块永远不会在一起,我想每个构建变体中都会有2个模块

这是需要注意的要点。您的组件定义不应位于
位置\u core
内。相反,它应该站在“消费者”一边。所谓消费者,我指的是实际使用位置的第四个模块。让我们称之为
consumer\u模块

我将如何完成这项任务

  • location\u gms
    location\u native
    都应包含具有不同实现的
    LocationModule
    。对两个模块中的
    LocationModule
    使用相同的软件包名称

  • 消费模块
    包含
    定位组件
    。根据构建变量,它将从
    location\u gms
    location\u native
    解析为
    LocationModule


  • 另一种方法与
    LocationModule
    相同,但在
    consumer\u module
    two
    LocationComponent
    中创建。每个版本都有不同的版本。在这种方法中,您不必为
    LocationModule

    保留相同的包名,但是我如何在location\u core中的LocationManager中实际注入并获得RxRepository接口的实际实现呢?我正在把它传递给我的构造函数。另外,请参见我更新的问题。实际上,它应该只在这3个模块中完成,而不是在第4个模块中。在这种情况下,请使用我描述的“另一种方法”。创建不同版本的
    LocationComponent
    ,每个版本具有不同的风格(例如构建变体)。一种风格取决于
    location\u gms
    ,另一种风格取决于
    location\u native
    我想更好的解决方案是您建议实际使用消费者模块,谢谢
    @Singleton
    @Component(modules = arrayOf(LocationModule::class))
    interface LocationComponent{
    fun locationClient(): LocationClient
    
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun context(context: Context): Builder
        fun build(): LocationComponent
     }
    
    }
    
    @Module
    class LocationModule {
    
    //some stuff
    
        @Provides
    @Singleton
    fun providesRxLocationRepository(
                                     reactiveLocationProvider: ReactiveLocationProvider,
                                     reactiveLocationRequest: LocationRequest,
                                     @Named("CONFIG_LOCATION_USE_NATIVE_API")isUsingLocationNativeApi: Boolean,
                                     locationManager: LocationManager,
                                     @Named("CONFIG_LOCATION_GEO_EVENTS_DISTANCE_METERS")geoEventsDistanceMeters: Int,
                                     @Named("CONFIG_LOCATION_GEO_EVENTS_INTERVAL_SECONDS")geoEventsIntervalSeconds: Int
    ): RxLocationRepository = RxLocationRepositoryImpl(
            reactiveLocationProvider,
            reactiveLocationRequest,
            isUsingLocationNativeApi,
            locationManager,
            geoEventsDistanceMeters,
            geoEventsIntervalSeconds)
    
    //some other stuff
    }