Android
AndroidStudio

Androidアプリ開発でDIのDagger2の使用方法

More than 3 years have passed since last update.


Androidアプリ開発でDIのDagger2の使用方法


Dagger2(公式)

http://google.github.io/dagger/


Dagger2の概要

アノテーションで依存性注入を行う。

@Inject: 依存注入して作成したいインスタンスの変数につける

@Module: 具像クラスを作成するメソッド郡の定義クラスにつける。

@Provide: 依存解決するための具像クラスを提供するメソッド。

@Component: どのモジュールを使うかのクラス。


Dagger2のインストール

TOPレベルのgradleのdependenciesに下記を追加


build.gradle

    dependencies {

classpath 'com.android.tools.build:gradle:1.0.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}

allprojectsのrepositoriesに下記を追加

mavenを追加


build.gradle

allprojects {

repositories {
jcenter()
maven { url "https://jitpack.io" }
}
}


アプリレベルのgradleのdependencies に下記を追加


build.gradle

dependencies {

compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'

compile 'com.google.dagger:dagger:2.0'
apt 'com.google.dagger:dagger-compiler:2.0'
provided 'org.glassfish:javax.annotation:10.0-b28'
}



依存注入の例に使うinterface、具像クラスを作成


interface


IRecipientRepository

public interface IRecipientRepository {

public void insert(String name, String email);

public Recipient getRecipient(long id);

}



具像クラス(DBFlowを使用)


RecipientRepository

public class RecipientRepository implements IRecipientRepository{

/**
* Recipientテーブルにインサート
*
* @param String name 氏名
* @param String email メールアドレス
*/

public void insert(String name, String email) {
Recipient recipient = new Recipient();
recipient.name = name;
recipient.email = email;
recipient.is_delivery = 1;
recipient.save();
}

/**
* プライマリーキーで宛先テーブルを検索して取得
*
* @param Long _id ID
*
* @return Recipient recipient Recipientオブジェクト
*/

public Recipient getRecipient(long id) {
Recipient recipient = SQLite.select().from(Recipient.class)
.where(Recipient_Table.id.eq(id)).and(Recipient_Table.is_delivery.eq(1)).querySingle();

String query = SQLite.select().from(Recipient.class)
.where(Recipient_Table.id.eq(id)).and(Recipient_Table.is_delivery.eq(1)).getQuery();

Log.d("DbQuery", query);
return recipient;
}
}



モック


MockRecipientRepository.java

public class MockRecipientRepository implements IRecipientRepository {

public void insert(String name, String email) {
//Mock
}

/**
* 宛先オブジェクトを返すモック
*/

public Recipient getRecipient(long id) {
Recipient recipient = new Recipient();
recipient.id = 100L;
recipient.email = "mock@mock.jp";
recipient.name = "name";
recipient.is_delivery = 1;

return recipient;
}

}



依存注入するインスタンスを返すクラス、メソッドの作成。

クラス名の上に@Moduleアノテーションを記述

具像クラスを返すメソッドに@providersアノテーションを追加


RecipientRepositoryModule

@Module

public class RecipientRepositoryModule {
@Provides
public IRecipientRepository provideRecipientRepository() {
return new RecipientRepository(); //DB使用
//return new MockRecipientRepository(); //モック
}
}


依存注入メソッドの作成。どのmoduleを使うか定義

@componentアノテーションを記述

modulesに@Moduleのファイル名を設定

interfaceを返すメソッドを設定


CRecipientRepository.java

@Component(modules = RecipientRepositoryModule.class)

public interface CRecipientRepository {
IRecipientRepository maker();
}



使い方

注入してインスタンス化する変数に@Injectを追加

Dagger{コンポーネント名}.create.{コンポーネントで定義したinterfaceを返すメソッド}で具像クラスを返す


NewRecipient.java


public class NewRecipient extends AppCompatActivity {

@Inject IRecipientRepository recipientRepository;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_recipient);

this.recipientRepository = DaggerCRecipientRepository.create().maker();
this.recipientRepository.insert("テスト", "test01@android.com");
Recipient recipient = this.recipientRepository.getRecipient(1L);
Log.d("DB",recipient.email);
}
}


RecipientRepositoryModuleでreturnを変えるだけでDBかモックかを切り替えられる

NewRecipientアクティビティは何も変更しなくてOK

外部から注入できた :smile:


参考リンク

Dagger2のインストール

Dependency Injection With Dagger 2 on Android

依存性注入(DI: Dependency Injection)と Dagger 2