久々に Dagger を使うとかなりの不自由感。
細かく咀嚼しないと全体は理解できない感じなので、まずはこのタイトルから。
少し、細かくシリーズ化してみますが。
👉 Dagger 2 @Binds vs @Provides - Elye - Medium
👉 Why is @Binds different from @Provides? - Frequently Asked Questions
Android が登場してから10年程度ですが、経緯というか、伝統というか、歴史というか。
そういうの嫌いだけど、そういうのを理解しようとしないと、その対象に対しての初心者は辛い時期になってるのだろうと思う。
Toolbar / ActionBar もそうでしょう?
シンプルにググるだけでは良いコードには辿り着けません、
この、Dagger2 2019-08-15現在 もそれと同じ雰囲気なのでしょう。
以下、上記リンクより引用。
@Binds methods must have only one parameter whose type is assignable to the return type
So only a single parameter, and the type return is typically the interface of the given parameter object.
Having said that, the other tips is consider using static function for @Provides which would help also reduce some generated codes.
@Bindsメソッドには、戻り値の型に割り当て可能な型のパラメーターが1つだけ必要です
そのため、1つのパラメーターのみが返され、型の戻り値は通常、指定されたパラメーターオブジェクトのインターフェイスです。
そうは言っても、他のヒントは、生成されるコードを減らすのに役立つ「@Provides」の「静的」関数の使用を検討することです。
@Provides, the most common construct for configuring a binding, serves three functions:
1. Declare which type (possibly qualified) is being provided — this is the return type
2. Declare dependencies — these are the method parameters
3. Provide an implementation for exactly how the instance is provided — this is the method body
While the first two functions are unique and critical to every @Provides method, the third can often be tedious and repetitive. So, whenever there is a @Provides whose implementation is simple and common enough to be inferred by Dagger, it makes sense to just declare that as a method without a body (an abstract method) and have Dagger apply the behavior.
But, if we were to just say that abstract @Provides methods should be treated as we do for @Binds methods, the specification of @Provides would basically be two specifications with a bunch of conditional logic. For example, a @Provides method can have any number of parameters of any type, but a @Binds method can only have a single parameter whose type is assignable to the return type. Separating those specifications makes it easier to reason about correctness because the annotation determines the constraints.
バインディングを構成するための最も一般的な構成要素である@Providesは、3つの機能を提供します。
1.どのタイプ(修飾されている可能性がある)が提供されているかを宣言します—これは戻りタイプです
2.依存関係を宣言します—これらはメソッドのパラメーターです
3.インスタンスが提供される方法を正確に実装します—これはメソッド本体です
最初の2つの関数は一意であり、「すべての@Provides」メソッドにとって重要ですが、3番目の関数は多くの場合、退屈で反復的です。そのため、実装がDaggerによって推論されるほど単純で一般的な@Providesが存在する場合はいつでも、それを本体のないメソッド(抽象メソッド)として宣言し、Daggerに動作を適用させることが理にかなっています。
しかし、abstract @Provides methodsを@Binds methodsのように扱うべきであると言うだけなら、@Providesの仕様は基本的に条件付きロジックの束を持つ2つの仕様になります。たとえば、@Provides methodは、任意の型の任意の数のパラメーターを持つことができますが、a @Binds methodは、型が戻り型に割り当て可能な単一のパラメーターのみを持つことができます。これらの仕様を分離すると、注釈によって制約が決定されるため、正確性についての推論が容易になります。
まとめ
kotlin でいうとこの
1. 基本 @Binds を使う。
2. Application 起動の object の場合(static な singleton メソッドの場合)は @Provides を使う。
という理解でいいのか。
👉 ATM - Dagger Tutorial