๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/Android

[Android] Dagger2 - ๋งค๊ฐœ๋ณ€์ˆ˜ ๋™์  ํ• ๋‹น

interfacer_han 2024. 6. 24. 11:29

#1 ์ด์ „ ๊ธ€

 

[Android] Dagger2 - @Provides

#1 ์ด์ „ ๊ธ€ [Android] Dagger2 - ๊ธฐ์ดˆ#1 ์ด์ „ ๊ธ€ ์˜์กด์„ฑ ์ฃผ์ž… (Dependency Injection)#1 ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)์ด๋ž€?#1-1 Dependent์™€ Dependencyfun main() { val car = Car() car.startCar() } class Car { private val engine = Engine

kenel.tistory.com

์œ„ ๊ฒŒ์‹œ๊ธ€์˜ ์™„์„ฑ๋œ ์•ฑ์„ ์ผ๋ถ€ ์ˆ˜์ •ํ•ด์„œ, @Provides ๋˜๋Š” @Module์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋งŒ๋“ค์–ด๋ณธ๋‹ค.

 

 

Dagger ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์“ฐ๋Š” ํ”„๋กœ์ ํŠธ์—์„œ @Provides ๋˜๋Š” @Module์— ์ธ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € dagger์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋Š” ์ฝ”๋“œ์˜ ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

 

#2 Component ํด๋ž˜์Šค์™€ ๊ทธ ๋นŒ๋” ํด๋ž˜์Šค

#2-1 dagger์—์„œ์˜ ์˜์กด์„ฑ ์ฃผ์ž… ์ค€๋น„๋Š” ์ปดํŒŒ์ผ ๋•Œ ์ด๋ค„์ง„๋‹ค

...

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)
        setContentView(R.layout.activity_main)
/*
        val crankshaft = Crankshaft()
        val cylinder = Cylinder()
        val piston = Piston(crankshaft, cylinder)
        val engine = Engine(piston)
        val airbag = Airbag()
        val battery = Battery()

        val car = Car(engine, airbag, battery)
*/
        val car = DaggerCarComponent.create().getCar()
        car.startCar()
    }
}

์ˆ˜๋™์  ์˜์กด์„ฑ ์ฃผ์ž…(์ฃผ์„ ์ฒ˜๋ฆฌ๋œ ์ฝ”๋“œ)๊ณผ dagger์˜ ์˜์กด์„ฑ ์ฃผ์ž…์˜ ์ฐจ์ด๋Š” '์˜์กด์„ฑ ์ฃผ์ž…์˜ ์•”์‹œ์„ฑ'๋ฟ๋งŒ์ด ์•„๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋ฐ”๋กœ, Dependency๋“ค์„ ๋ชจ์•„์„œ ์ตœ์ข…์ ์ธ Dependent๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒ€์ฆ ๊ณผ์ •์ด ๋Ÿฐํƒ€์ž„์ด ์•„๋‹Œ ์ปดํŒŒ์ผ ์‹œ์ ์— ์ด๋ค„์ง„๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ฃผ์„ ์ฒ˜๋ฆฌ๋œ ์ฝ”๋“œ์—์„  Car ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•˜์œ„ Dependency๋“ค์˜ ์ธ์Šคํ„ด์Šค๋“ค์„ ๋‹จ๊ณ„์ ์œผ๋กœ ์ƒ์„ฑํ•ด๋‚˜๊ฐ€๊ณ  ์žˆ๋‹ค. ์ด ๊ณผ์ •์€ ๋Ÿฐํƒ€์ž„์—์„œ ์ง„ํ–‰๋œ๋‹ค.

 

๋ฐ˜๋ฉด, dagger์—์„œ๋Š” ์–ด๋–ค๊ฐ€? ์ฃผ์„ ์ฒ˜๋ฆฌ๋œ ์ฝ”๋“œ ๋ถ€๋ถ„์˜ ๊ณผ์ •์„ ์ปดํŒŒ์ผ ์‹œ์ ์— ๊ฒ€์ฆ ๋ฐ ์ €์žฅํ•˜๊ณ , ์ตœ์ข… Dependent์ธ Car ์ธ์Šคํ„ด์Šค๋ฅผ getCar() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ๋ฐ”๋กœ ์–ป์–ด๋‚ด๊ณ  ์žˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž. 

 

