TL;博士你忘了或者添加@Inject
到您的構造函數,以便匕首可以使用構造器注入到提供對象,或者你需要一些方法在一個你創建或綁定對象的模塊。
這是怎麼回事?
仔細看看錯誤消息:它聲明您嘗試請求依賴項,但匕首無法提供或創建它。它根本不知道如何去做,因爲如果沒有@Inject構造函數或者來自@Provision-Annotated方法,就不能提供。
仔細看錯誤消息顯示類(一)您試圖提供和組件(B)需要它。
com.example.MyDependency (a) is provided at
com.example.MyComponent.myDependency() (b)
你必須確保(B)可以創建或提供(一),以解決您的問題。
它看起來有點複雜,如果你試圖在別的地方注入你的依賴關係,但你仍然可以看到在這種情況下構造函數注入缺少依賴關係的事件—的完整堆棧。你試圖提供的類(a)和Dagger試圖注入的位置(b)。它也告訴你哪個依賴類創建的地方是(c),並且再次提供了組件(d),它提供的失敗(a)。
com.example.MyDependency cannot be provided without an @Inject constructor or from an @Provides-annotated method.
com.example.MyDependency (a) is injected at
com.example.DependentClass.(dependency) (b)
com.example.DependentClass is provided at (c)
com.example.MyComponent.myDependency() (d)
同樣適用於這裏:確保(d)知道如何提供(一),你是好去。
我該如何解決這個問題?
看看上面的錯誤。確保你明白其中它發生和什麼你試圖注入。然後告訴Dagger如何提供你的對象。
的@Inject構造
由於錯誤狀態,您嘗試使用MyDependency
但MyComponent
不知道該怎麼做。如果我們看一下例子就變得很清楚,爲什麼:
class MyDependency {}
類有沒有@Inject
註釋構造!而且組件中沒有其他模塊,所以Dagger沒有什麼可以做的。
如果你想使用構造函數注入,你可以只需添加一個@Inject
註釋構造函數並完成。 Dagger會看到這個構造函數並知道如何創建你的類。
class MyDependency {
@Inject
MyDependency() { /**/ }
}
這就是您在使用構造函數注入時必須要做的所有事情。
從@提供註解方法
錯誤信息指出第二個選項,它允許您提供一個對象,如果你不希望—或無法—使用構造函數注入做。您還可以將@Provides
帶註釋的方法添加到模塊並將此模塊添加到您的組件。
@Module
class MyModule {
@Provides
MyDependency provideMyDependency() {
return new MyDependency();
}
}
@Component(modules = MyModule.class)
interface MyComponent {
MyDependency myDependency();
}
這樣Dagger可以使用你的模塊來創建並提供依賴。它比使用構造函數注入要多一點樣板,但是對於需要進一步設置或者沒有註釋構造函數的所有東西,第三方庫,如Retrofit,OkHttp或Gson。
還有其他方法可以從組件中提供依賴關係。 A @SubComponent
可以訪問其父項依賴項,並且組件依賴項可以將其某些依賴項公開給其依賴項組件。但是在某些時候,Dagger提供的一切都需要有一個@Inject
構造函數或一個提供它的模塊。
但我確實加了MyDependency
!
密切關注細節。當您僅提供實現時,您可能正在使用接口,或者當Dagger僅知道子類時嘗試使用父類。
也許你添加了自定義@Qualifier
或使用了@Named("typeA")
。匕首這是一個完全不同的對象!仔細檢查你是否實際提供並請求相同的依賴關係。
讀取錯誤,並確保你要麼有一個@Inject
註釋構造,具有@Provides
方法提供某種類型,或者,做了父組件的模塊。
如果我想爲我的界面提供實現,該怎麼辦?
一個簡單的例子,如以下顯示如何一個類繼承了另一個問題:
class MyDependency extends MyBaseDependency {
@Inject MyDependency() { super(); }
}
這將通知匕首約MyDependency
,但不是MyBaseDependency
。
如果您有一個類實現接口或擴展超類,則必須聲明該類。如果您提供MyDependency
這並不意味着Dagger可以提供MyBaseDependency
。你可以使用@Binds
告訴Dagger你的實現,並在需要超類的時候提供它。
@Module
interface MyModule {
@Binds
MyBaseDependency provideMyBaseDependency(MyDependency implementation);
}
寫得很好! –
使用Binds設置接口的實現時,是否仍然需要爲接口創建@Provides方法來返回實現? – jonney
@jonney不,你不需要額外的@ @提供。 '@ Binds'也將提供實現/接口。 –