Dagger2 활용을 위하여
- 기본을 공부하기에는 이곳 만큼 좋은곳은 없는거 같습니다.
- http://pluu.github.io/blog/android/2017/01/13/android-dagger/
0. 내가 생각하는 시나리오
- 기능이 있거나 구조체로 사용하는 클래스를 만든다.
- 어노테이션을 이용해서 원하는곳에서 사용 가능하게 한다.
- 싱글톤으로 구현된 스태틱 클래스를 들을 편하게 가져다 쓰는 느낌으로
1. 그래들 설정
- 
    다른곳은 너무 어렵게 되어 있습니다. compile 'com.google.dagger:dagger:2.7' annotationProcessor 'com.google.dagger:dagger-compiler:2.7'
2. 따라하기
- 개 이름이 있는 클래스를 생성한다.
java
    public class Dog {
      public String getName() {
          return "멈뭄미";
      }
    }
 
- 개 클래스를 제공할 모듈을 만든다.
- 개 클래스를 반환한 함수를 메소드를 만들고 어노테이션으로 @Provides 추가 한다.
- 클래스에는 @Module 을 어노테이션을 입력한다.
java
    @Module
    public class SampleModule {
        @Provides
        Dog provideDog() {
            return new Dog();
        }
    }
 
- 모듈을 사용할 인터페이스를 만든다.
- inject 메소드를 만들어야 한다.
java
    @Component(modules = SampleModule.class)
    public interface SampleComponent {
        void inject(MainActivity activity);
    }
 
- 액티비티에 의존성을 주입시켜 개 이름을 출력해 보자
- 아래 내용을 진행하기 전에 make 를 한번 진행해야 DaggerSampleComponent 를 사용할 수 있습니다.
- new Dog 를 안했지만 “멈뭄미” 를 출력 가능합니다.
- 즉 Dog 를 주입 시켰습니다.
- 가장 기본 적인 필드 인젝션 입니다.
```java public class MainActivity extends AppCompatActivity { // 인스턴스가 주입되는 필드 @Inject Dog dog;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      // SampleComponent로부터 DaggerSampleComponent 가 자동 생성되므로, 그것을 사용하여 SampleComponent를 만듭니다.
      SampleComponent component = DaggerSampleComponent.builder()
              // 사용하는 Module 인스턴스를 지정합니다.
              // (여기서 deprecated 될 수 있지만, 일단 모든 코드를 작성하고 빌드하면 사라질 것입니다)
              .sampleModule(new SampleModule())
              .build();
      // 의존 주입을 실행합니다
      component.inject(this);
      String name = dog.getName();
      Log.d("MainActivity", name);
  }
}   ```
- 생성자 인젝션
- 생성자에서 개 클래스를 입력 받기 위해서 아래 처럼 클래스를 작성합니다.
```java public class Owner {
  private Dog dog;
  @Inject
  public Owner(Dog dog) {
      this.dog = dog;
  }
  public String getPetName() {
      return dog.getName();
  }
}   ```
- MainActivity 에서 변경 내용은 아래 처럼 인젝트 내용만 변경해 주면 됩니다.
java
    @Inject
    Owner owner;
 
3. 인터페이스를 이용하여 좀더 편하게 주입을 변경하기
- 지금까지 사용한 것은 구현 클래스였지만, 다음은 interface를 사용하도록 변경합니다.
```java public interface Pet { String getName(); }
public class Dog implements Pet {
  @Override
  public String getName() {
      return "포치";
  }
}
@Module
public class SampleModule {
  @Provides
  Pet providePet() {
      return new Dog();
  }
}
public class Owner {
  private Pet pet;
  @Inject
  public Owner(Pet pet) {
      this.pet = pet;
  }
  public String getPetName() {
      return pet.getName();
  }
}   ```
- 구현 클래스가 아닌 인터페이스로만 의존성을 변경하였습니다.
- 여러가지 컴포넌트를 이용해서 주입을 변경해도 되지만 그래들에서 제공하는 플래버를 이용해 보겠습니다.
4. Build Variants 를 이용해서 주입을 변경해보자
- 테스트 또는 저장소 변경등을 쉽게 할 수 있다.
- 그래들 변경
gradle
    flavorDimensions "mode"
    productFlavors {
        dog {
            dimension "mode"
        }
        cat {
            dimension "mode"
        }
    }
 
- src 폴더 아래 dog/java ,cat/java 폴더 생성(패키지 이름까지 동일하게 처리 해야 한다.)
- View → Tool Windows → Build Variants에서 추가된 내용을 확인 할 수 있다.
- main 폴더의 sampleModule 를 제거 한다.
- cat, dog 폴더에 각각 추가한다.
- 플래버 변경 만으로 원하는 인터페이스 모듈 주입 가능합니다.