#2-2 ์ƒ์„ฑ๋œ @Component ํด๋ž˜์Šค ์‚ดํŽด๋ณด๊ธฐ (DaggerCarComponent.java)

๋”๋ณด๊ธฐ
// Generated by Dagger (https://dagger.dev).
package com.example.parameter;

import dagger.internal.DaggerGenerated;
import dagger.internal.Preconditions;

@DaggerGenerated
@SuppressWarnings({
    "unchecked",
    "rawtypes",
    "KotlinInternal",
    "KotlinInternalInJava",
    "cast"
})
public final class DaggerCarComponent {
  private DaggerCarComponent() {
  }

  public static Builder builder() {
    return new Builder();
  }

  public static CarComponent create() {
    return new Builder().build();
  }

  public static final class Builder {
    private MyModule myModule;

    private Builder() {
    }

    public Builder myModule(MyModule myModule) {
      this.myModule = Preconditions.checkNotNull(myModule);
      return this;
    }

    public CarComponent build() {
      if (myModule == null) {
        this.myModule = new MyModule();
      }
      return new CarComponentImpl(myModule);
    }
  }

  private static final class CarComponentImpl implements CarComponent {
    private final MyModule myModule;

    private final CarComponentImpl carComponentImpl = this;

    private CarComponentImpl(MyModule myModuleParam) {
      this.myModule = myModuleParam;

    }

    private Piston piston() {
      return new Piston(new Crankshaft(), new Cylinder());
    }

    private Engine engine() {
      return new Engine(piston());
    }

    private Airbag airbag() {
      return new Airbag(MyModule_ProvidesAirbagManufacturerFactory.providesAirbagManufacturer(myModule));
    }

    private Battery battery() {
      return new Battery(MyModule_ProvidesBatteryManufacturerFactory.providesBatteryManufacturer(myModule));
    }

    @Override
    public Car getCar() {
      return new Car(engine(), airbag(), battery());
    }
  }
}

์ด ํด๋ž˜์Šค๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ž‘์„ฑํ•œ @Component ์ธํ„ฐํŽ˜์ด์Šค์— ๊ธฐ๋ฐ˜ํ•ด ์ปดํŒŒ์ผ ์‹œ์ ์— dagger๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ @Component ํด๋ž˜์Šค๋‹ค. dagger๋Š” ์ปดํŒŒ์ผ ์‹œ์ ์— ๋ง๋‹จ Dependency๊นŒ์ง€์˜ ๋ชจ๋“  ์˜์กด์„ฑ ์ฃผ์ž…์„ ๊ฒ€์ฆํ•˜๊ณ , ๊ทธ ์ฃผ์ž… ๊ฒฐ๊ณผ๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์›ํด๋ฆญ์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ(getCar())๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๊ฐ€ ์†ํ•œ ํด๋ž˜์Šค์ธ CarComponentImpl์™€ ๊ทธ ๋นŒ๋” ํด๋ž˜์Šค(์ดํ•˜ Component Builder)๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

#2-3 ๋งค๊ฐœ๋ณ€์ˆ˜ ํ• ๋‹น ํƒ€์ด๋ฐ

๋ง๋‹จ Dependency์—์„œ ์‹œ์ž‘ํ•ด ์ฐจ๊ณก์ฐจ๊ณก ๋‹จ๊ณ„๋ฅผ ๋ฐŸ์•„ ์˜ฌ๋ผ๊ฐ€๋Š” ์ˆ˜๋™์  ์˜์กด์„ฑ ์ฃผ์ž…์€ ๋Ÿฐํƒ€์ž„์— ์ด๋Ÿฐ์ €๋Ÿฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋จธ ์ž…๋ง›๋Œ€๋กœ ์† ์‰ฝ๊ฒŒ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ฉด, dagger์˜ ๊ฒฝ์šฐ๋Š” ๊ตฌ์กฐ์ƒ ๊ทธ๋Ÿด ์ˆ˜ ์—†๋‹ค. ComponentImpl ํด๋ž˜์Šค๋Š” ์ปดํŒŒ์ผ ์‹œ์ ์— ๋งŒ๋“ค์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ, ์šฐ๋ฆฌ๋Š” ComponentImpl ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋นŒ๋” ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฝ์ž…ํ•˜๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์‚ฝ์ž…๋œ ๋ฒ„์ „์˜ ComponentImpl์ด ์–ป์–ด์ง€๋Š” ๊ฑธ ๋ชฉํ‘œ๋กœ ๋‘์–ด์•ผ ํ•œ๋‹ค.

 

