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

  • 51
    いいね
  • 4
    コメント
この記事は最終更新日から1年以上が経過しています。

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