If tutorials available on this website are helpful for you, please whitelist this website in your ad blocker😭 or Donate to help us ❤️ pay for the web hosting to keep the website running.
NestJS में Circular Dependency एक ऐसा issue है जो तब होता है जब दो या दो से ज़्यादा modules या providers एक दुसरे पर directly या indirectly depend करते हैं, और यह loop create करते हैं जिससे application crash या unexpected behavior हो सकता है।
Circular dependencies को handle करना एक important aspect है जब आप scalable और maintainable applications build कर रहे होते हैं।
इस topic में हम समझेंगे कि Circular Dependency क्या होती है, यह कब होती है, कैसे इससे detect और fix किया जाता है, और कैसे हम NestJS में इस issue को avoid कर सकते हैं।
●●●
Circular Dependency तब होती है जब दो या दो से ज़्यादा modules या services एक दुसरे पर indirectly या directly depend करते हैं, जिससे एक loop create हो जाता है।
इसका मतलब, अगर Service A को Service B का instance चाहिए और Service B को Service A का, तो यह circular dependency
है।
For example
Service A → Depends on Service B
Service B → Depends on Service A
जब NestJS dependency injection system यह detect करता है, तो यह circular reference के कारण error throw करता है, या फिर application crash हो सकता है।
●●●
चलिए एक simple example देखते हैं जिसमे circular dependency introduce होती है।
File : src/services/service-a.ts
import { Injectable } from '@nestjs/common';
import { ServiceB } from './service-b';
@Injectable()
export class ServiceA {
constructor(private serviceB: ServiceB) {}
getServiceBMessage() {
return this.serviceB.getMessage();
}
}
File : src/services/service-b.ts
import { Injectable } from '@nestjs/common';
import { ServiceA } from './service-a';
@Injectable()
export class ServiceB {
constructor(private serviceA: ServiceA) {}
getMessage() {
return 'Hello from Service B!';
}
}
यहां -
Service A को Service B का instance चाहिए, और
Service B को Service A का instance चाहिए।
यह circular dependency है, क्योंकि दोनो services एक दुसरे पर depend कर रही हैं। यह NestJS के Dependency Injection
(DI) system को confuse कर सकती है और runtime errors
या crashes हो सकते हैं।
●●●
NestJS circular dependencies को detect करता है और error messages throw
करता है जिसमे आपको पता चल जाता है कि कौनसे providers circular dependency में फसे हुए हैं।
जब NestJS circular dependency detect करता है, तब आपको console में कुछ इस तरह का error
message मिल सकता है -
[ExceptionHandler] Circular dependency found: "ServiceA" <- "ServiceB"
इससे आपको पता चल जाता है कि circular dependency का loop कहा पर है।
●●●
Circular dependencies को fix करने का एक effective तरीका है forwardRef()
function का use. forwardRef()
NestJS को बताता है कि जब circular dependency introduce होती है, तो injection को defer कर दिया जाये जब तक दोनो services inject हो सकें।
forwardRef()
का use करते hue आप dependencies को handle कर सकते हैं बिना application को crash किये।
File : src/services/service-a.ts
import { Injectable, forwardRef, Inject } from '@nestjs/common';
import { ServiceB } from './service-b';
@Injectable()
export class ServiceA {
constructor(@Inject(forwardRef(() => ServiceB)) private serviceB: ServiceB) {}
getServiceBMessage() {
return this.serviceB.getMessage();
}
}
File : src/services/service-b.ts
import { Injectable, forwardRef, Inject } from '@nestjs/common';
import { ServiceA } from './service-a';
@Injectable()
export class ServiceB {
constructor(@Inject(forwardRef(() => ServiceA)) private serviceA: ServiceA) {}
getMessage() {
return 'Hello from Service B!';
}
}
यहां @Inject(forwardRef(() => ServiceA))
और @Inject(forwardRef(() => ServiceB))
का use किया गया है, जो circular dependencies को defer करता है जब तक services properly inject हो सकें।
आप interfaces
का use करके circular dependency को break कर सकते हैं। Interfaces का use करने से आप dependency injection को loosely couple कर सकते हैं।
Circular dependency को handle करने का एक और तरीका Event Emitters
का use करना है।
इस approach में, एक service दूसरी service का directly reference नहीं लेती, बल्कि events
के through data pass करती है।
●●●
चलिए एक practical example implement करते हैं जिसमे forwardRef() का use करके circular dependency को fix करते हैं।
File : src/services/service-a.ts
import { Injectable, Inject, forwardRef } from '@nestjs/common';
import { ServiceB } from './service-b';
@Injectable()
export class ServiceA {
constructor(@Inject(forwardRef(() => ServiceB)) private serviceB: ServiceB) {}
getServiceBMessage() {
return this.serviceB.getMessage();
}
getMessage() {
return 'Hello from Service A!';
}
}
File : src/services/service-b.ts
import { Injectable, Inject, forwardRef } from '@nestjs/common';
import { ServiceA } from './service-a';
@Injectable()
export class ServiceB {
constructor(@Inject(forwardRef(() => ServiceA)) private serviceA: ServiceA) {}
getMessage() {
return 'Hello from Service B!';
}
}
File : src/app.module.ts
import { Module, forwardRef } from '@nestjs/common';
import { ServiceA } from './services/service-a';
import { ServiceB } from './services/service-b';
@Module({
providers: [
forwardRef(() => ServiceA),
forwardRef(() => ServiceB),
],
exports: [ServiceA, ServiceB],
})
export class AppModule {}
यहां -
forwardRef() का use services को module में register करने के लिए किया है।
Circular dependency को properly handle किया गया है without causing runtime errors.
File : src/app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { ServiceA } from './services/service-a';
import { ServiceB } from './services/service-b';
@Controller()
export class AppController {
constructor(
private serviceA: ServiceA,
private serviceB: ServiceB
) {}
@Get('service-a')
getServiceAMessage() {
return this.serviceA.getMessage();
}
@Get('service-b')
getServiceBMessage() {
return this.serviceB.getMessage();
}
}
यहां Service A
और Service B
को inject किया गया है और उनके methods को call किया गया है।
●●●
Use forwardRef() Judiciously : forwardRef()
का use तभी करें जब आपको circular dependency का issue हो। इसका overuse avoid करें, क्योंकि यह application के design को complex बना सकता है।
Refactor Services : Circular dependencies को avoid करने के लिए services को refactor करें। अगर दो services एक दुसरे पर heavily depend कर रही हैं, तो यह code design issue हो सकता है।
Use Interfaces : Interfaces का use करके services को loosely couple करें, इससे आप circular dependencies को break कर सकते हैं।
Circular Dependency एक common issue है जो large-scale NestJS applications में आ सकता है, लेकिन इससे handle करना जरूरी होता है ताकि application का design clean और maintainable रहे।
इस topic में हमने समझा कि circular dependencies क्या होती हैं, कैसे forwardRef()
का use करके इहे resolve किया जा सकता है, और कैसे best practices का use करके circular dependencies को avoid किया जा सकता है।