tsyringe

๐ŸŽฒ TSyringe

TSyringe๋Š” ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.


๐Ÿ“ ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)

์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์„ ๋•Œ, ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ฐธ์กฐํ•  ๋•Œ, ์˜์กด์„ฑ์ด ์ƒ๊ธด๋‹ค. ์˜์กด์„ฑ ์ฃผ์ž…์€ ์ด๋Ÿฐ ์˜์กด์„ฑ์„ ๋А์Šจํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

๐Ÿ“ ์˜์กด์„ฑ ์ฃผ์ž…์˜ ์žฅ์ 

  • ์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ ์˜์กด์„ฑ์ด ์ค„์–ด๋“ค์–ด ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

  • ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์›Œ์ง„๋‹ค.

  • ๋ชจ์˜ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์‰ฌ์›Œ์ง„๋‹ค.


๐Ÿ“ reflect-metadata

practice code

// store/Store.ts
import 'reflect-metadata';

@singleton()
export default class Store {
    count = 0;

    listeners = new set();

    update() {
        this.listeners.forEach((listeners) => {
            listeners();
        })
    }

    addListener(listener) {
        this.listeners.add(listener);
    }

    removeListener(listener) {
        this.listeners.delete(listener);
    }
}

// component/CountControl.tsx
import { container } from "tsyringe";
import Store from "../store/Store";

export default function CountControl() {
    const store = container.resolve(Store);

    const handleClickIncrease = () => {
        store.count += 1;
        store.publish();
    }

    const handleClickDecrease = () => {
        store.count -= 1;
        store.publish();
    }

    return (
        <div>
        <button onClick={handleClickIncrease}>
            Increase
        </button>
         <button onClick={handleClickDecrease}>
            Decrease
        </button>
        </div>
    )
}
// component/Counter.tsx
import { container } from "tsyringe";
import Store from "../store/Store";

export default function Counter() {
    const store = container.resolve(Store);
    // ๊ฐ•์ œ ๋ฆฌ๋žœ๋”๋ง ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜
    const forceUpdate = useForceUpdate();

    store.forceUpdates.add(forceUpdate);

    useEffect(() => {
        store.addListener(forceUpdate);
        return () => {
            store.removeListener(forceUpdate);
        }
    }, [store, forceUpdate])

    return (
        <div>
            <p>{store.count}</p>
        </div>
    )
}
// App.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
const context = describe;

describe('APP', () => {

    beforeEach(() => {
        container.clearInstances();
    })

    context('when press increase button once', () => {
        test('counter', () => {
            render(<APP />);
    
            fireEvent.click(screen.getByText('Increase'));
    
            const elements = screen.getAllByText('1');
            expect(elements).toHaveLength(1);
        })
    })
})

๐Ÿ“ singleton (์‹ฑ๊ธ€ํ†ค)

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์€ ์ƒ์„ฑ์ž๊ฐ€ ์—ฌ๋Ÿฌ ์ฐจ๋ก€ ํ˜ธ์ถœ๋˜๋”๋ผ๋„ ์‹ค์ œ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด๋Š” ํ•˜๋‚˜์ด๊ณ , ์ตœ๊ณ  ์ƒ์„ฑ ์ดํ›„์— ํ˜ธ์ถœ๋œ ์ƒ์„ฑ์ž๋Š” ์ตœ์ดˆ์˜ ์ƒ์„ฑ์ž๊ฐ€ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

  • ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋งŒ ์กด์žฌํ•œ๋‹ค

  • ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.


โœ๏ธ ์ •๋ฆฌ

  • ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ

  • ๋” ๊ณต๋ถ€ํ•  ๊ฒƒ

Last updated