daggerサンプルコードの最初から、メソッドなどの関係が分からなかったので、理解しようと頑張った
なんとなく勉強会などで説明を聞いていて
DIとかよりまず処理の流れがよく分かっていませんでした。。
@Moduleのついているクラス@Providesがついているメソッドを使うと@Injectのところに入れてくれるとかは聞いていた
public class MainActivity extends Activity{ @Inject Test test; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); ObjectGraph.create(new TestModule()).inject(this); } } @Module(injects = MainActivity.class) public class TestModule { @Provides Test provideTest() { return new Test(); } }
こんなイメージだった
これだとMainActivity.testに入れる変数をTestModuleから提供される感じだった
そんな感じで公式のdaggerのサンプルを読もうとした
サンプルコードの最初はこういう感じ
public class CoffeeApp implements Runnable { @Inject CoffeeMaker coffeeMaker; @Override public void run() { coffeeMaker.brew(); } public static void main(String[] args) { ObjectGraph objectGraph = ObjectGraph.create(new DripCoffeeModule()); CoffeeApp coffeeApp = objectGraph.get(CoffeeApp.class); coffeeApp.run(); } }
このmainを実行する
CoffeeMakerはこうなっている
class CoffeeMaker { @Inject Lazy<Heater> heater; // Don't want to create a possibly costly heater until we need it. @Inject Pump pump; public void brew() { heater.get().on(); pump.pump(); System.out.println(" [_]P coffee! [_]P "); heater.get().off(); } }
普通に考えるのがDripCoffeeModuleの中に、CoffeeApp.coffeeMakerに変数を入れる@Providesが書いてあるとか思うでしょう?
でも
@Module( injects = CoffeeApp.class, includes = PumpModule.class ) public class DripCoffeeModule { @Provides @Singleton Heater provideHeater() { return new ElectricHeater(); } }
Heaterなどは提供してくれる処理があるけど、 PumpModuleなどをたどっていってもCoffeeMakerを提供してくれる処理はないです
daggerはInjectって書いてあるところのクラスを勝手にnewして入れてくれるっぽいです。
つまりdaggerはobjectGraph.getや@Providesが付いているメソッドの引数などでオブジェクトが必要になったタイミングで以下のように動くみたいです
if @Moduleが付いているクラス and @Providerの付いている返り値がCoffeeAppのメソッドがある: それを使って作る else if CoffeeAppに@Injectが付いているコンストラクタがある: それを使って作る else : new CoffeeApp();#(CoffeeAppのクラスの中には@Injectがついているメンバ変数を含んで、injects=CoffeeApp.classのModuleが必要)
こんなイメージです
サンプルコード
public class MyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); ObjectGraph.create(new TestModule()).get(Test.class).hello(); } } @Module(injects = Test.class) public class TestModule { @Provides public SayHello provideSayHello() { return new SayHello(); } } public class Test { public Test(){ System.out.println("Test created"); } @Inject SayHello sayHello; public void hello(){ sayHello.hello(); } } public class SayHello { void hello(){ System.out.println("hello"); } }
Test created hello
間違いなどがありましたらご指摘ください