#3 ์ฝ”๋“œ ์ˆ˜์ • - @Module ํด๋ž˜์Šค์— ์ƒ์„ฑ์ž ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ

#3-1 MyModule.kt

...

@Module
class MyModule(private val countryOfManufacture: String) {

    @Provides
    @Named("Airbag")
    fun providesAirbagManufacturer(): String {
        return "KENEL" + " (MADE IN ${countryOfManufacture})"
    }

    @Provides
    @Named("Battery")
    fun providesBatteryManufacturer(): String {
        return "TISTORY" + " (MADE IN ${countryOfManufacture})"
    }
}

MyModule ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , init { ... }์— ๋งค๊ฐœ๋ณ€์ˆ˜ ํ™•์ธ์šฉ Log.i( ... )๋„ ๋„ฃ์–ด์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  [Build] - [Rebuild Project]ํ•œ๋‹ค. ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค๋ฉด, MainActivity์—์„œ ์ฃผ์„ ์•„๋ž˜์ชฝ ์ฝ”๋“œ๋ฅผ ์ง€์šฐ๊ณ  ๋‹ค์‹œ ์‹œ๋„ํ•ด๋ณธ๋‹ค.

 

#3-2 @Component ์ธํ„ฐํŽ˜์ด์Šค

// package com.example.parameter

import dagger.BindsInstance
import dagger.Component
import javax.inject.Named

@Component(modules = [MyModule::class])
interface CarComponent {
    fun getCar(): Car

    @Component.Builder
    interface Builder {
        fun setMyModule(myModule: MyModule): Builder

        fun build(): CarComponent
    }
}

๋นŒ๋” ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค. ์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด, dagger๊ฐ€ ์•Œ์•„์„œ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

 

#3-3 ์ƒ์„ฑ๋œ @Component ํด๋ž˜์Šค ์‚ดํŽด๋ณด๊ธฐ (DaggerCarComponent.java)

๋”๋ณด๊ธฐ
// Generated by Dagger (https://dagger.dev).
package com.example.parameter;

import dagger.internal.DaggerGenerated;
import dagger.internal.Preconditions;

@DaggerGenerated
@SuppressWarnings({
    "unchecked",
    "rawtypes",
    "KotlinInternal",
    "KotlinInternalInJava",
    "cast"
})
public final class DaggerCarComponent {
  private DaggerCarComponent() {
  }

  public static CarComponent.Builder builder() {
    return new Builder();
  }

  private static final class Builder implements CarComponent.Builder {
    private MyModule myModule;

    @Override
    public Builder setMyModule(MyModule myModule) {
      this.myModule = Preconditions.checkNotNull(myModule);
      return this;
    }

    @Override
    public CarComponent build() {
      Preconditions.checkBuilderRequirement(myModule, MyModule.class);
      return new CarComponentImpl(myModule);
    }
  }

  private static final class CarComponentImpl implements CarComponent {
    private final MyModule myModule;

    private final CarComponentImpl carComponentImpl = this;

    private CarComponentImpl(MyModule myModuleParam) {
      this.myModule = myModuleParam;

    }

    private Piston piston() {
      return new Piston(new Crankshaft(), new Cylinder());
    }

    private Engine engine() {
      return new Engine(piston());
    }

    private Airbag airbag() {
      return new Airbag(MyModule_ProvidesAirbagManufacturerFactory.providesAirbagManufacturer(myModule));
    }

    private Battery battery() {
      return new Battery(MyModule_ProvidesBatteryManufacturerFactory.providesBatteryManufacturer(myModule));
    }

    @Override
    public Car getCar() {
      return new Car(engine(), airbag(), battery());
    }
  }
}

