Выпуск сборника Dagger2 в котлине
Я пытаюсь научиться внедрять зависимости с помощью Dagger2. Я создал несколько пользовательских областей и Qualifier. Я создал компонент приложения, в который я хотел внедрить определенные глобальные зависимости, а также я создал компонент Activity, который будет возвращать определенные экземпляры на основе контекста действия.
Теперь, когда я пытаюсь внедрить глобальные экземпляры в Activity, я получаю ошибку следующим образом:
e: /home/arifur/source_code/me/myprojects/Learn/studio/Android/kotlin/FirebaseChat/app/build/tmp/kapt3/stubs/debug/com/example/arifur/firebasechatkotlin/dependecies/component/ActivityComponent.:7: ошибка: com.google.firebase.auth.FirebaseAuth не может быть предоставлена без аннотированного метода @Provides- или @Produces. е:
e: открытый абстрактный void inject (@ org.jetbrains.annotations.NotNull () e:
^ e: com.google.firebase.auth.FirebaseAuth вводится в e:
com.example.arifur.firebasechatkotlin.BaseActivity.firebaseAuth e:
com.example.arifur.firebasechatkotlin.MainActivity вводится в e:
com.example.arifur.firebasechatkotlin.dependecies.component.ActivityComponent.inject (р0)w: warning: Ни один процессор не распознал следующие параметры: '[kapt.kotlin.generated]' w:
e: /home/arifur/source_code/me/myprojects/Learn/studio/Android/kotlin/FirebaseChat/app/src/main/java/com/example/arifur/firebasechatkotlin/BaseActivity.kt: (29, 9): не решено ссылка: DaggerActivityComponent e: /home/arifur/source_code/me/myprojects/Learn/studio/Android/kotlin/FirebaseChat/app/src/main/java/com/example/arifur/firebasechatkotlin/FirebaseChatApp.kt: (20, 13): Неразрешенная ссылка: DaggerFirebaseComponent e: /home/arifur/source_code/me/myprojects/Learn/studio/Android/kotlin/FirebaseChat/app/src/main/java/com/example/arifur/firebasechatkotlin/MainActivity.kt (1, 1): при обработке аннотаций произошли некоторые ошибки. Пожалуйста, смотрите сообщения об ошибках выше.
Отборочные
ActivityContext.kt
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class ActivityContext
ApplicationContext.kt
@javax.inject.Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class ApplicationContext
Области применения
ActivityScope.kt
@Scope
@Retention(AnnotationRetention.SOURCE)
annotation class ApplicationScope
ApplicationScope.kt
@Scope
@Retention(AnnotationRetention.SOURCE)
annotation class ApplicationScope
Компоненты
ActivityComponent.kt Используется в классе Injecting Activity.
@ActivityScope
@Component(modules = arrayOf(ActivityModule::class), dependencies = arrayOf(FirebaseComponent::class))
interface ActivityComponent {
fun inject(mainActivity: MainActivity)
}
FirebaseComponent.kt Используется в инъекционном классе приложения.
@ApplicationScope
@Component(modules = arrayOf(ApplicationModule::class, FirebaseAuthModule::class, NetworkModule::class))
interface FirebaseComponent {
fun inject(app: FirebaseChatApp)
}
Модули
ActivityModule.kt
@Module
class ActivityModule(val activity : Activity) {
var mActivityRef : WeakReference<Activity> ;
init {
mActivityRef = WeakReference<Activity>(activity)
}
@Provides
@ActivityScope
@ActivityContext
public fun getActivityContext() : Context? = mActivityRef.get()
@Provides
@ActivityScope
@ActivityContext
public fun getActivityInstance() : Activity? = mActivityRef.get();
@Provides
@ActivityScope
public fun getGlideActivityInstance(@ActivityContext context : Context?) : Glide {
Log.i("activityModule", "Returning activity glide")
return Glide.get(context);
}
}
ApplicationModule.kt
@Module
class ApplicationModule(val app : FirebaseChatApp) {
@ApplicationContext
@ApplicationScope
@Provides
fun provideContext() : Context = app
@ApplicationInstance
@ApplicationScope
@Provides
fun provideApplication() : Application = app
}
FirebaseAuthModule.kt
@Module
class FirebaseAuthModule {
@Provides
@ApplicationScope
public fun getFirebaseAuth() : FirebaseAuth = FirebaseAuth.getInstance()
}
NetworkModule.kt
@Module
class NetworkModule {
@Provides
@ApplicationScope
public fun getGlideApplicationInstance(@ApplicationContext applicationContext: Context ) : Glide {
return Glide.get(applicationContext);
}
}
FirebaseChatApp.kt Класс приложения
class FirebaseChatApp : Application() {
val firebaseComponent: FirebaseComponent by lazy {
DaggerFirebaseComponent
.builder()
.applicationModule(ApplicationModule(this))
.build()
}
@Inject
lateinit var firebaseAuth : FirebaseAuth
@Inject
lateinit var glide : Glide
override fun onCreate() {
super.onCreate()
firebaseComponent.inject(this)
Log.i("application", "APP->Firebase Auth = " + firebaseAuth)
Log.i("application", "APP->Glide = " + glide)
}
public fun getApplicationComponent() : FirebaseComponent = firebaseComponent;
}
BaseActivity.kt Супер классы для всех видов деятельности
public abstract class BaseActivity : AppCompatActivity(){
@Inject
@ActivityScope
protected lateinit var glide : Glide
@Inject
@ApplicationScope
protected lateinit var firebaseAuth : FirebaseAuth //ERROR HERE
protected val activityComponent: ActivityComponent by lazy {
DaggerActivityComponent
.builder()
.activityModule(ActivityModule(this))
.firebaseComponent((this.application as FirebaseChatApp).getApplicationComponent())
.build()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
injectComponent(activityComponent)
}
abstract fun injectComponent(activityComponent: ActivityComponent)
}
MainActivity.kt Где объекты должны быть введены.
class MainActivity : BaseActivity() {
override fun injectComponent(activityComponent: ActivityComponent) {
activityComponent.inject(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Что я должен сделать, чтобы устранить эту ошибку. И как правильно использовать DI. Так как я новичок в этом. Я немного запутался.
1 ответ
Проблема в том, что вы пытаетесь использовать зависимости компонентов, но вы пропустили добавление методов предоставления, которые ваш наследующий компонент может унаследовать.
@ApplicationScope
@Component(modules = arrayOf(ApplicationModule::class, FirebaseAuthModule::class, NetworkModule::class))
interface FirebaseComponent {
fun firebaseAuth() : FirebaseAuth // <-- this is missing
fun inject(app: FirebaseChatApp)
}