๋ชจ๋ฐ”์ผ์—์„œ์˜ Dependency Injection - Part1.

chihacker
  • #kotlin
  • #dagger
  • #hilt
  • #android
  • #ios
  • #swift
  • #swinject

๋“ค์–ด๊ฐ€๋ฉฐ

๋ชจ๋ฐ”์ผ ์•ฑ๊ฐœ๋ฐœ์—์„œ๋„ ์•„ํ‚คํ…์ฒ˜๊ฐ€ ๊ณ ๋„ํ™” ๋˜๋ฉด์„œ DI ์‚ฌ์šฉ์€ ํ•„์ˆ˜์ ์ธ ์š”์†Œ๊ฐ€ ๋˜์–ด๊ฐ€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ €ํฌ ํ”„๋กฌ ๋ชจ๋ฐ”์ผํŒ€๋„ android, ios ๊ฐœ๋ฐœ ์‹œ DI๋ฅผ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋‹ค์–‘ํ•œ DIํˆด์„ ํ†ตํ•ด ๋ณด๋‹ค ์‰ฝ๊ฒŒ DI๋ฅผ ์ ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” DI์— ๋Œ€ํ•œ ๊ฐœ๋…๊ณผ ๊ตฌํ˜„์„ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์•Œ์•„๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ๋˜ dagger๋ผ๋Š” di framework์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ DI์— ๋Œ€ํ•ด์„œ ์กฐ๊ธˆ ๋” ๊นŠ์€ ์ดํ•ด๋ฅผ ๋•๊ณ ์žํ•ฉ๋‹ˆ๋‹ค.

Dependency Injection(DI) ์ด๋ž€?

DI๋Š” Dependency Injection, ์˜์กด์„ฑ ์ฃผ์ž…์˜ ์•ฝ์ž ์ž…๋‹ˆ๋‹ค. ์œ„ํ‚ค๋ฐฑ๊ณผ์—๋Š” โ€œํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๊ตฌ์„ฑ์š”์†Œ๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„๊ฐ€ ์†Œ์Šค์ฝ”๋“œ ๋‚ด๋ถ€๊ฐ€ ์•„๋‹Œ ์™ธ๋ถ€์˜ ์„ค์ •ํŒŒ์ผ ๋“ฑ์„ ํ†ตํ•ด ์ •์˜๋˜๊ฒŒ ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด ์ค‘์˜ ํ•˜๋‚˜์ด๋‹ค.โ€ ๋ผ๊ณ  ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. DI๋ฅผ ํ™œ์šฉํ•˜๋ฉด ํด๋ž˜์Šค ๋ ˆ๋ฒจ์—์„œ ์˜์กด๊ด€๊ณ„๊ฐ€ ๊ณ ์ •๋˜์ง€ ์•Š๋„๋ก ํ•˜๊ณ  ๋™์ ์œผ๋กœ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ฃผ๋ฉด์„œ ์ฝ”๋“œ์˜ ์œ ์—ฐ์„ฑ์„ ํ™•๋ณดํ•˜๊ณ  ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ์–ด๋–ค ๋ง์ธ์ง€ ์ดํ•ดํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ํฌ์ŠคํŠธ์˜ ์˜ˆ์ œ ์ฝ”๋“œ๋Š” Java๋กœ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. (๊ฐ ๋ชจ๋ฐ”์ผ ํ”Œ๋žซํผ์—์„œ์˜ DI์ ์šฉ ๊ด€๋ จํ•ด์„œ๋„ ํฌ์ŠคํŒ… ์ง„ํ–‰ํ•  ์˜ˆ์ •์ธ๋ฐ ์ด๋•Œ๋Š” kotlin, swift ์˜ˆ์ œ๋กœ ์ง„ํ–‰ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŠธ๋Š” dagger๋ฅผ ํ†ตํ•ด DI์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ ์˜ˆ์ •์ด๋ผ dagger๊ฐ€ ๊ตฌ์„ฑ๋œ ์–ธ์–ด์ธ java๋กœ ์˜ˆ์ œ๋ฅผ ๊ตฌ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.)

์˜ˆ์ œ๋Š” Dagger ์—์„œ๋„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” Coffee Maker ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋จผ์ € DI ์—†์ด Coffee Maker ์—์„œ ์ปคํ”ผ๋ฅผ ๋‚ด๋ ค๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. Coffee๋ฅผ ๋‚ด๋ฆฌ๋Š”๋ฐ๋Š” ์—ด์„ ๊ฐ€ํ•˜๋Š” Heater ์™€ ์••๋ ฅ์„ ๊ฐ€ํ•˜๋Š” pump ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Heater ๋Š” on / off ์™€ ๋œจ๊ฑฐ์šด์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ธฐ๋Šฅ(isHot)์ด ์žˆ๊ณ  pump๋Š” pump ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด๋ด…์‹œ๋‹ค.

public interface Heater { void on(); void off(); boolean isHot(); }
public interface Pump { void pump(); }

๊ทธ๋ฆฌ๊ณ  Heater ์™€ Pump ๋ฅผ ์‚ฌ์šฉํ•ด ์ปคํ”ผ๋ฅผ ๋‚ด๋ ค์ฃผ๋Š” Coffee Maker ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•ด๋ด…์‹œ๋‹ค.

public class CoffeeMaker { 
    private final Heater heater; 
    private final Pump pump; 
    
    public CoffeeMaker(Heater heater, Pump pump) { 
        this.heater = heater; this.pump = pump; 
    } 
    
    public void brew(){ 
        heater.on(); 
        pump.pump(); 
        System.out.println(" [_]P coffee! [_]P "); 
        heater.off(); 
    } 
}

์ด์ œ A_Heater ์™€ A_Pump ๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์ฒด๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class A_Heater implements Heater { 
    boolean heating; 
    
    public void on() { 
        System.out.println("A_Heater : ~ ~ ~ heating ~ ~ ~"); 
        this.heating = true; 
    }
    
    public void off() { 
        this.heating = false; 
    }
    
    public boolean isHot() { 
        return heating; 
    } 
}

public class A_Pump implements Pump { 
    private final Heater heater; 
    
