#java #android #kotlin #dependency-injection #dagger-2
#java #Android #котлин #внедрение зависимостей #кинжал-2
Вопрос:
Привет, у меня есть класс PdfTicketStorage, в котором есть конструктор, который принимает 2 параметра, я добавил @Inject в конструктор, а также в MockServiceOrderModule. но я получаю сообщение об ошибке
MockAppComponent.java:48: error: [Dagger/MissingBinding] java.lang.String cannot be provided without an @Inject constructor or an @Provides-annotated method.
полная ошибка
/home/circleci/code/app/src/androidTest/java/com/xx/xxx/test/injection/components/MockAppComponent.java:48: error: [Dagger/MissingBinding] java.lang.String cannot be provided without an @Inject constructor or an @Provides-annotated method.
public interface MockAppComponent extends AppComponent {
^
java.lang.String is injected at
com.xxx.xx.test.injection.modules.MockServiceOrderModule.providePdfTicketStorage(cloudStorageBucket, …)
com.xxx.xx.printing.storage.PdfTicketStorage is injected at
com.xxx.xx.clean.offline.OfflineHelper(…, pdfTicketStorage, …)
com.xxx.xx.clean.offline.OfflineHelper is injected at
com.xxx.xx.clean.offline.repository.OfflineUserApiRepository(…, offlineHelper)
com.xxx.xx.clean.offline.repository.OfflineUserApiRepository is injected at
com.xxx.xx.clean.florder.data.repository.flOrderRepository(offlineUserApiRepository, …)
com.xxx.xx.clean.florder.data.repository.flOrderRepository is injected at
com.xxx.xx.test.scenarios.BaseScenario.flOrderRepository
com.xxx.xx.test.scenarios.BaseScenario is injected at
com.xxx.xx.test.injection.components.MockAppComponent.inject(com.xxx.xx.test.scenarios.BaseScenario)
The following other entry points also depend on it:
com.xxx.xx.test.injection.components.MockAppComponent.inject(com.xxx.xx.test.scenarios.VehicleTakeoverScenario)
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.activities.MainActivity) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.fragments.fller.florder.BaseflOrderFragment) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.fragments.fller.florder.BaseflOrderDataFragment) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.fragments.fller.florder.flOrderDataFragment) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.fragments.fller.florder.flOrderSummaryFragment) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.fragments.fller.florder.flOrderDeallocationFragment) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.clean.orderslist.serviceorders.view.ServiceOrderListFragment) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.fragments.fller.florder.ServiceOrderViewFragment) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
com.xxx.xx.injection.components.ActivityComponent.inject(com.xxx.xx.clean.orderslist.serviceorders.view.ServiceOrderAdapter) [com.xxx.xx.test.injection.components.MockAppComponent → com.xxx.xx.injection.components.ActivityComponent]
and 31 others/home/circleci/code/app/src/androidTest/java/com/xx/xxx/test/injection/components/MockAppComponent.java:48: error: [Dagger/MissingBinding] java.lang.String cannot be provided without an @Inject constructor or an @Provides-annotated method.
PdfTicketStorage
@PerApp
public class PdfTicketStorage {
private final String cloudStorageBucket;
private final Lazy<OfflineHelper> offlineHelper;
@Inject
public PdfTicketStorage(String cloudStorageBucket, Lazy<OfflineHelper> offlineHelper) {
this.cloudStorageBucket = cloudStorageBucket;
this.offlineHelper = offlineHelper;
}
}
OfflineHelper
@PerApp
class OfflineHelper @Inject constructor(
private val app: App,
private val settings: Settings,
private val pdfTicketStorage: PdfTicketStorage,
@Named("default") private val gson: Gson
)
MockServiceOrderModule
@Module
public class MockServiceOrderModule {
@Provides @PerApp
PdfTicketStorage providePdfTicketStorage(String cloudStorageBucket, Lazy<OfflineHelper> offlineHelper) {
return new PdfTicketStorage(cloudStorageBucket, offlineHelper);
}
}
Не могли бы вы подсказать, что я здесь делаю не так, пожалуйста
ваши предложения о том, как я могу решить эту проблему, пожалуйста, это было бы очень полезно
спасибо R
Комментарии:
1. Похоже, вы вводите строку где-то внутри
MockServiceOrderModule
. Либо укажите строку в модуле, либо избегайте ее введения.2. привет, когда вы говорите, избегайте его введения? что вы имели в виду под этим, удалите Inject из ` @Inject public PdfTicketStorage(строка cloudStorageBucket, ленивый<OfflineHelper> offlineHelper) { this.cloudStorageBucket = cloudStorageBucket; this.offlineHelper = offlineHelper; }`
Ответ №1:
Ациклический граф Dagger не знает, как указать тип String
, в случае String cloudStorageBucket
. Есть два решения:
- Либо создайте другой
@Provides
дляString
. Это не рекомендуется, так как вы столкнетесь с проблемой, если потребуется другойString
тип. - (Рекомендуется) Отметьте
@Provides
в 1 с@Named("cloudStorageBucket")
помощью .
Вы также можете использовать @assisted-inject
, если это String
будет предоставлено во время выполнения.
Комментарии:
1. Привет, @Karan ты имел в виду это из 2-го рекомендуемого варианта « @Provides @PerApp PdfTicketStorage providePdfTicketStorage(@Named(«по умолчанию») Строка cloudStorageBucket, Lazy<OfflineHelper> offlineHelper) { возвращает новый PdfTicketStorage(cloudStorageBucket, offlineHelper); }«
2. Что происходит прямо сейчас, так это то, что вы просите dagger предоставить вам экземпляр String из своего графика. Если у вас есть provides, которые возвращают строку, то dagger вернет ее. Но причина, по которой хорошей идеей было бы назвать эту строку, заключается в том, что в будущем вам может потребоваться предоставить больше строковых зависимостей.
Ответ №2:
Прежде всего, когда вы уже предоставляете объект здесь, в этом модуле dagger:
@Module
public class MockServiceOrderModule {
@Provides @PerApp
PdfTicketStorage providePdfTicketStorage(String cloudStorageBucket, Lazy<OfflineHelper> offlineHelper) {
return new PdfTicketStorage(cloudStorageBucket, offlineHelper);
}
}
Вам не нужно использовать внедрение конструктора в PdfTicketStorage
классе. Вы можете просто ввести объект и использовать его следующим образом:
@PerApp
public class PdfTicketStorage {
@Inject
public PdfTicketStorage pdfTicketStorage;
}
Но также вы должны убедиться, что строка также указана в модуле dagger. Не знаете, зачем вам нужно указывать строку в модуле dagger?