Builder().build()๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋˜ #2-2์˜ create() ๋ฉ”์†Œ๋“œ๊ฐ€ ์‚ฌ๋ผ์กŒ๋‹ค. ๋˜, #2-2์—๋Š” myModule์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ null์ด๋ฉด ์ž๋™์œผ๋กœ myModule์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋„ฃ๋Š” ๋™์ž‘์ด ์ •์˜๋˜์–ด์žˆ์—ˆ๋Š”๋ฐ ์ด๊ฒƒ์ด ์‚ญ์ œ๋˜์—ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ #3-2์—์„œ ๋งŒ๋“ค์—ˆ๋˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ์ธ setMyModule()์˜ ๊ตฌํ˜„ ๋ฉ”์†Œ๋“œ๊ฐ€ myModule์ด null์ธ์ง€๋ฅผ checkNotNull()์ด๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋กœ ๊ฒ€์‚ฌํ•˜๊ณ  ์žˆ๋‹ค. ์ด ๋ฉ”์†Œ๋“œ๋Š” ์ธ์ž๋กœ ๋ฐ›์€ ๊ฐ์ฒด๊ฐ€ null์ด๋ฉด java.lang.NullPointerException ์—๋Ÿฌ๋ฅผ ์ผ์œผํ‚จ๋‹ค. ํ•œ๋งˆ๋””๋กœ, myModule์„ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋ฐ˜๋“œ์‹œ ๋ช…์‹œํ•˜์—ฌ Builder ํด๋ž˜์Šค์—๊ฒŒ ๋„˜๊ฒจ์ฃผ๋„๋ก ์œ ๋„ํ•˜๊ณ  ์žˆ๋‹ค. ์ด์ œ MainActivity์—์„œ ์œ ๋„๋ฐ›์€(?)๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์งœ๋ณด๊ฒ ๋‹ค.

 

#3-4 MainActivity.kt

...

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)
        setContentView(R.layout.activity_main)
/*
        ...
*/

        val car = DaggerCarComponent
            .builder()
            .setMyModule(MyModule("KOREA"))
            .build()
            .getCar()
        car.startCar()
    }
}

 

#3-5 ์ž‘๋™ ํ™•์ธ (๋กœ๊ทธ ๋ฉ”์‹œ์ง€)

Crankshaft is ready
Cylinder is ready
Piston is ready
Engine is ready
Airbag is ready
Airbag made by KENEL (MADE IN KOREA)
Battery is ready
Battery made by TISTORY (MADE IN KOREA)
Car is ready

 

#4 ์ฝ”๋“œ ์ˆ˜์ • - @Provides ๋ฉ”์†Œ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ

#4-1 MyModule.kt

...

@Module
class MyModule {

    @Provides
    @Named("Airbag")
    fun providesAirbagManufacturer(@Named("material") material: String): String {
        return "KENEL" + " (์žฌ์งˆ: ${material})"
    }

    @Provides
    @Named("Battery")
    fun providesBatteryManufacturer(@Named("type") type: String): String {
        return "TISTORY" + " (์ข…๋ฅ˜: ${type})"
    }
}

์ด๋ฒˆ์—” @Provides ๋ฉ”์†Œ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ๋‹ค. ์ˆ˜์ • ํ›„ [Build] - [Rebuild Project]ํ•œ๋‹ค. ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค๋ฉด, MainActivity์—์„œ ์ฃผ์„ ์•„๋ž˜์ชฝ ์ฝ”๋“œ๋ฅผ ์ง€์šฐ๊ณ  ๋‹ค์‹œ ์‹œ๋„ํ•ด๋ณธ๋‹ค.

 

#4-2 @Component ์ธํ„ฐํŽ˜์ด์Šค

// package com.example.parameter

import dagger.BindsInstance
import dagger.Component
import javax.inject.Named

@Component(modules = [MyModule::class])
interface CarComponent {
    fun getCar(): Car

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun setMaterialOfProvides(@Named("material") country: String): Builder

        @BindsInstance
        fun setTypeOfProvides(@Named("type") type: String): Builder

        fun build(): CarComponent
    }
}