    public A_Pump(Heater heater) { t
        his.heater = heater; 
    } 
    
    public void pump() { 
        if (heater.isHot()) { 
            System.out.println("A_Pump => => pumping => =>"); 
        } 
    } 
}

์ด์ œ DI๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๋ฉ”์ธํ•จ์ˆ˜์—์„œ ์ปคํ”ผ๋ฅผ ๋‚ด๋ ค๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Heater heater = new A_Heater(); 
Pump pump = new A_Pump(heater); 
CoffeeMaker coffeeMaker = new CoffeeMaker(heater,pump); 
coffeeMaker.brew();

์ปคํ”ผ๋ฅผ ๋‚ด๋ฆฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” CoffeeMaker ๊ฐ์ฒด ์‚ฌ์šฉ์ž๊ฐ€ A_Heater ๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์ฒด์™€ A_Pump ๋ผ๋Š” ๊ตฌํ˜„์ฒด๋ฅผ ์•Œ์•„์•ผ ์ปคํ”ผ๋ฅผ ๋‚ด๋ฆด์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ปคํ”ผ๋ฅผ ๋งˆ์‹œ๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ์€ ์–ด๋–ค heater ๋ฅผ ์“ฐ๋Š”์ง€ ์–ด๋–ค pump ๋ฅผ ์“ฐ๋Š”์ง€ ์ƒ๊ด€์—†๋Š”๋ฐ ๋ง์ด์ฃ . ์ฆ‰ CoffeeMaker ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ๊ตฌํ˜„์ฒด์— ์˜์กดํ•˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

DI๋Š” CoffeeMaker ์‚ฌ์šฉ์ž๊ฐ€ ์˜์กด์„ฑ์„ ๋ชจ๋ฅด๋Š” ์ƒํƒœ์—์„œ๋„ ์ปคํ”ผ๋ฅผ ๋‚ด๋ฆด์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. ์–ด๋–ค heater ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š”์ง€ pump ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š”์ง€ ๋ชฐ๋ผ๋„ ์ปคํ”ผ๋ฅผ ๋‚ด๋ฆด์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ CoffeeMaker ์‚ฌ์šฉ์ž ๋Œ€์‹ ์— ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ฃผ๋Š” Injection ์ด๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class Injection { 
    public static Heater provideHeater(){ 
        return new A_Heater(); 
    } 
    
    public static Pump providePump(Heater heater){ 
        return new A_Pump(heater); 
    } 
    
    public static CoffeeMaker provideCoffeeMaker(){ 
        Heater heater = Injection.provideHeater();
        return new CoffeeMaker(heater,providePump(heater)); 
    } 
}

Injection ํด๋ž˜์Šค๋Š” DI, ์ฆ‰ ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•ด์ฃผ๋Š” ์„ค์ • ํŒŒ์ผ์ด๋ผ๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ €ํฌ๋Š” ์ด ์„ค์ • ํŒŒ์ผ์—์„œ ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์ฒด๋ฅผ ๋ฆฌํ„ดํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ž ๊ทธ๋Ÿผ DI ๋ฅผ ๊ตฌํ˜„ํ•œ ์ƒํƒœ์—์„œ CoffeeMaker ์‚ฌ์šฉ์ž๋Š” ์–ด๋–ป๊ฒŒ ์ปคํ”ผ๋ฅผ ๋‚ด๋ฆด์ˆ˜ ์žˆ์„๊นŒ์š”?

CoffeeMaker coffeeMaker = new CoffeeMaker(Injection.provideHeater(),Injection.providePump()); 
coffeeMaker.brew();

Injection ํด๋ž˜์Šค์—์„œ heater์™€ pump ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด์ œ CoffeeMaker ์‚ฌ์šฉ์ž๋Š” A_Heater๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š”์ง€ B_Heater๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š”์ง€ ์•Œ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ๋Š” ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Injection.provideCoffeeMaker().brew();

์ด ๊ฒฝ์šฐ CoffeeMaker ์‚ฌ์šฉ์ž๋Š” heater ๋‚˜ pump ๊ฐ€ ํ•„์š”ํ•œ์ง€ ๋ชจ๋ฅด๋Š” ์ƒํƒœ์—์„œ๋„ ์ปคํ”ผ๋ฅผ ๋‚ด๋ฆด์ˆ˜ ์žˆ๊ฒ ๋„ค์š”. ๊ฐ‘์ž๊ธฐ A_Heater ๋ง๊ณ  B_Heater ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์™”์„ ๋•Œ DI ๊ฐ€ ๊ตฌํ˜„๋œ ์ฝ”๋“œ์—์„œ CoffeeMaker๊ด€๋ฆฌ์ž๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์•„๋ฌด ์–˜๊ธฐ ์—†์ด Injection ์„ค์ •๋งŒ B_Heater๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ DI ๊ฐ€ ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด CoffeeMaker ๊ด€๋ฆฌ์ž๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ปคํ”ผ ๋‚ด๋ฆด๋•Œ A_Heater ๊ฐ์ฒด ๋ง๊ณ  B_Heater ๊ฐ์ฒด ์“ฐ๋ ด ํ•˜๋ฉฐ ์š”์ฒญํ•ด์•ผํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์šด ์ผ์ด ์ƒ๊ธฐ๊ฒ ์ฃ .

์ด๋Ÿฐ ํ˜•ํƒœ์˜ ๋””์ž์ธ ํŒจํ„ด์„ DI ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. DI๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ„ ์ปคํ”Œ๋ง์„ ๊ฐ์†Œ์‹œํ‚ฌ์ˆ˜ ์žˆ๊ณ  ์žฌ์‚ฌ์šฉ ๋ฐ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์œ ๋‹› ํ…Œ์ŠคํŠธ ์‹œ์—๋„ ๊ฐ„๊ฒฐํ•œ ๊ตฌํ˜„์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ DI๋ฅผ ์‰ฝ๊ณ  ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ Dagger ์ž…๋‹ˆ๋‹ค.

Dagger๋ฅผ ์ด์šฉํ•œ DI

