Dagger와 주입

6122 단어

평론 주입의 이해


주입


주입은 일반적으로 하나의 프로젝트에 완전한 프레임워크로 삽입되어 새로운 스텔스 대상 초기화 방식을 제공한다. 설정 파일, 주석 등을 통해 지정한 변수 대상은 이 주입 프레임워크가 초기화 작업을 책임지고 (신설이나 단례 등) 적합한 특정 실현 클래스 대상을 제공한다. 코드적으로 주입 대상을 설명하는 클래스는 이 필드를 초기화하지 않아도 바로 사용할 수 있다.

주입 과정

  • 인터페이스 정의
  • 인터페이스 구현 클래스 제공
  • 구성 구현 클래스를 인터페이스 대상으로 공급자
  • 주입 프레임워크를 통해 주입에 필요한 주입 유형 필드 변수 초기화
  • 장점


    주입 모드는 정적 설정에 가까운 방식으로 자동으로 (new) 대상을 구성하고 호출자에게 사용하도록 한다. 번거로운 대상 초기화 코드를 간소화하고 숨기며 대상 초기화 단계의 격리를 제공하여 더욱 순수한 인터페이스 프로그래밍을 실현하고 인터페이스형 변수를 주입함으로써 최종적으로 대상 변수, 방법 호출과 구체적인 실현 클래스 간의 완전한 결합을 완성한다.따라서 다른 호출 클래스 코드를 수정하지 않고 실현 클래스를 완전히 투명하게 교체할 수 있으며 단일 테스트에 더욱 적합한 Mock 입구를 제공할 수 있다.
    특히 목표 대상이 비교적 범용될 때 중복적인 템플릿 구조 코드를 대량으로 줄일 수 있어 은식 자동 조립 공장에 해당한다.

    적용 장면


    주입 프레임워크는 자동으로 대상 초기화를 완성하고 보통 정적 방식으로 지정한 설정을 하기 때문에 발생하는 대상은 모두 템플릿 단계의 제품이다.
    주입에 적합한 객체는 다음과 같은 동적 변환 구조 매개변수 값이 필요하지 않은 클래스에 속합니다.
  • 솔리드 클래스
  • 용기류
  • 단일 예제 도구 클래스
  • 결점


    해결 정도가 높을수록 코드의 호출 관계가 모호해지고 IDE 추적을 통해 코드의 논리적 호출 체인을 구체적으로 실현하기 어렵다. 호출 관계는 주입 프레임 내부의 논리적 제어와 사용자에게 숨겨지기 때문에 프로젝트를 인수하는 프로그래머가 코드를 읽기 어렵고 그 중의 전체 호출 체인 관계 도표를 이해하기 어렵다. 또한 코드 디버깅, 재구성에 어려움을 증가시켰다.예측할 수 없는 잠재적 버그를 도입할 수도 있다.

    Dagger


    Square사가 개발한 안드로이드 플랫폼에 대한 주입 프레임워크이 프레임워크를 사용하려면 주입 대상 공장 방법,Module, 목표 주입 클래스의 직접적인 관계를 명확하게 설명해야 한다. 완전한 컴파일을 제공할 때 검증할 수 있으며, 그 어떠한 부족함, 사용하지 않은 주입 귀속도 오류를 보고할 수 있다.

    주요 개념

  • ObjectGraph: 의존과 주입의 관리 핵심 클래스이고 관리 단원은 모델
  • 이다.
  • @Module + @Provides: 주입 가능한 대상을 제공하는 공장 종류와 방법을 설명하는 데 사용
  • @Inject: 주입할 대상 변수를 설명하는 데 사용
  • @Module(injects={class...}):현재 Module 및 대상 주입 클래스 바인딩
  • ObjectGraph.ject: 목표 주입 클래스에서 주동적으로 호출하고 모듈이 제공하는 대상을 주입합니다
  • 사용 방법

  • @Module + @Provides를 사용하여 공장류와 그 공장 방법을 주석하는데 그 중에서 공장 방법은 provide로 시작해야 한다
  • @Inject 주석 필드 대상을 사용하고 Dagger는 ObjectGraph.inject 방법으로 자동 주입
  • (선택 사항) @Inject 주석 클래스 구조기를 사용하여Dagger에서 주입 가능한 대상을 만드는 기본 공장 방법으로 방법 매개 변수는 첨부된 모듈 주입 트리에서 추출
  • ObjectGraph 초기화: ObjectGraph.create(modules...)
  • ObjectGraph를 사용하여 객체 자동 주입: objectGraph.inject(this)
  • ObjectGraph에서 객체 추출: objectGraph.get(class)
  • @Module 선언


    @Module 주석은 임의의 일반 클래스에 사용되며, 이를 Module 클래스로 설명하고, 주입 가능한 대상 (공장 방법) 을 제공하는 일련의 @Provides 주석 방법을 포함합니다.
    @Module에는 다음과 같은 필드가 있습니다.
  • includes = {Modules...}: 기타 Modules(그리고 모든 하위 Modules)를 조합
  • addsTo = class: (선택 사항) 현재 모듈은 ObjectGraph를 통과할 수 있습니다.plus() 방법이 첨부된 목표 숙주류
  • overrides = boolean: 현재 모듈이 성명한 Provide 방법은 다른 모듈의 같은 공장 방법을 덮어쓰고 테스트 또는 개발 환경에만 적용
  • complete = boolean: 현재 모듈에서Provide 방법의 매개 변수는 (includes 및addsTo 목록에 존재하지 않는) 외부 모듈에서 제공해야 할 때false로 성명하고 이 모듈은 추상적인 부류로 확장됨
  • 을 나타낸다.
  • library = boolean: 현재 모듈에 추가적인Provide 방법이 존재하며 목표 injects 대상에 주입할 필요가 없을 때true
  • 로 성명합니다
  • injects = {class...}: 현재 모듈의 적합한 목표 클래스, 이런 클래스는 현재 모듈에서 주입 대상을 제공하고 objectGraph.injectobjectGraph.get 방법
  • 에 사용

    주의

  • @Inject 주석 필드 변수일 때private 또는final
  • 로 성명할 수 없습니다
  • @Inject는 하나의 구조기만 주석할 수 있음
  • @Inject 주석 필드의 대상을 사용하는 클래스에서 구조 함수에 대한 @Inject 주석을 생략할 수 있음
  • 모든 주입점은 @Module(injects)에 열거되어야 합니다
  • Provider 주입


    Provider는 주입 대상을 포장하는 데 사용되며 get () 방법을 호출할 때마다 새로운 대상이 되돌아옵니다.
    Provider 주입을 사용할 때, Provider 포장의 목표 대상인provide 방법을 제공하기만 하면, Provider는 Dagger에서 자동으로 봉인하여 제공된다.
    @Inject Provider filterProvider;
    
    void method(){
        filterProvider.get();
        ...
    }
    
     
    
    @Provides
    public ObjInf provideObj(Provider p) {
        return p.get();
    }
    

    읽기 어려운 코드가 쉽게 생성되기 때문에, Dagger는 남겨진 코드 문제 등 비정상적인 상황에 대처하지 않는 한 Provider를 남용하는 것을 추천하지 않는다.

    참고 자료


    Dagger-square Dagger-안드로이드의 의존 주입 프레임워크

    Dagger2


    Google은 Dagger1을 기반으로 2차 개발한 주입 프레임워크를 사용하며, 현재 Square에서 Dagger1의 새로운 버전을 대체하는 데 사용될 것을 승인했습니다.

    Dagger1과 비교


    Dagger1
  • 장점: 컴파일링 시 자동 생성 코드를 검증하고 완전한 호출 추적을 제공하며 디버깅을 편리하게 한다(Guice와 비교)
  • 단점: 자동 생성 코드의 질이 낮고 읽기 어렵습니다. 반사 대상의 의존도를 사용하는 효율이 낮습니다. 생성 과정은 맵식 API(@Module 설정 등)를 추적할 수 없습니다. Scope는 @Singleton
  • 만 지원합니다.
    Dagger2
  • 장점: 반사를 전혀 사용하지 않고 추적이 가능하며 자동으로 코드를 생성하여 읽을 수 있도록 API를 간소화하여 성능을 향상시킵니다. Dagger1보다 13% 빠른 지원 방법 주입 사용자 정의 Scope 지원 스텔스null 검사 제공(@Nullable 제외)
  • @Module


    모든 @Module는complete =false &library =true로 정의되며,complete,library,addsTo,injects,staticInjections의 속성 지정이 필요하지 않으며, 컴파일할 때 느슨한 검증을 사용합니다.
    또한 오버라이드와 정적 주입은 더 이상 지원되지 않습니다.동일한 기능을 수행하려면 파생 대상 Module 하위 클래스에서 새 객체를 제공하는 것을 고려할 수 있습니다.
    includes 속성은 여전히 사용할 수 있습니다.

    ObjectGraph


    ObjectGraph는 Module의class나 실례 대상을 통해 초기화하여 만들 수 있습니다.
    ObjectGraph.create(ModuleOne.class, ModuleTwo.class, new ModuleThree("hello!"));
    

    Component


    Component는 Modules를 조직하고 ObjectGraph를 구축하는 또 다른 방식을 제공합니다.Component 인터페이스에서Dagger1에서 @Module (injects) 를 설명하는 것과 같은 방법을 정의합니다.
    @Component(
      modules = {
        ModuleOne.class,
        ModuleTwo.class,
        ModuleThree.class,
      }
    )
    interface MyComponent {
      /* Functionally equivalent to objectGraph.get(Foo.class). */
      Foo getFoo();
      /* Functionally equivalent to objectGraph.get(Bar.class). */
      Bar getBar();
      /* Functionally equivalent to objectGraph.inject(aBaz). */
      Baz injectBaz(Baz baz);
    }
    
    //   Component
    // Dagger2   MyComponent  ,  Dagger  
    MyComponent myComponent = DaggerMyComponent.create();
    
    //   Module  ,  Component
    MyComponent myComponent = DaggerMyComponent.builder()
        // ModuleOne and ModuleTwo don't need to be set explicitly
        .moduleThree(new ModuleThree("hello!"))
        .build();
    

    주의


    주입점과provide 방법은 @Nullable을 지정해야 합니다. 그렇지 않으면 컴파일할 때null 검증이 실패할 때 오류가 발생합니다.

    참고 자료


    Dagger2 - Google github의 강력한 Dagger2
    기초 의존 주입 프레임 편 dagger2 당신 을 사랑 하지 않 았 다: 중점 개념 설명, 융합 편 dagger2 당신 을 사랑 하지 않 았 다: 종결 편
    [텐센트 Bugly 건품 공유] Butter Knife를 깊이 이해하고 당신의 프로그램이 코드를 쓰는 것을 배울 수 있도록 하세요.

    좋은 웹페이지 즐겨찾기