मुझे यह पता लगाने में कठिनाई हो रही है कि कब क्या उपयोग करना है। मैं DI को समझता हूं और वर्षों से ऐसा कर रहा हूं, लेकिन NestJS के भीतर ऐसा लगता है कि डॉक्स से कुछ चीजें गायब हैं जो मुझे यह समझने में मदद करेंगी कि इंजेक्शन वाली वस्तु से कुछ निर्दिष्ट गुण गायब क्यों हो जाते हैं।

हमारे पास एक लॉगर है जो एक कस्टम प्रदाता के माध्यम से इंजेक्शन हो जाता है।

दस्तावेज़ों को देखने से, वे कंस्ट्रक्टर क्षेत्र के दौरान @Inject जोड़ देंगे, लेकिन अगर मैं एक कस्टम प्रदाता के माध्यम से इंजेक्शन लगा रहा हूं, तो @Inject का उपयोग क्यों करें?

समान रूप से, @Injectable का उपयोग क्यों करें यदि हमारे पास मॉड्यूल के लिए सभी इंजेक्शन सेटअप को संभालने वाले कस्टम प्रदाता हैं?

जहां सवाल यह उठता है कि अन्य इंजेक्शन सेवाओं के बीच फ़ाइल नाम खो रहा है, जहां कभी-कभी जब लॉगर एक सेवा में निष्पादित हो जाता है, तो फ़ाइल नाम वही होता है, जबकि दूसरी बार सेवा अलग होती है, यह फ़ाइल नाम को सीटीआर नाम से बरकरार रखेगी एक अलग सेवा।

वैसे भी, मुझे समझ में नहीं आता कि एक सेट अप का उपयोग दूसरे पर क्यों किया जाए।

अद्यतन: मैंने पाया कि हम कुछ सेवाओं पर लाइफसाइकल का पालन करते हैं, लेकिन मुझे लगता है कि निष्पादन के समय लॉगर बरकरार नहीं रहता है।

//custom-provider
export ClientProvider = {
   provide: Client,
   userFactory: (logger: Logger): Client => {
        return new Client(logger);
   },
   inject: [Logger.getToken()]
};

//client
export class Client{
    private readonly logger;
    constructor(logger:Logger){
        this.logger = logger;
        if (this.logger) this.logger.fileName = this.constructor.name;
    }
}

//logger
export class Logger {
    static getToken(): string { return 'the-token-key'; }
    private filename: string;

    constructor(filename: string){
        this.filename = filename;
    }
}

//cat-service
export class CatService implements OnModuleInit {
    private readonly logger;
    constructor(@Inject(Logger.getToken()) private logger:Logger){
        this.logger = logger;
    }

    onModuleInit() {
       if (this.logger) this.logger.fileName = this.constructor.name;
    }
}

0
KellyTheDev 17 अप्रैल 2020, 18:13

1 उत्तर

सबसे बढ़िया उत्तर

तो, उच्च स्तर, नेस्ट स्वाभाविक रूप से टाइपस्क्रिप्ट से परिलक्षित मेटाडेटा का उपयोग यह जानने के लिए करता है कि क्या बाँधना है और कहाँ। आम तौर पर, यह मेटाडेटा क्लास नेम जैसी चीजें होती हैं जो रनटाइम पर मौजूद होती हैं, यही वजह है कि आप इंटरफेस का उपयोग नहीं कर सकते।

@Injectable() नेस्ट को बताता है कि उसे इस क्लास के कंस्ट्रक्टर में दिए गए मेटाडेटा की तलाश करनी चाहिए और सही प्रदाताओं को ढूंढना चाहिए। जैसा कि पहले उल्लेख किया गया है, इस तरह नेस्ट अधिकांश डीआई करता है।

@Inject() नेस्ट को बताता है, "अरे, मुझे पता है कि यह कहता है कि यह एक Logger वर्ग है, लेकिन वास्तव में प्रदाता को इंजेक्शन टोकन के साथ इंजेक्ट करें जो मैं आपको बताता हूं", जो विशिष्ट उदाहरणों का उपयोग करने जैसी चीजों के लिए उपयोगी है, कहते हैं, एक लकड़हारा वर्ग।

एक कस्टम प्रदाता के साथ, @Injectable() आवश्यक नहीं है यदि आप एक कारखाने का उपयोग करते हैं, जैसा कि आपने दिखाया है, लेकिन यह होगा यदि आप इसके बजाय एक वर्ग का उपयोग करते हैं, क्योंकि कारखाने प्रदान किए जाने वाले मूल्य का उदाहरण लौटाते हैं, जबकि useClass के साथ आप एक वर्ग परिभाषा लौटा रहे हैं जिसे Nest को तत्काल करने की आवश्यकता होगी।

आपके फ़ाइल नाम को ओवरराइट किए जाने का एकमात्र कारण यह है कि प्रदाता मॉड्यूल के बीच सिंगलटन स्कोप हैं, लेकिन यदि एक ही प्रदाता providers सरणी में है तो यह हर बार एक नया उदाहरण होना चाहिए, इसलिए शायद इसके साथ कुछ अभिनय कर रहा है थोड़ा विंकी won

1
Jay McDoniel 17 अप्रैल 2020, 19:54