์ด์ œ ์œ„์—์„œ ๋งŒ๋“  CoffeeMaker ๋ฅผ Dagger๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์œ„์—์„œ ์šฐ๋ฆฌ๋Š” Injection ์ด๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ด๊ณณ์— ์˜์กด์„ฑ ์ฃผ์ž… ์ •๋ณด๋ฅผ ๋„ฃ์–ด๋†จ์Šต๋‹ˆ๋‹ค. Dagger์—์„œ๋Š” ์ด๋Ÿฐ ์˜์กด์„ฑ ์ฃผ์ž… ๊ด€๊ณ„๋ฅผ annotation ์„ ์ด์šฉํ•˜์—ฌ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Dagger ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ annotation ์€ ๋„ค ๊ฐ€์ง€ ์ •๋„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@Component : ์‹ค์ œ ์˜์กด์„ฑ ์ฃผ์ž…์ด ๊ตฌํ˜„๋  interface ๋˜๋Š” abstract class ์— ์‚ฌ์šฉ๋˜๋Š” annotation ์ž…๋‹ˆ๋‹ค. dagger๋Š” ์ด annotation ์ด ๋‹ฌ๋ ค์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กด์„ฑ ์ฃผ์ž… ์ฝ”๋“œ๋ฅผ generate ํ•ฉ๋‹ˆ๋‹ค. Component ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Module : ์˜์กด์„ฑ ๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•˜๋Š” ํด๋ž˜์Šค์— ์‚ฌ์šฉ๋˜๋Š” annotation. ์‹ค์ œ ๊ฐ์ฒด ์ฃผ์ž… ๊ด€๊ณ„์— ๋Œ€ํ•œ ์„ค์ •์ด ๋“ค์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@Provides : ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ์— ๋‹ฌ์•„์ฃผ๋Š” annotation ์ž…๋‹ˆ๋‹ค.

@Inject : DI๋ฅผ ์ง„ํ–‰ํ•  ๋ฉค๋ฒ„๋ณ€์ˆ˜์™€ ์ƒ์„ฑ์ž์— ๋‹ฌ์•„์คŒ์œผ๋กœ์„œ DI ๋Œ€์ƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ์ œ๊ณตํ•˜๊ณ ์ž ํ•˜๋Š” ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์— ๋‹ฌ์•„์คŒ์œผ๋กœ์„œ ์ œ๊ณต ๋Œ€์ƒ์„ ํ™•์ธ ํ• ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

๋จผ์ € ์˜์กด์„ฑ ๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค. Dagger์—์„œ๋Š” ์ด๋Ÿฐ ํด๋ž˜์Šค๋ฅผ ๋ชจ๋“ˆ์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ณ  @Module ์ด๋ผ๋Š” annotation ์„ ๋‹ฌ์•„ ๋†“์Šต๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ํด๋ž˜์Šค์—์„œ๋Š” ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•˜๊ธฐ ์œ„ํ•œ ๋งค์„œ๋“œ๋“ค์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” heater ์™€ pump ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์ฒด๋“ค์„ ์ฃผ์ž…ํ•˜๊ธฐ ์œ„ํ•œ ๋งค์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ตฌํ˜„๋œ ๋งค์„œ๋“œ์—๋Š” @Provides annotation ์„ ์ ์šฉ์‹œํ‚ต๋‹ˆ๋‹ค.

@Module public class CoffeeMakerModule { 
    @Provides Heater provideHeater(){ 
        return new A_Heater(); 
    } 
    
    @Provides Pump providePump(Heater heater){ 
        return new A_Pump(heater); 
    } 
}

์—ฌ๊ธฐ์„œ ์ ์šฉ๋œ @Module ๊ณผ @Provides๋Š” @Component ํด๋ž˜์Šค์—์„œ ์‹ค์ œ ์ฃผ์ž… ์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค. ์ด์ œ ์‹ค์ œ ์ฝ”๋“œ๊ฐ€ generate ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ธ component๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. component ์—๋Š” ์ตœ์†Œ ํ•œ๊ฐœ์˜ abstract ๋งค์„œ๋“œ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋งค์„œ๋“œ๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ injection์„ ์‹œํ‚ฌ ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๊ฑฐ๋‚˜(provision method) ๋˜๋Š” ๋งด๋ฒ„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์˜์กด์„ฑ ์ฃผ์ž…์„ ์‹œํ‚ฌ ๊ฐ์ฒด๋ฅผ ๋„˜๊ธฐ๋Š”(Members-injection methods) ๋งค์„œ๋“œ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Component(modules = CoffeeMakerModule.class) 
public interface CoffeeComponent { 
    //provision method 
    CoffeeMaker make(); 
    // member-injection method 
    void inject(CoffeeMaker coffeeMaker); 
}

CoffeeComponent ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  provision method ์™€ member-injection method ๋„ ํ•˜๋‚˜์”ฉ ๊ตฌํ˜„ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ธํ„ฐํŽ˜์ด์Šค์— component์ž„์„ ์•Œ๋ฆฌ๋Š” @Component annotation์„ ๋‹ฌ์•„์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. @Component ์—๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์„ ๊ตฌํ˜„ํ•  ๋ชจ๋“ˆ๋“ค์„ ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. annotation์˜ modules๊ฐ’์— ์œ„์—์„œ ๊ตฌํ˜„ํ•œ CoffeeMakerModule์„ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค. ์ด์ œ dagger๋Š” CoffeeMakerModule ์—์„œ @Provides๋กœ ๊ตฌํ˜„ํ•œ ๋งค์„œ๋“œ๋“ค์„ ์ด์šฉํ•ด์„œ ์˜์กด์„ฑ์„ ์ฃผ์ž… ์‹œํ‚ฌ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ @Inject ๋ฅผ ํ†ตํ•ด์„œ ์–ด๋””์— ์ฃผ์ž…ํ•˜๋ฉด ๋˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