@Named๊ฐ€ ์“ฐ์ธ ์ด์œ ๋Š”, MyModule์˜ ๋‘ ํ•จ์ˆ˜์˜ ์ƒ์„ฑ์ž ์ธ์ˆ˜์˜ ์ข…๋ฅ˜์™€ ๊ฐฏ์ˆ˜๊ฐ€ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋งŒ์•ฝ ๋‘˜ ๋‹ค String์„ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, ์–ด๋Š ํ•œ ์ชฝ์€ String์ด๊ณ  ๋ฐ˜๋Œ“์ชฝ์€ Int์˜€๋‹ค๋ฉด @Named๊ฐ€ ์—†์–ด๋„ ์ •์ƒ์ž‘๋™ํ•œ๋‹ค. dagger ์ž…์žฅ์—์„œ ์–ด๋Š @BindInstance ๋ฉ”์†Œ๋“œ๊ฐ€ ์–ด๋Š @Provide ๋ฉ”์†Œ๋“œ์— ์—ฐ๊ฒฐ๋˜๋Š”์ง€ ๋ช…ํ™•ํžˆ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๋˜, #3-2์—์„œ์™€๋Š” ๋‹ฌ๋ฆฌ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ์— @BindInstance ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์—ˆ๋‹ค. @BindsInstance๋Š” Component Builder์— ์˜ํ•ด ๋งŒ๋“ค์–ด์ง€๋Š” ComponentImpl๋ฅผ ์™„์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ํŠน์ • ์ธ์Šคํ„ด์Šค, ๋ฐ”๋กœ ๊ทธ ํŠน์ • ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์†Œ๋“œ์— ๋ถ™๋Š”๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, ์–ด์งธ์„œ #3-2์—์„œ๋Š” @BindInstance๊ฐ€ ์—†์—ˆ๋Š”๊ฐ€? MyModule ๋˜ํ•œ ComponentImpl๋ฅผ ์™„์„ฑํ•  ๋•Œ ํ•„์š”ํ•˜์ง€ ์•Š์€๊ฐ€?

 

@Module์˜ ์—ญํ• ์€ ์ฒซ์งธ๋กœ๋Š” @Provides ๋ฉ”์†Œ๋“œ๋ฅผ ๋‹ด๋Š” ์šฉ๊ธฐ๋‹ค. ๋‘˜์งธ๋กœ๋Š” @Component ์–ด๋…ธํ…Œ์ด์…˜์˜ modules ์†์„ฑ์— ๋ช…์‹œ์ ์œผ๋กœ ๋“ฑ๋ก๋จ์œผ๋กœ์จ, Dagger์—๊ฒŒ ์–ด๋–ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ œ๊ณตํ•˜๋Š”์ง€ (@Provides ๋ฉ”์†Œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…๋“ค์„ ํ†ตํ•ด) ์•Œ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ MyModule ํด๋ž˜์Šค๊ฐ€ ComponentImpl์„ ์™„์„ฑํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ์€ ๋ถ„๋ช… ๋งž๋‹ค. ํ•˜์ง€๋งŒ #3-2์˜ setMyModule()์€ ComponentImpl์—๊ฒŒ(= ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„ ์ƒ์—์„œ) ์ง์ ‘์ ์œผ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, MyModule์˜ ๋ฉค๋ฒ„ ๋ฉ”์†Œ๋“œ์—๊ฒŒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— @BindInstance๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์€ ๊ฒƒ์ด๋‹ค.

 

#4-3 ์ƒ์„ฑ๋œ @Component ํด๋ž˜์Šค ์‚ดํŽด๋ณด๊ธฐ (DaggerCarComponent.java)

๋”๋ณด๊ธฐ
// Generated by Dagger (https://dagger.dev).
package com.example.parameter;

import dagger.internal.DaggerGenerated;
import dagger.internal.Preconditions;

@DaggerGenerated
@SuppressWarnings({
    "unchecked",
    "rawtypes",
    "KotlinInternal",
    "KotlinInternalInJava",
    "cast"
})
public final class DaggerCarComponent {
  private DaggerCarComponent() {
  }

  public static CarComponent.Builder builder() {
    return new Builder();
  }

  private static final class Builder implements CarComponent.Builder {
    private String setMaterialOfProvides;

    private String setTypeOfProvides;

    @Override
    public Builder setMaterialOfProvides(String country) {
      this.setMaterialOfProvides = Preconditions.checkNotNull(country);
      return this;
    }

    @Override
    public Builder setTypeOfProvides(String type) {
      this.setTypeOfProvides = Preconditions.checkNotNull(type);
      return this;
    }

