-
[Android] Dagger Binding의 종류프로그래밍/Android 2022. 4. 24. 14:03
@Binds
- 모듈 내의 추상 메서드에 붙일 수 있다.
- 반드시 하나의 매개변수만을 가져야 한다.
- @Provides 메소드 대신 좀 더 효율적으로 사용할 수 있다
- 객체를 생성하는 대신 컴포넌트 내의 객체를 파라미터로 받아 바인딩 함으로써 좀 더 효율적으로 사용이 가능하다.@Binds abstract Random bindRandom(SecureRandom secureRandom);
- 이미 바인드된 SecureRandom을 Random 타입으로 한 번 더 바인드 할 수 있다.
@BindsOptionalOf
- 모듈 내의 추상 메소드에 붙일 수 있다.
- 매개변수를 가질 수 없다.
- 특정 타입을 반환형으로 가져야 한다.
- 예외 사항을 던질 수 없다.(Exception)
- @BindsOptionalOf 메소드를 통한 의존성 주입은 Optional 타입 등으로 주입된다.class Foo { @Inject Optional<String> str; //@Nullable 바인딩은 허용하지 않는다. @Inject Optional<Provider<String>> str2; @Inject Optional<Lazy<String>> str3; } @Module abstract class CommonModule { @BindsOptionalOf abstract fun bindsOptionalOfString(): String? } @Module class HelloModule { @Provides fun provideString(): String { return "Hello" } } @Component(modules = [CommonModule::class, HelloModule::class]) interface StrComponent { fun inject(foo: Foo?) } @Component(modules = [CommonModule::class]) interface NoStrComponent { fun inject(foo: Foo?) } @Test fun testFoo() { println("testFoo start") val foo = Foo() DaggerStrComponent.create().inject(foo) println("daggerStrComponent -> ${foo.str?.isPresent}") println("daggerStrComponent -> ${foo.str?.get()}") Assert.assertTrue(foo.str!!.isPresent) Assert.assertNotNull(foo.str!!.get()) DaggerNoStrComponent.create().inject(foo) Assert.assertFalse(foo.str!!.isPresent) println("daggerStrComponent -> ${foo.str?.isPresent}") //println("daggerStrComponent -> ${foo.str?.get()}") //foo.str.get(); 호출시 NoSuchElementException 발생 println("testFoo end") }
testFoo start daggerStrComponent -> true daggerStrComponent -> Hello daggerStrComponent -> false testFoo end
- String이 바인드 되엇을 때는 present, 바인딩 되지 않았을 때는 absent이다
- absent 상태일 때 get()메소드로 값을 참조하면 에러가 발생한다.
- 컴포넌트 내에 Foo가 바인딩 된 적이 있다면 Optional 상태는 present(객체 있음)이고, 그렇지 않다면 absent(객체 없음)이다.@BindsInstance
- 컴포넌트 빌더의 setter 메소드 또는 component factory의 매개변수에 붙일 수 있다.
- 모듈이 아닌 외부로부터 생성된 인스턴스를 builder또는 factory를 통해 넘겨줌으로써 컴포넌트가 해당 인스턴스를 바인드하게 된다.
- 이러한 인스턴스들은 모듈로부터 제공되는 인스턴스와 동일하게 @Inject가 붙은 필드, 생성자, 메소드에 주입될 수 있다.@Component interface BindsComponent { fun inject(foo2: Foo2?) @Component.Builder interface Builder { @BindsInstance fun setString(str: String): Builder? fun build(): BindsComponent } } class Foo2 @Inject constructor() { var str: String? = null @Inject set } @Module class FooModule { @Provides fun provideHello(): String { return "Hello" } } @Test fun testBindsInstance() { println("testBindsInstance start") val hello = "Hello World" val foo2 = Foo2() val component: BindsComponent = DaggerBindsComponent.builder() .setString(hello)!!.build() component.inject(foo2) println(foo2.str) println("testBindsInstance end") }
testBindsInstance start Hello World testBindsInstance end
- Builder를 만들고 @BindsInstance가 붙은 setString setter 메소드를 추가했다.
- 이 메소드에 외부로부터 생성한 객체를 바인드하여 출력하는 예제
- setString에 hello라는 String을 바인드 한 뒤에 Foo 객체에 inject 하여 foo.str 값이 외부로부터 받은 값으로 변경되었다.'프로그래밍 > Android' 카테고리의 다른 글
[Android] Dagger (Module, Provides, Component, Inject) 간단 용어 설명 (0) 2022.04.25 [Android] Dagger2 Multi binding 멀티바인딩(Set, Map) (0) 2022.04.24 [Android]Dagger Singleton과 Reusable 차이 (0) 2022.04.24 [Android] Dagger2 Component Generate 되지 않을 때 with Kotlin (0) 2022.04.24 [Android] SOLID 설계 원칙 (0) 2022.04.19