CoffeeComponent ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  provision method ์™€ member-injection method ๋„ ํ•˜๋‚˜์”ฉ ๊ตฌํ˜„ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ธํ„ฐํŽ˜์ด์Šค์— component์ž„์„ ์•Œ๋ฆฌ๋Š” @Component annotation์„ ๋‹ฌ์•„์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. @Component ์—๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์„ ๊ตฌํ˜„ํ•  ๋ชจ๋“ˆ๋“ค์„ ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. annotation์˜ modules๊ฐ’์— ์œ„์—์„œ ๊ตฌํ˜„ํ•œ CoffeeMakerModule์„ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค. ์ด์ œ dagger๋Š” CoffeeMakerModule ์—์„œ @Provides๋กœ ๊ตฌํ˜„ํ•œ ๋งค์„œ๋“œ๋“ค์„ ์ด์šฉํ•ด์„œ ์˜์กด์„ฑ์„ ์ฃผ์ž… ์‹œํ‚ฌ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ @Inject ๋ฅผ ํ†ตํ•ด์„œ ์–ด๋””์— ์ฃผ์ž…ํ•˜๋ฉด ๋˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

@Inject 
public CoffeeMaker(Heater heater, Pump pump){ 
    this.heater = heater; 
    this.pump = pump; 
}

CoffeeMaker์˜ ์ƒ์„ฑ์ž์— @Inject ๋ฅผ ๋‹ฌ์•„์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ปคํ”ผ๋ฅผ ๋‚ด๋ ค๋ณด๋Š” ์ผ๋งŒ ๋‚จ์•˜์Šต๋‹ˆ๋‹ค. Dagger์—์„œ๋Š” @Component ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ DaggerYourComponentName ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” CoffeeComponent๋กœ ํ–ˆ์œผ๋‹ˆ DaggerCoffeeComponent๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Component ๊ฐ์ฒด๋Š” create() ๋˜๋Š” build() ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ปคํ”ผ๋ฅผ ๋‚ด๋ ค๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

DaggerCoffeeComponent.create().make().brew();

CoffeeComponent์—์„œ ๊ตฌํ˜„ํ–ˆ๋˜ make ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ์ปคํ”ผ๋ฅผ ๋‚ด๋ ค๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ inject ํ•จ์ˆ˜๋Š” ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ• ๊นŒ์š”? CoffeeMaker ํด๋ž˜์Šค๋ฅผ ๋จผ์ € ์กฐ๊ธˆ ๊ณ ์ณ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Inject Heater heater; 
@Inject Pump pump; 

public CoffeeMaker(){}

์ด์ œ CoffeeMaker ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ inject ํ•จ์ˆ˜๋กœ ๋„˜๊ฒจ ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

CoffeeMaker coffeeMaker = new CoffeeMaker(); 
DaggerCoffeeComponent.create().inject(coffeeMaker); 
coffeeMaker.brew();

์ด๋ ‡๊ฒŒ ์ปคํ”ผ๋ฅผ ๋‚ด๋ฆด์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Dagger์—์„œ๋Š” ์กฐ๊ธˆ ๋” ๋ณต์žกํ•˜๊ฒŒ DI๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Dagger๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ช‡๊ฐ€์ง€ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•œ ํ‚ค์›Œ๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด์„œ ์–ด๋–ป๊ฒŒ ํ™œ์šฉ๋˜๋Š”์ง€ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Subcomponent : dagger2 ์—๋Š” subcomponent ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. subcomponent๋Š” ๋ง๊ทธ๋Œ€๋กœ ๋ถ€๋ชจ component๊ฐ€ ์žˆ๋Š” component๋ผ๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ผ๋ฐ˜ component์™€๋Š” ๋‹ฌ๋ฆฌ ์ฝ”๋“œ ์ƒ์„ฑ์€ ๋ถ€๋ชจ component์—์„œ ์ด๋ฃจ์–ด ์ง‘๋‹ˆ๋‹ค. subcomponent๋Š” component์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ interface๋‚˜ abstract class์— @Subcomponent ๋ฅผ ๋‹ฌ์•„์ฃผ๋ฉด์„œ ์ƒ์„ฑ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Scope : dagger2 ๋Š” scope ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Component ๋ณ„๋กœ @scope annotation ์„ ์ด์šฉํ•˜์—ฌ ์ฃผ์ž…๋˜๋Š” ๊ฐ์ฒด๋“ค์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Binds : module์—์„œ ์ œ๊ณตํ•˜๊ณ ์ž ํ•˜๋Š” ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์ฒด(ex interface ๊ตฌํ˜„์ฒด)๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Multibinding : dagger2 ์—์„œ๋Š” Set ์ด๋‚˜ Map ์„ ์ด์šฉํ•œ Multibinding ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ๋ฅผ ํ†ตํ•ด์„œ ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” ์•„์˜ˆ CafeApp ์„ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. Cafe๋Š” CafeInfo ์™€ CoffeMaker ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

public class CafeInfo { 
    
    private String name; 
    
    public CafeInfo(){} 
    
    public CafeInfo(String name){ 
        this.name = name; 
    } 
    
    public void welcome(){ 
        System.out.println("Welcome " + name == null? "":name ); 
    }
}

public class CoffeeMaker{ 
    private Heater heater; 
    
    @Inject public CoffeeMaker(Heater heater){ 
        this.heater = heater; 
    } 
    
    public void brew(CoffeeBean coffeeBean){ 
        System.out.println("CoffeeBeen("+coffeeBean.toString()+") [_]P coffee! [_]P "); 
    } 
}

CafeInfo ์™€ CoffeeMaker ๋ฅผ ์œ„์™€ ๊ฐ™์ด ๊ตฌ์„ฑํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. CafeInfo ๋Š” ๋‹จ์ˆœํžˆ ์นดํŽ˜์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํด๋ž˜์Šค์ด๋ฉฐ CoffeeMaker๋Š” Heater๋ผ๋Š” ๊ฐ์ฒด๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๊ณ  CoffeeBean์„ ๋ฐ›์•„ ์ปคํ”ผ๋ฅผ ๋‚ด๋ฆด ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ( ์ง€๋‚œ ํฌ์ŠคํŠธ ๋ณด๋‹ค ์—…๊ทธ๋ ˆ์ด๋“œ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ™‚ )

public class CoffeeBean { 
    public void name(){ 
        System.out.println("CoffeeBean"); 
    } 
}

์ž! ์ด์ œ ๊ธฐ๋ณธ์ ์ธ ์ค€๋น„๋ฅผ ๋งˆ์ณค์Šต๋‹ˆ๋‹ค.