    @Override
    public CarComponent build() {
      Preconditions.checkBuilderRequirement(setMaterialOfProvides, String.class);
      Preconditions.checkBuilderRequirement(setTypeOfProvides, String.class);
      return new CarComponentImpl(new MyModule(), setMaterialOfProvides, setTypeOfProvides);
    }
  }

  private static final class CarComponentImpl implements CarComponent {
    private final MyModule myModule;

    private final String setMaterialOfProvides;

    private final String setTypeOfProvides;

    private final CarComponentImpl carComponentImpl = this;

    private CarComponentImpl(MyModule myModuleParam, String setMaterialOfProvidesParam,
        String setTypeOfProvidesParam) {
      this.myModule = myModuleParam;
      this.setMaterialOfProvides = setMaterialOfProvidesParam;
      this.setTypeOfProvides = setTypeOfProvidesParam;

    }

    private Piston piston() {
      return new Piston(new Crankshaft(), new Cylinder());
    }

    private Engine engine() {
      return new Engine(piston());
    }

    private String namedString() {
      return MyModule_ProvidesAirbagManufacturerFactory.providesAirbagManufacturer(myModule, setMaterialOfProvides);
    }

    private Airbag airbag() {
      return new Airbag(namedString());
    }

    private String namedString2() {
      return MyModule_ProvidesBatteryManufacturerFactory.providesBatteryManufacturer(myModule, setTypeOfProvides);
    }

    private Battery battery() {
      return new Battery(namedString2());
    }

    @Override
    public Car getCar() {
      return new Car(engine(), airbag(), battery());
    }
  }
}

#3-3๊ณผ ๊ฐ™์€ ๋งฅ๋ฝ์œผ๋กœ #4-2์—์„œ ๋งŒ๋“  setMaterialOfProvides() ๋ฐ setTypeOfProvides()๊ฐ€ ๊ตฌํ˜„๋œ ๋ชจ์Šต์ด๋‹ค.

 

#4-4 MainActivity.kt ์ˆ˜์ •

...

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)
        setContentView(R.layout.activity_main)
/*
        ...
*/

        val car = DaggerCarComponent
            .builder()
            .setMaterialOfProvides("๋‚˜์ผ๋ก ")
            .setTypeOfProvides("๋ฆฌํŠฌ์ด์˜จ")
            .build()
            .getCar()
        car.startCar()
    }
}

 

#4-5 ์ž‘๋™ ํ™•์ธ (๋กœ๊ทธ ๋ฉ”์‹œ์ง€)

Crankshaft is ready
Cylinder is ready
Piston is ready
Engine is ready
Airbag is ready
Airbag made by KENEL (์žฌ์งˆ: ๋‚˜์ผ๋ก )
Battery is ready
Battery made by TISTORY (์ข…๋ฅ˜: ๋ฆฌํŠฌ์ด์˜จ)
Car is ready

 

#5 ์ฝ”๋“œ ์ˆ˜์ • - @Module๊ณผ @Provides ๋‘˜ ๋‹ค ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ

#3๊ณผ #4์˜ ํ•ฉ์ง‘ํ•ฉ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค. ๋ณธ ๊ฒŒ์‹œ๊ธ€์—์„  ์ƒ๋žตํ–ˆ์ง€๋งŒ, #3๊ณผ #4๊ฐ€ ํ•ฉ์ณ์ง„ ์ฝ”๋“œ๋Š” #7์— ์˜ฌ๋ ค๋‘์—ˆ๋‹ค.

 

#5-1 ์ž‘๋™ ํ™•์ธ (๋กœ๊ทธ ๋ฉ”์‹œ์ง€)

Crankshaft is ready
Cylinder is ready
Piston is ready
Engine is ready
Airbag is ready
Airbag made by KENEL (์žฌ์งˆ: ๋‚˜์ผ๋ก ) (MADE IN KOREA)
Battery is ready Battery made by TISTORY (์ข…๋ฅ˜: ๋ฆฌํŠฌ์ด์˜จ) (MADE IN KOREA)
Car is ready

 

#6 ์š”์•ฝ

dagger๋ฅผ ์“ธ ๋•, ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ Component Builder์—๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค.

 

#7 ์™„์„ฑ๋œ ์•ฑ

 

android-practice/dagger2/Parameter at master ยท Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com