์ด์ œ ์šฐ๋ฆฌ๋Š” Dagger๋ฅผ ์ด์šฉํ•ด ์นดํŽ˜์˜ ์ •๋ณด๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ปคํ”ผ๋ฅผ ๋‚ด๋ ค๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. CafeApp ์‚ฌ์šฉ์ž๋Š” ๋‹จ์ˆœํžˆ CafeInfo๋ฅผ ํ†ตํ•ด ์นดํŽ˜์ •๋ณด๋ฅผ ๋ณด๊ฑฐ๋‚˜ CoffeeMaker.brew ๋ฅผ ํ†ตํ•ด ์ปคํ”ผ๋ฅผ ๋‚ด๋ฆด์ˆ˜ ์žˆ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. CafeComponent์— ํ•ด๋‹น ๋‚ด์šฉ์„ ์ •์˜ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Component(modules = { CafeModule.class }) 
public interface CafeComponent { 
    CafeInfo cafeInfo(); 
    CoffeeMaker coffeeMaker(); 
}

์ด์ œ ๊ฐ CafeInfo ์™€ CoffeeMaker ์— ๋Œ€ํ•œ DI ์„ค์ •์„ ํ•˜๋Š” CafeModule์„ ์ •์˜ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Module 
public class CafeModule { 
    @Provides 
    CafeInfo provideCafeInfo(){ 
        return new CafeInfo(); 
    } 
    
    @Provides 
    CoffeeMaker provideCoffeeMaker(Heater heater){ 
        return new CoffeeMaker(heater); 
    } 
    
    @Provides Heater provideHeater(){ 
        return new Heater(); 
    } 
}

์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑ์ด ๋œ๋‹ค๋ฉด ์ง€๋‚œ ํฌ์ŠคํŠธ์—์„œ ํ–ˆ๋˜ ๋‚ด์šฉ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ CafeInfo์™€ CoffeeMaker์— ์กฐ๊ธˆ ๋” ํ˜„์‹ค์„ ๋ฐ˜์˜ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ์นดํŽ˜์— CafeInfo๋Š” ํ•˜๋‚˜๋ฟ์ด๋ฉฐ ๋ˆ„๊ฐ€ ๋ณด๋˜์ง€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์นดํŽ˜๊ฐ€ ๋งํ•˜๊ธฐ ์ „๊นŒ์ง€ CafeInfo๋Š” ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์นดํŽ˜๊ฐ€ ๋งํ•˜๋ฉด CoffeeMaker๋„ ์—†์–ด์ง‘๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์นดํŽ˜๊ฐ€ ๋งํ•˜์ง€ ์•Š์•„๋„ CoffeeMaker๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CoffeeMaker๋ฅผ ๋งŒ๋“ค ๋•Œ ๋“ค์–ด๊ฐ€๋Š” Heater๋Š” ๊ฐ™์€ CoffeeMaker์— ํ•ญ์ƒ ๊ฐ™์€ Heater๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์œผ๋กœ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” Subcomponent์™€ Scope ๋ฅผ ์ด์šฉํ•˜์—ฌ Dagger์—์„œ ๊ฐ์ฒด๋“ค์„ ์œ„์™€ ๊ฐ™์ด ๊ด€๋ฆฌ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ๊ธฐ๋ณธ์ ์œผ๋กœ java์—์„œ ์ œ๊ณตํ•˜๋Š” @Singleton ๊ณผ @CoffeeScope ์ด๋ผ๋Š” ์ปค์Šคํ…€ annotation ์„ ํ™œ์šฉํ•˜์—ฌ ๊ฐ ๊ฐ์ฒด๋“ค์˜ ๋ฒ”์œ„๋ฅผ ๊ด€๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Component์— Scope annotation ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น Component์—์„œ ๋ฐ”์ธ๋”ฉ ๋˜๋Š” ๊ฐ์ฒด๋“ค์€ Component ์™€ ๊ฐ™์€ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Singleton @Component(modules = { CafeModule.class }) 
public interface CafeComponent { 
    CafeInfo cafeInfo(); 
    CoffeeMaker coffeeMaker(); 
}

@Module 
public class CafeModule { 
    @Singleton @Provides CafeInfo provideCafeInfo(){ 
        return new CafeInfo(); 
    } 
    
    @Provides CoffeeMaker provideCoffeeMaker(Heater heater){ 
        return new CoffeeMaker(heater); 
    } 
    
    @Provides Heater provideHeater(){ 
        return new Heater(); 
    } 
}

์œ„์™€ ๊ฐ™์ด Component ์— @Singleton scope ์„ ๋ถ™์ด๊ณ  Module์˜ CafeInfo๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์„œ๋“œ์— @Singleton์„ ๋ถ™์ด๋ฉด ๊ฐ™์€ CafeComponent์—์„œ CafeInfo ๊ฐ์ฒด ํ˜ธ์ถœ์‹œ ๋™์ผํ•œ CafeInfo ๊ฐ์ฒด๊ฐ€ ํ˜ธ์ถœ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ @Singleton ์ด ์—†๋Š” CoffeeMaker๋ฅผ ํ˜ธ์ถœ์‹œ์—๋Š” ๋งค๋ฒˆ ๋‹ค๋ฅธ CoffeeMaker๊ฐ€ ํ˜ธ์ถœ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

CafeComponent cafeComponent = DaggerCafeComponent.create(); 
CafeInfo cafeInfo1 = cafeComponent.cafeInfo(); 
CafeInfo cafeInfo2 = cafeComponent.cafeInfo();

CoffeeMaker coffeeMaker1 = coffeeComponent1.coffeeMaker(); 
CoffeeMaker coffeeMaker2 = coffeeComponent1.coffeeMaker();

cafeInfo1 ๊ณผ cafeInfo2 ๋Š” ๋™์ผํ•œ ๊ฐ์ฒด๊ฐ€ ๋˜์ง€๋งŒ coffeeMaker1 ๊ณผ coffeeMaker2 ๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

Cafe(CafeComponent)์™€ CafeInfo ์˜ Scope ๋Š” ๋งž์ถ”์—ˆ์œผ๋‹ˆ ์ด์ œ CoffeeMaker ์™€ Heater ์˜ Scope ์„ ๋งž์ถฐ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. CoffeeMaker ์˜ Scope์„ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ CoffeeMaker๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” CoffeeComponent๋ฅผ ์ •์˜ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  CoffeeComponent์—๋Š” @CoffeeScope ๋ผ๋Š” Scope๋ฅผ ์ •์˜ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. CoffeeComponent์—์„œ๋Š” CoffeeMaker ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ Scope ๋น„๊ต๋ฅผ ์œ„ํ•ด์„œ CoffeeBean ๋„ ์–ป์„ ์ˆ˜ ์žˆ๋„๋ก ์ถ”๊ฐ€ํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

@CoffeeScope @Subcomponent(modules = { CoffeeModule.class }) 
public interface CoffeeComponent { 
    CoffeeMaker coffeeMaker(); 
    CoffeeBean coffeeBean(); 
    
    @Subcomponent.Builder interface Builder{ 
        CoffeeComponent build(); 
    } 
}

CoffeeMaker๊ฐ€ Cafe์•ˆ์— ์†ํ•ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— Component ๊ด€๊ณ„ ์—ญ์‹œ ์ƒ์œ„-ํ•˜์œ„ ๊ฐœ๋…์„ ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.( Cafe ๋ฅผ ํ†ตํ•˜์ง€ ์•Š๊ณ ์„œ๋Š” CoffeeMaker์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก encapsulate ํ•˜๊ณ  Scope ์—ญ์‹œ ๋„“์€ ๋ฒ”์œ„์—์„œ ์ข์€ ๋ฒ”์œ„๋กœ ์ง„ํ–‰๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋„ ์ƒ์œ„-ํ•˜์œ„ ๊ฐœ๋…์€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ) ์ด๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด Subcomponent ์ž…๋‹ˆ๋‹ค. Subcomponent๋Š” component ์™€ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์ด ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ @Subcomponent.Builder ๋ฅผ ์ •์˜ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. @Subcomponent.Builder ์˜ ํ™œ์šฉ์— ๋Œ€ํ•ด์„œ๋Š” ๋‚˜์ค‘์— ๋˜ ์„ค๋ช…ํ•˜๊ฒ ์œผ๋‹ˆ ์ผ๋‹จ์€ @Subcomponent ๋Š” Builder ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ •์˜ ๋˜์–ด์•ผ๋งŒ @Component ์—์„œ ์ฝ”๋“œ์ƒ์„ฑ์ด ๋œ๋‹ค๋ผ๊ณ ๋งŒ ์•Œ๊ณ  ๋„˜์–ด๊ฐ€๋„๋ก ํ•ฉ์‹œ๋‹ค.

์ •์˜ํ•œ Subcomponent๋ฅผ Component์— encapsulate ํ•ด์•ผํ•˜๋Š”๋ฐ ์ด๋•Œ ๋ชจ๋“ˆ์„ ํ†ตํ•ด์„œ subcomponent์™€ component๊ฐ€ ๊ด€๊ณ„๋ฅผ ๋งบ์Šต๋‹ˆ๋‹ค. ์œ„์˜ CafeComponent ์— CafeModule ์ด ์ ์šฉ๋˜์–ด ์žˆ๋Š”๋ฐ์š” ์ด๋ ‡๊ฒŒ ์ƒ์œ„ Component์— ์ ์šฉ๋œ ๋ชจ๋“ˆ์— subcomponent๋ฅผ ์ ์šฉ์‹œํ‚ค๋ฉด component ๋ผ๋ฆฌ ์ƒ์œ„-ํ•˜์œ„ ๊ด€๊ณ„๋ฅผ ๋งบ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” CafeModule์— CoffeeComponent๋ฅผ ์ ์šฉ์‹œํ‚ค๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  CafeInfo provider ๋ฉ”์„œ๋“œ๋งŒ ๋‚จ๊ธฐ๊ณ  ๋ชจ๋‘ ์‚ญ์ œ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.(์ด์ œ๋Š” CoffeeComponent์—์„œ Heater ์™€ CoffeeMaker ๋ฅผ ์ œ๊ณตํ•˜๋ฏ€๋กœ.)

@Module(subcomponents = CoffeeComponent.class) 
public class CafeModule { 
    //.... 
}

์ด๋ ‡๊ฒŒ @Module ์— subcomponents ๋ฅผ ์ ์šฉ ์‹œํ‚ฌ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” CafeComponent๊ฐ€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋˜๊ณ  CoffeeComponent ๊ฐ€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. @Subcomponent ๋Š” @Component ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฐ™์€ @Subcomponent ๋ผ๋ฆฌ๋„ ๊ด€๊ณ„์„ฑ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ CoffeeComponent ์— ์ ์šฉํ•  CoffeeModule์„ ์ •์˜ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Module 
public class CoffeeModule { 
    @CoffeeScope 
    @Provides 
    CoffeeMaker provideCoffeeMaker(Heater heater){ 
        return new CoffeeMaker(heater); 
    } 
    
    @CoffeeScope 
    @Provides 
    Heater provideHeater(){ 
        return new Heater(); 
    } 
    
    @Provides 
    CoffeeBean provideCoffeeBean(){ 
        return new CoffeeBean(); 
    } 
}

CoffeeMaker ์™€ Heater ์— ๋Œ€ํ•œ provider ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜์˜€๊ณ  Heater์™€ CoffeeMaker์—๋Š” CoffeeComponent ์™€ ๊ฐ™์€ ๋ฒ”์œ„์˜ @CoffeeScope ๋กœ ์ •์˜ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  CoffeeBean ์€ ์ปคํ”ผ๋ฅผ ๋งŒ๋“ค๋•Œ๋งˆ๋‹ค ์†Œ๋ชจ๋˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ Scope ๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด์ œ CafeComponent์—์„œ CoffeeComponent๋ฅผ ๋ถ€๋ฅผ ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๊ณ  Scope ์ ์šฉ์ด ์ž˜ ๋˜์—ˆ๋‚˜ ํ™•์ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Singleton @Component(modules = { CafeModule.class }) 
public interface CafeComponent { 
    CafeInfo cafeInfo(); 
    CoffeeComponent.Builder coffeeComponent(); 
}

CafeComponent ์—์„œ CoffeeMaker ๋Œ€์‹  CoffeeComponent.Builder ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ Scope ์ ์šฉ์„ ํ™•์ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

//Scope 
CafeComponent cafeComponent = DaggerCafeComponent.create(); 
CafeInfo cafeInfo1 = cafeComponent.cafeInfo(); 

// ๋™์ผํ•œ singleton scope ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ๋ฆฌํ„ด 
CafeInfo cafeInfo2 = cafeComponent.cafeInfo(); 
System.out.println("Singleton scope CafeInfo is equal : " + cafeInfo1.equals(cafeInfo2)); 

//CoffeeScope 
CoffeeComponent coffeeComponent1 = cafeComponent.coffeeComponent().build(); 
CoffeeComponent coffeeComponent2 = cafeComponent.coffeeComponent().build(); 
CoffeeMaker coffeeMaker1 = coffeeComponent1.coffeeMaker(); 
CoffeeMaker coffeeMaker2 = coffeeComponent1.coffeeMaker(); 
System.out.println("Maker scope / same component coffeeMaker is equal : " + coffeeMaker1.equals(coffeeMaker2)); 
CoffeeMaker coffeeMaker3 = coffeeComponent2.coffeeMaker();

//MakerScopeMethod 
System.out.println("Maker scope / different component coffeeMaker is equal : " + coffeeMaker1.equals(coffeeMaker3)); 

//Non-scope 
CoffeeBean coffeeBean1 = coffeeComponent1.coffeeBean(); 
CoffeeBean coffeeBean2 = coffeeComponent1.coffeeBean(); 
System.out.println("Non-scoped coffeebean is equal : " + coffeeBean1.equals(coffeeBean2));

๋งจ ์œ„ ๋ถ€๋ถ„์€ ์ด์ „์— ์„ค๋ช…ํ–ˆ์œผ๋‹ˆ ๋„˜์–ด๊ฐ€๊ณ  CoffeeScope ๋ถ€๋ถ„ ๋ถ€ํ„ฐ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. coffeeComponent1 ์—์„œ coffeeMaker1, coffeeMaker2 ๋ฅผ ๋งŒ๋“ค๊ณ  coffeeComponent2 ์—์„œ coffeeMaker3 ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. coffeeMaker ๋Š” provider ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ coffeeComponent ์™€ ๊ฐ™์€ @CoffeeScope ์œผ๋กœ ์ •์˜ํ–ˆ๊ธฐ๋•Œ๋ฌธ์— coffeeComponent ๋‹น ํ•œ๊ฐœ์˜ CoffeeMaker ๋งŒ ์กด์žฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฒฐ๊ณผ๋Š” coffeeMaker1 = coffeeMaker2 != coffeeMaker3 ์ด ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ Non-scope ๋ถ€๋ถ„์„ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. CoffeeModule ์—์„œ CoffeeBean provider๋ฉ”์„œ๋“œ๋Š” scope์„ค์ •์„ ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ฐ™์€ coffeeComponent ์—์„œ CoffeeBean ์„ ์ƒ์„ฑํ•ด๋„ ์„œ๋กœ ๋‹ค๋ฅธ CoffeeBean ์ด ๋‚˜์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ coffeeBean1 != coffeeBean2 ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ ์œ„์—์„œ ์ง€๋‚˜์ณค๋˜ @Component.Builder ๊ณผ @Subcomponent.Builder ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. Dagger๋Š” component ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ builder pattern์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. @Component ์˜ ๊ฒฝ์šฐ ์ฝ”๋“œ๊ฐ€ generate ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ builder ์—ญ์‹œ generate ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ @Subcomponent ๋Š” @Component ํด๋ž˜์Šค ์•ˆ์—์„œ ์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ @Subcomponent.Builder ๊ฐ€ ๋ถ™์€ interface ๊ฐ€ ์—†์œผ๋ฉด builder ๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ @Subcomponent.Builder ๊ฐ€ ๊ผญ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Builder ์—๋Š” build ํ•˜๊ธฐ ์ „์— ๋ชจ๋“ˆ์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฉค๋ฒ„๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ชจ๋“ˆ์ด ์žˆ์„ ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์—์„œ ์ •์˜ํ•œ CafeModule์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€๊ฒฝํ•ด๋ด…์‹œ๋‹ค.

@Module(subcomponents = CoffeeComponent.class) 
public class CafeModule { 
    private String name; 
    public CafeModule(){ } 
    public CafeModule(String name){ 
        this.name = name; 
    } 
    
    @Singleton 
    @Provides 
    CafeInfo cafeInfo(){ 
        if(name == null || name.isEmpty()) 
            return new CafeInfo(); 
        else return new CafeInfo(name);
    } 
}

์ด์ œ CafeModule ์€ ์ƒ์„ฑ์ž์—์„œ ์นดํŽ˜ ์ด๋ฆ„์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ  ์ด๊ฒƒ์„ CafeInfo ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ ํ• ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ CafeComponent ์—์„œ Component Builder๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค.

public interface CafeComponent { 
    CafeInfo cafeInfo(); 
    CoffeeComponent.Builder coffeeComponent(); 
    
    @Component.Builder 
    interface Builder{ 
        Builder cafeModule(CafeModule cafeModule); 
        CafeComponent build(); 
    } 
}

์ด๋ ‡๊ฒŒ build ํ•˜๊ธฐ ์ „์— CafeModule ์„ ์ ์šฉ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

CafeComponent cafeComponent = DaggerCafeComponent.builder() 
        .cafeModule(new CafeModule("example cafe")) 
        .build(); 
cafeComponent.cafeInfo().welcome();

๊ทธ๋Ÿผ ์œ„ ์ฝ”๋“œ ์ฒ˜๋Ÿผ CafeComponent ์ƒ์„ฑ์‹œ ์นดํŽ˜์ด๋ฆ„์„ ์ ์šฉํ•œ ๋ชจ๋“ˆ์„ ๋ฏธ๋ฆฌ bind ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ณ  ์ด๋ฅผ ํ†ตํ•ด์„œ ์นดํŽ˜์ด๋ฆ„์„ ๊ฐ–๊ฒŒ ๋œ CafeInfo ๋ฅผ ์ œ๊ณต ๋ฐ›์„์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ Subcomponent ๊ณผ ๊ทธ์™€ ๊ด€๋ จ๋œ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์ด์ œ @Binds, MultiBinding ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. @Binds๋Š” ์ถ”์ƒ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ์ข€ ๋” ๊ฐ„๋žตํ•˜๊ฒŒ binding์„ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋จผ์ € CoffeeBean ์„ ์ƒ์†ํ•œ EthiopiaBean ์„ ์ •์˜ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class EthiopiaBean extends CoffeeBean{ 
    public void name(){ 
        System.out.println("EthiopiaBean"); 
    } 
}

๋งŒ์•ฝ ์–ด๋–ค ๋ชจ๋“ˆ์—์„œ EthiopiaBean ์˜ provider ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ๊ฑฐ๋‚˜ EthiopiaBean ์ด @Inject ๋ฅผ ํ†ตํ•ด Injectable ํ•œ ๊ฒƒ์œผ๋กœ ์ •์˜ ๋˜์–ด ์žˆ๋‹ค๋ฉด

@Binds 
abstract CoffeeBean provideCoffeeBean(EthiopiaBean ethiopiaBean);

์ด๋ ‡๊ฒŒ ์ถ”์ƒ๋ฉ”์„œ๋“œ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ CoffeeBean ๊ฐ์ฒด๋ฅผ ์ œ๊ณต๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ MultiBinding ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. Dagger ๋Š” ํ•œ ๊ฐ์ฒด๊ฐ€ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ˜•ํƒœ๋กœ binding ๊ฐ€๋Šฅ ํ•  ๋•Œ Set ์ด๋‚˜ Map์„ ์ด์šฉํ•ด์„œ MultiBinding ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉฐ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” CoffeeBean ์„ ์ƒ์†๋ฐ›์€ GuatemalaBean ์„ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class GuatemalaBean extends CoffeeBean { 
    public void name(){ 
        System.out.println("GuatemalaBean"); 
    } 
}

๊ทธ๋ฆฌ๊ณ  GuatemalaBean ๋„ EthiopiaBean ์ฒ˜๋Ÿผ CoffeeBean ์œผ๋กœ ๋ฐ”์ธ๋”ฉ ์‹œํ‚ค๋ ค๊ณ  ํ•˜๋ฉด CoffeeBean ๊ฐ์ฒด ์ œ๊ณต์‹œ ํ˜ผ๋ž€์„ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ MultiBinding ์„ ์ด์šฉํ•˜์—ฌ ํŠน์ • ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Binds 
@IntoMap 
@StringKey("ethiopia") 
abstract CoffeeBean provideEthiopiaBean(EthiopiaBean ethiopiaBean); 

@Binds 
@IntoMap 
@StringKey("guatemala") 
abstract CoffeeBean provideGuatemalaBean(GuatemalaBean guatemalaBean); 
// EthiopiaBean ์ฒ˜๋Ÿผ @Provide method ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์•„๋„ @Inject annotation์„ ์ด์šฉํ•ด Injectable ํ•œ ๊ฐ์ฒด๋กœ ์ •์˜ํ•ด๋„ bind ๊ฐ€๋Šฅ.

@IntoMap ๊ณผ @StringKey ๋ฅผ ์ด์šฉํ•˜์—ฌ Map ํ˜•ํƒœ๋กœ MultiBinding ํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. Map์œผ๋กœ MultiBinding ๋œ ๊ฒƒ์€ Map<key,object> ํ˜•ํƒœ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

Map<String,CoffeeBean> coffeeBeanMap(); // in CoffeeComponent

CoffeeComponent coffeeComponent = DaggerCafeComponent.create().coffeeComponent().build(); 
coffeeComponent.coffeeBeanMap().get("guatemala").name();

์œ„์™€ ๊ฐ™์ด ํ™œ์šฉ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์น˜๋ฉฐ

์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” ๊ฐ„๋‹จํ•œ DI์˜ˆ์ œ๋กœ DI์— ๋Œ€ํ•ด์„œ ์‚ดํŽด๋ณด์•˜๊ณ  cafe์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋ฉด์„œ DI๋ฅผ ํ™œ์šฉํ–ˆ์„ ๋•Œ ์–ด๋–ค ์žฅ์ ๋“ค์ด ์žˆ๋Š”์ง€, DI tool ๋“ค์€ ์ด๋Ÿฐ ์žฅ์ ์„ ์‰ฝ๊ฒŒ ์ ์šฉ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์–ด๋–ค ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•˜๋Š”์ง€ dagger ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. DI์— ๋Œ€ํ•ด์„œ ์ดํ•ดํ•˜๊ณ ์ž ํ•˜์‹œ๋Š” ๋ถ„๋“ค๊ป˜ ์กฐ๊ธˆ์ด๋‚˜๋งˆ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ํ•ฉ๋‹ˆ๋‹ค.

์ €ํฌ ๋ชจ๋ฐ”์ผํŒ€์—์„œ๋Š” Android์˜ ๊ฒฝ์šฐ Hilt, iOS์˜ ๊ฒฝ์šฐ Swinject์„ ํ†ตํ•ด DI๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ Part2. ํฌ์ŠคํŠธ์—์„œ๋Š” ๊ฐ ํ”Œ๋žซํผ ๋ณ„๋กœ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ์˜ DI๋ฅผ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”์ง€, ๋ชจ๋ฐ”์ผํŒ€์—์„œ DI๋ฅผ ์ ์šฉํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ๋ฐฉ๋ฒ•๊ณผ Hilt, Swinject๋ฅผ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

โ† ๋ชฉ๋ก์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ

Art Changes Life

๋…ธ๋จธ์Šค์™€ ํ•จ๊ป˜ ์—”ํ„ฐํ…Œํฌ ์‚ฐ์—…์„ ํ˜์‹ ํ•ด๋‚˜๊ฐˆ ๋ฉค๋ฒ„๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

์ฑ„์šฉ ์ค‘์ธ ๊ณต๊ณ  ๋ณด๊ธฐ