[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"article-nestjs-weekly-dependency-injection-providers-scopes":44,"search-suggestions":460,"related-nestjs-weekly-dependency-injection-providers-scopes":501,"code:ts:true:b4d0t5":625,"code:ts:true:xq4anq":626,"code:ts:true:1ozwuyk":627,"code:ts:true:u77qf4":628,"code:ts:true:1uelzq0":629,"code:ts:true:wxaszb":630,"code:ts:true:xpr7nb":631,"code:ts:true:5676qx":632,"code:ts:true:e8e882":633,"code:ts:true:1v8q078":634,"code:ts:true:1xdn7li":635,"comments-01a05e06-53b7-7415-9cd3-05504882514b":636},[4,20,32],{"id":5,"slug":6,"name":7,"tagline":8,"description":9,"accentFrom":10,"accentTo":11,"icon":12,"defaultLocale":13,"locales":14,"features":16,"position":19},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Read it. Run it. Prove it.","A post a day on modern web development — most with an editable playground and a quiz that explains every answer. Free, no account needed.","violet-500","cyan-400","◇","en",[13,15],"fa",{"courses":17,"paths":17,"articles":17,"exams":18,"flashcards":18,"packages":17,"community":17,"certificates":17,"teams":17,"commerce":17},true,false,0,{"id":21,"slug":22,"name":23,"tagline":24,"description":25,"accentFrom":26,"accentTo":10,"icon":27,"defaultLocale":13,"locales":28,"features":30,"position":31},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Grammar explained the way good documentation explains an API — one idea at a time, each with a quiz.","amber-400","⌘",[13,15,29],"es",{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":17,"packages":18,"community":17,"certificates":17,"teams":18,"commerce":18},2,{"id":33,"slug":34,"name":35,"tagline":36,"description":37,"accentFrom":38,"accentTo":39,"icon":40,"defaultLocale":13,"locales":41,"features":42,"position":43},"7b3c16f2-931d-410e-802e-e1fa4edab7de","soft","Soft Skills","The half of the job nobody wrote documentation for.","Weekly, on the parts of working life that decide more than your code does — first weeks, meetings, interviews, promotions, and the people around you. Written from what actually happens, and recorded as a podcast you can listen to on the walk.","emerald-400","teal-300","◉",[13],{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":18,"packages":18,"community":17,"certificates":18,"teams":18,"commerce":18},3,{"id":45,"slug":46,"title":47,"subtitle":48,"excerpt":49,"coverUrl":50,"locale":13,"readingMinutes":51,"publishedAt":52,"viewCount":53,"likeCount":19,"commentCount":19,"author":54,"vertical":59,"topic":60,"tags":63,"_count":74,"playground":76,"body":78,"bodyMd":435,"seo":436,"translationGroupId":438,"series":439,"podcastUrl":48,"verticalId":5,"thread":448,"assessments":450,"translations":456,"quiz":458},"01a05e06-53b7-7415-9cd3-05504882514b","nestjs-weekly-dependency-injection-providers-scopes","NestJS Dependency Injection Explained (with Cheat Sheet)",null,"How the NestJS DI container resolves providers: tokens, module scope, singleton vs request vs transient, and why 'singleton' can still mean two instances.","\u002Fmedia\u002Fcovers\u002Fnestjs-weekly-dependency-injection-providers-scopes.png",14,"2026-09-04T10:58:05.602Z",27,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},"nestjs","Nestjs",[64,67,70,73],{"slug":65,"name":66,"color":48},"typescript","Typescript",{"slug":68,"name":69,"color":48},"node","Node",{"slug":71,"name":72,"color":48},"tutorial","Tutorial",{"slug":61,"name":62,"color":48},{"assessments":75},1,{"slug":46,"title":77},"NestJS DI container — interactive playground",{"blocks":79,"version":75},[80,84,87,92,95,104,107,110,113,116,130,134,137,143,147,151,154,157,160,163,166,169,173,177,181,184,187,190,193,196,199,202,205,208,212,215,218,221,225,228,232,235,239,242,245,248,252,256,259,262,265,268,271,274,277,280,288,291,300,303,306,309,312,315,318,321,324,327,330,333,336,340,343,346,349,352,404,407,414,417,420,423,426,429],{"id":81,"html":82,"type":83},"b1","\u003Cp>Two feature modules, \u003Ccode>OrdersModule\u003C\u002Fcode> and \u003Ccode>BillingModule\u003C\u002Fcode>, both list \u003Ccode>CacheService\u003C\u002Fcode> in their \u003Ccode>providers\u003C\u002Fcode> array. Both inject it in a constructor. Both call \u003Ccode>cache.increment(&#39;hits&#39;)\u003C\u002Fcode>. In staging, the counter never goes above the value each module produced on its own — \u003Ccode>OrdersModule\u003C\u002Fcode> reports 40 hits, \u003Ccode>BillingModule\u003C\u002Fcode> reports 12, and the total the dashboard shows is wrong by definition, because there&#39;s no single counter to be wrong about.\u003C\u002Fp>","paragraph",{"id":85,"html":86,"type":83},"b2","\u003Cp>\u003Ccode>CacheService\u003C\u002Fcode> is decorated with \u003Ccode>@Injectable()\u003C\u002Fcode>. Nobody set a scope. By every definition you&#39;ve read, it&#39;s a singleton. It is — just not the singleton you assumed.\u003C\u002Fp>",{"id":88,"html":89,"text":90,"type":91,"level":31},"b3","What you&#39;ll learn","What you'll learn","heading",{"id":93,"html":94,"type":83},"b4","\u003Cp>By the end of this article you&#39;ll be able to:\u003C\u002Fp>",{"id":96,"type":97,"items":98,"ordered":18},"b5","list",[99,100,101,102,103],"Explain what NestJS&#39;s dependency injection (DI) container actually does when it sees \u003Ccode>constructor(private readonly cache: CacheService)\u003C\u002Fcode>","State precisely what &quot;singleton&quot; means in Nest — and why the same \u003Ccode>@Injectable()\u003C\u002Fcode> class can end up as two separate instances","Choose between \u003Ccode>useValue\u003C\u002Fcode>, \u003Ccode>useClass\u003C\u002Fcode>, \u003Ccode>useFactory\u003C\u002Fcode>, and \u003Ccode>useExisting\u003C\u002Fcode> when a provider needs more than a bare class","Pick the right provider scope (\u003Ccode>DEFAULT\u003C\u002Fcode>, \u003Ccode>REQUEST\u003C\u002Fcode>, \u003Ccode>TRANSIENT\u003C\u002Fcode>) and predict the performance and correctness consequences of each","Recognize when a provider&#39;s scope &quot;bubbles up&quot; and forces something else in your app to become request-scoped too",{"id":105,"html":106,"text":106,"type":91,"level":31},"b6","Who this is for",{"id":108,"html":109,"type":83},"b7","\u003Cp>You&#39;ve written at least one NestJS service with \u003Ccode>@Injectable()\u003C\u002Fcode> and injected it into a controller&#39;s constructor. You don&#39;t need to have written a custom provider, a factory, or a scoped provider yet — we&#39;ll build all three from nothing.\u003C\u002Fp>",{"id":111,"html":112,"type":83},"b8","\u003Cp>This article is written against \u003Cstrong>NestJS 12.x\u003C\u002Fstrong> (verified against the \u003Ccode>nestjs\u002Fnest\u003C\u002Fcode> GitHub release history — \u003Ccode>v12.0.0\u003C\u002Fcode> shipped August 27, 2026). Provider registration and scopes are core-container behavior, unchanged in shape across the 10.x → 12.x line; nothing here depends on the v12 ESM migration specifically.\u003C\u002Fp>",{"id":114,"html":115,"text":115,"type":91,"level":31},"b9","Table of contents",{"id":117,"type":97,"items":118,"ordered":18},"b10",[119,120,121,122,123,124,125,126,127,128,129],"\u003Ca href=\"#the-problem-a-singleton-that-isnt\">The problem: a singleton that isn&#39;t\u003C\u002Fa>","\u003Ca href=\"#the-mental-model-registrations-not-classes\">The mental model: registrations, not classes\u003C\u002Fa>","\u003Ca href=\"#stage-1-the-simplest-provider\">Stage 1: the simplest provider\u003C\u002Fa>","\u003Ca href=\"#stage-2-sharing-one-instance-across-modules\">Stage 2: sharing one instance across modules\u003C\u002Fa>","\u003Ca href=\"#stage-3-custom-providers-when-a-class-isnt-enough\">Stage 3: custom providers — when a class isn&#39;t enough\u003C\u002Fa>","\u003Ca href=\"#stage-4-provider-scopes-default-request-transient\">Stage 4: provider scopes — DEFAULT, REQUEST, TRANSIENT\u003C\u002Fa>","\u003Ca href=\"#stage-5-scope-bubbling\">Stage 5: scope bubbling\u003C\u002Fa>","\u003Ca href=\"#edge-cases-and-gotchas\">Edge cases and gotchas\u003C\u002Fa>","\u003Ca href=\"#best-practices\">Best practices\u003C\u002Fa>","\u003Ca href=\"#faq\">FAQ\u003C\u002Fa>","\u003Ca href=\"#cheat-sheet\">Cheat sheet\u003C\u002Fa>",{"id":131,"html":132,"text":133,"type":91,"level":31},"b11","The problem: a singleton that isn&#39;t","The problem: a singleton that isn't",{"id":135,"html":136,"type":83},"b12","\u003Cp>Here&#39;s the setup, trimmed to the part that matters:\u003C\u002Fp>",{"id":138,"code":139,"type":140,"language":141,"highlight":142},"b13","\u002F\u002F cache.service.ts\n@Injectable()\nexport class CacheService {\n  private hits = 0;\n  increment(key: string) {\n    this.hits++;\n    return this.hits;\n  }\n}","code","ts",[],{"id":144,"code":145,"type":140,"language":141,"highlight":146},"b14","\u002F\u002F orders.module.ts\n@Module({\n  controllers: [OrdersController],\n  providers: [OrdersService, CacheService],\n})\nexport class OrdersModule {}",[],{"id":148,"code":149,"type":140,"language":141,"highlight":150},"b15","\u002F\u002F billing.module.ts\n@Module({\n  controllers: [BillingController],\n  providers: [BillingService, CacheService],\n})\nexport class BillingModule {}",[],{"id":152,"html":153,"type":83},"b16","\u003Cp>Both \u003Ccode>OrdersService\u003C\u002Fcode> and \u003Ccode>BillingService\u003C\u002Fcode> inject \u003Ccode>CacheService\u003C\u002Fcode> through their constructors. Both trust that &quot;singleton&quot; means what it usually means in a dependency-injection framework: one instance, shared by whoever asks for it. That trust is reasonable — and wrong here, because of one detail that&#39;s easy to skim past: \u003Cstrong>\u003Ccode>CacheService\u003C\u002Fcode> appears in the \u003Ccode>providers\u003C\u002Fcode> array of two different modules.\u003C\u002Fstrong>\u003C\u002Fp>",{"id":155,"html":156,"type":83},"b17","\u003Cp>Nest doesn&#39;t ask &quot;has this class been instantiated anywhere in the app?&quot; It asks &quot;has this token been registered in \u003Cem>this module&#39;s\u003C\u002Fem> injector?&quot; \u003Ccode>OrdersModule\u003C\u002Fcode> and \u003Ccode>BillingModule\u003C\u002Fcode> never import each other or a shared module that exports \u003Ccode>CacheService\u003C\u002Fcode>, so Nest treats the two listings as two independent registrations — and builds two independent instances. Each service gets a real, working, entirely singleton \u003Ccode>CacheService\u003C\u002Fcode>. They&#39;re just not the \u003Cem>same\u003C\u002Fem> one.\u003C\u002Fp>",{"id":158,"html":159,"text":159,"type":91,"level":31},"b18","The mental model: registrations, not classes",{"id":161,"html":162,"type":83},"b19","\u003Cp>\u003Cstrong>The mental model:\u003C\u002Fstrong> NestJS&#39;s DI container isn&#39;t one global map from class to instance. It&#39;s a \u003Cstrong>tree of injectors, one per module\u003C\u002Fstrong>, and each injector only knows about the providers \u003Cem>that module registered\u003C\u002Fem> — either directly in its own \u003Ccode>providers\u003C\u002Fcode> array, or indirectly, imported from another module that \u003Ccode>export\u003C\u002Fcode>s them.\u003C\u002Fp>",{"id":164,"html":165,"type":83},"b20","\u003Cp>A provider&#39;s real identity is its \u003Cstrong>token\u003C\u002Fstrong> (by default, the class itself) \u003Cem>plus\u003C\u002Fem> \u003Cstrong>where it was registered\u003C\u002Fstrong>. &quot;Singleton&quot; is a promise about a registration, not about a class name: \u003Cem>within one injector&#39;s scope, this token resolves to one instance, created once.\u003C\u002Fem> If a class gets registered twice — once per module, with no import\u002Fexport connecting the two — you get two injectors, two registrations, two honestly-singleton instances that have never met.\u003C\u002Fp>",{"id":167,"html":168,"type":83},"b21","\u003Cp>This is why \u003Ccode>exports\u003C\u002Fcode> matters so much in Nest, and it&#39;s the missing piece in the bug above: to actually share one \u003Ccode>CacheService\u003C\u002Fcode>, exactly one module should own it and export it, and every consumer should import that module instead of re-listing the class.\u003C\u002Fp>",{"id":170,"code":171,"type":140,"language":141,"highlight":172},"b22","\u002F\u002F cache.module.ts\n@Module({\n  providers: [CacheService],\n  exports: [CacheService],\n})\nexport class CacheModule {}",[],{"id":174,"code":175,"type":140,"language":141,"highlight":176},"b23","\u002F\u002F orders.module.ts\n@Module({\n  imports: [CacheModule],\n  controllers: [OrdersController],\n  providers: [OrdersService], \u002F\u002F CacheService is NOT listed here\n})\nexport class OrdersModule {}",[],{"id":178,"code":179,"type":140,"language":141,"highlight":180},"b24","\u002F\u002F billing.module.ts\n@Module({\n  imports: [CacheModule],\n  controllers: [BillingController],\n  providers: [BillingService], \u002F\u002F CacheService is NOT listed here either\n})\nexport class BillingModule {}",[],{"id":182,"html":183,"type":83},"b25","\u003Cp>Now there&#39;s exactly one registration of \u003Ccode>CacheService\u003C\u002Fcode>, owned by \u003Ccode>CacheModule\u003C\u002Fcode>. \u003Ccode>OrdersModule\u003C\u002Fcode> and \u003Ccode>BillingModule\u003C\u002Fcode> both import it, so Nest resolves the same token to the same instance in both — one counter, correctly shared.\u003C\u002Fp>",{"id":185,"html":186,"type":83},"b26","\u003Cp>\u003Cstrong>Key concept:\u003C\u002Fstrong> if you want one instance across your app, register the provider in exactly one place and \u003Cem>import\u003C\u002Fem> it everywhere else. Never re-list the class in a second module&#39;s \u003Ccode>providers\u003C\u002Fcode> array &quot;to be safe&quot; — that&#39;s the line that creates the second instance.\u003C\u002Fp>",{"id":188,"html":189,"type":83},"b27","\u003C!-- playground:start -->",{"id":191,"html":192,"text":192,"type":91,"level":31},"b28","🎮 Try it yourself",{"id":194,"html":195,"type":83},"b29","\u003Cp>\u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fnestjs-weekly-dependency-injection-providers-scopes\u002Fplayground\">▶️ Open the interactive playground →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":197,"html":198,"type":83},"b30","\u003Cp>\u003Cem>Runs right in your browser — poke at it and watch the concept react live.\u003C\u002Fem>\u003C\u002Fp>",{"id":200,"html":201,"type":83},"b31","\u003C!-- playground:end -->",{"id":203,"html":204,"text":204,"type":91,"level":31},"b32","Stage 1: the simplest provider",{"id":206,"html":207,"type":83},"b33","\u003Cp>The smallest possible provider is just a decorated class:\u003C\u002Fp>",{"id":209,"code":210,"type":140,"language":141,"highlight":211},"b34","@Injectable()\nexport class GreetingService {\n  greet(name: string) {\n    return `Hello, ${name}`;\n  }\n}",[],{"id":213,"html":214,"type":83},"b35","\u003Cp>\u003Ccode>@Injectable()\u003C\u002Fcode> marks the class as something Nest&#39;s container is allowed to manage. Listing it in a module&#39;s \u003Ccode>providers\u003C\u002Fcode> array registers it — Nest instantiates it once, resolving its own constructor dependencies first (constructor injection is recursive: if \u003Ccode>GreetingService\u003C\u002Fcode> needed a \u003Ccode>LoggerService\u003C\u002Fcode>, Nest would build that first). Anything that injects \u003Ccode>GreetingService\u003C\u002Fcode> via its constructor type gets the same instance, because the class itself doubles as its injection \u003Cstrong>token\u003C\u002Fstrong>.\u003C\u002Fp>",{"id":216,"html":217,"text":217,"type":91,"level":31},"b36","Stage 2: sharing one instance across modules",{"id":219,"html":220,"type":83},"b37","\u003Cp>Covered above — the fix is \u003Ccode>exports\u003C\u002Fcode> plus \u003Ccode>imports\u003C\u002Fcode>, not a second \u003Ccode>providers\u003C\u002Fcode> listing. It&#39;s worth restating as a rule, because it&#39;s the single most common DI mistake in a growing Nest app: \u003Cstrong>a provider is shared by being exported and imported, never by being declared twice.\u003C\u002Fstrong>\u003C\u002Fp>",{"id":222,"html":223,"text":224,"type":91,"level":31},"b38","Stage 3: custom providers — when a class isn&#39;t enough","Stage 3: custom providers — when a class isn't enough",{"id":226,"html":227,"type":83},"b39","\u003Cp>Not every dependency is &quot;a class Nest can \u003Ccode>new\u003C\u002Fcode> up.&quot; Configuration objects, third-party SDK clients, and values that depend on other providers all need something more flexible than the shorthand \u003Ccode>providers: [CacheService]\u003C\u002Fcode>. Nest&#39;s provider registration accepts a full object instead, keyed by \u003Ccode>provide\u003C\u002Fcode> (the token) and one of four resolution strategies:\u003C\u002Fp>",{"id":229,"code":230,"type":140,"language":141,"highlight":231},"b40","@Module({\n  providers: [\n    \u002F\u002F useValue — hand Nest an already-built value\n    { provide: 'API_BASE_URL', useValue: 'https:\u002F\u002Fapi.example.com' },\n\n    \u002F\u002F useClass — pick the implementation at registration time\n    { provide: PaymentsGateway, useClass: StripeGateway },\n\n    \u002F\u002F useFactory — build the value at runtime, with its own dependencies\n    {\n      provide: 'DB_CONNECTION',\n      useFactory: (config: ConfigService) => createConnection(config.get('DB_URL')),\n      inject: [ConfigService],\n    },\n\n    \u002F\u002F useExisting — an alias: a second token pointing at the same instance\n    { provide: 'LEGACY_CACHE', useExisting: CacheService },\n  ],\n})\nexport class AppModule {}",[],{"id":233,"html":234,"type":83},"b41","\u003Cp>\u003Ccode>&#39;API_BASE_URL&#39;\u003C\u002Fcode> and \u003Ccode>&#39;DB_CONNECTION&#39;\u003C\u002Fcode> are \u003Cstrong>string tokens\u003C\u002Fstrong> — the class-as-token trick only works when the dependency is a class, so a plain value or an interface needs an explicit token instead. Injecting one of these requires \u003Ccode>@Inject()\u003C\u002Fcode>, since there&#39;s no type for Nest to read off the constructor parameter:\u003C\u002Fp>",{"id":236,"code":237,"type":140,"language":141,"highlight":238},"b42","@Injectable()\nexport class PaymentsService {\n  constructor(@Inject('API_BASE_URL') private readonly baseUrl: string) {}\n}",[],{"id":240,"html":241,"type":83},"b43","\u003Cp>\u003Cstrong>Key concept:\u003C\u002Fstrong> \u003Ccode>useValue\u003C\u002Fcode>, \u003Ccode>useClass\u003C\u002Fcode>, \u003Ccode>useFactory\u003C\u002Fcode>, and \u003Ccode>useExisting\u003C\u002Fcode> are four ways to answer the same question — &quot;what does this token resolve to?&quot; — not four unrelated features. \u003Ccode>useFactory\u003C\u002Fcode>&#39;s \u003Ccode>inject\u003C\u002Fcode> array is exactly the same resolution the container already does for constructors; it&#39;s just spelled out explicitly because a factory function has no constructor for Nest to inspect.\u003C\u002Fp>",{"id":243,"html":244,"text":244,"type":91,"level":31},"b44","Stage 4: provider scopes — DEFAULT, REQUEST, TRANSIENT",{"id":246,"html":247,"type":83},"b45","\u003Cp>Everything so far assumes the default: one instance, created once at bootstrap, reused for the life of the process. That&#39;s \u003Ccode>Scope.DEFAULT\u003C\u002Fcode>, and you never write it — it&#39;s what \u003Ccode>@Injectable()\u003C\u002Fcode> means with no options. Two other scopes exist, each trading that simplicity for something a shared singleton can&#39;t do:\u003C\u002Fp>",{"id":249,"code":250,"type":140,"language":141,"highlight":251},"b46","@Injectable({ scope: Scope.REQUEST })\nexport class RequestContextService {\n  \u002F\u002F A new instance is created for every incoming request,\n  \u002F\u002F and garbage-collected once that request finishes.\n}",[],{"id":253,"code":254,"type":140,"language":141,"highlight":255},"b47","@Injectable({ scope: Scope.TRANSIENT })\nexport class LoggerService {\n  \u002F\u002F A new instance is created for every consumer that injects it —\n  \u002F\u002F not shared, not tied to a request.\n}",[],{"id":257,"html":258,"type":83},"b48","\u003Cp>\u003Ccode>REQUEST\u003C\u002Fcode> scope is for state that&#39;s genuinely per-request — the authenticated user, a request ID for tracing, tenant context in a multi-tenant app. \u003Ccode>TRANSIENT\u003C\u002Fcode> is for the rarer case where you don&#39;t want sharing at all, even within one request — a logger that should carry the name of whichever class asked for it is the textbook example.\u003C\u002Fp>",{"id":260,"html":261,"type":83},"b49","\u003Cp>Both cost something a singleton doesn&#39;t. NestJS&#39;s own documentation is explicit that request-scoped providers affect performance, because the container can no longer build the dependency graph once at bootstrap — it has to rebuild the request-scoped branch on every request. A properly designed app shouldn&#39;t lose more than roughly 5% latency to it, but &quot;properly designed&quot; is doing real work in that sentence: reach for \u003Ccode>REQUEST\u003C\u002Fcode> scope only for state that actually varies per request, not as a default habit.\u003C\u002Fp>",{"id":263,"html":264,"type":83},"b50","\u003Cp>For multi-tenant apps where many requests share the same tenant, Nest also supports \u003Cstrong>durable providers\u003C\u002Fstrong> — \u003Ccode>@Injectable({ scope: Scope.REQUEST, durable: true })\u003C\u002Fcode> — which let the container reuse a request-scoped sub-tree across requests that share a common attribute (like a tenant ID) instead of rebuilding it every single time.\u003C\u002Fp>",{"id":266,"html":267,"text":267,"type":91,"level":31},"b51","Stage 5: scope bubbling",{"id":269,"html":270,"type":83},"b52","\u003Cp>Scopes aren&#39;t isolated to the provider that declares them. If \u003Ccode>OrdersController\u003C\u002Fcode> injects \u003Ccode>RequestContextService\u003C\u002Fcode> (request-scoped) directly, \u003Ccode>OrdersController\u003C\u002Fcode> itself becomes request-scoped — Nest has to create a new controller instance per request too, because it can&#39;t build a \u003Ccode>DEFAULT\u003C\u002Fcode>-scoped controller once and hand it a dependency that only exists per-request. This is called \u003Cstrong>scope bubbling\u003C\u002Fstrong>: request scope propagates up the entire chain of things that (directly or transitively) depend on it.\u003C\u002Fp>",{"id":272,"html":273,"type":83},"b53","\u003Cp>\u003Ccode>TRANSIENT\u003C\u002Fcode> doesn&#39;t bubble the same way. A \u003Ccode>DEFAULT\u003C\u002Fcode>-scoped service that injects a \u003Ccode>TRANSIENT\u003C\u002Fcode> logger stays \u003Ccode>DEFAULT\u003C\u002Fcode>-scoped — it just gets its own private logger instance, created once, same as any other dependency at bootstrap. Transience only means &quot;not shared between different consumers,&quot; not &quot;recreated per request.&quot;\u003C\u002Fp>",{"id":275,"html":276,"type":83},"b54","\u003Cp>\u003Cstrong>Key concept:\u003C\u002Fstrong> before marking any provider \u003Ccode>REQUEST\u003C\u002Fcode>-scoped, check what already depends on it. One request-scoped leaf can turn an entire branch of your app — including controllers — into something rebuilt on every single request.\u003C\u002Fp>",{"id":278,"html":279,"text":279,"type":91,"level":31},"b55","Edge cases and gotchas",{"id":281,"type":97,"items":282,"ordered":18},"b56",[283,284,285,286,287],"\u003Cstrong>Two \u003Ccode>providers\u003C\u002Fcode> listings, zero shared state.\u003C\u002Fstrong> The bug that opened this article. If a &quot;singleton&quot; seems to be losing state, check whether it&#39;s registered in more than one module instead of exported from one and imported everywhere else.","\u003Cstrong>Circular provider dependencies.\u003C\u002Fstrong> If \u003Ccode>ServiceA\u003C\u002Fcode> needs \u003Ccode>ServiceB\u003C\u002Fcode> and \u003Ccode>ServiceB\u003C\u002Fcode> needs \u003Ccode>ServiceA\u003C\u002Fcode>, Nest can&#39;t decide which to build first. \u003Ccode>forwardRef(() =&gt; ServiceB)\u003C\u002Fcode> on both sides breaks the deadlock — but a true circular dependency between services is usually a sign one of them should be split.","\u003Cstrong>Injecting a request-scoped provider into a \u003Ccode>DEFAULT\u003C\u002Fcode>-scoped one you don&#39;t control\u003C\u002Fstrong> (a library service, for instance) silently makes \u003Cem>that\u003C\u002Fem> dependency chain request-scoped too, even though nothing about its own code changed. The bubbling happens at the injection site, not the declaration site.","\u003Cstrong>\u003Ccode>useFactory\u003C\u002Fcode> dependencies must be listed in \u003Ccode>inject\u003C\u002Fcode>, in the same order as the factory&#39;s parameters.\u003C\u002Fstrong> Nest resolves them positionally; a factory that takes \u003Ccode>(config, logger)\u003C\u002Fcode> but declares \u003Ccode>inject: [LoggerService, ConfigService]\u003C\u002Fcode> will hand each argument the wrong provider, with no error — just quietly wrong values.","\u003Cstrong>String tokens collide across modules if you&#39;re not careful.\u003C\u002Fstrong> \u003Ccode>&#39;CACHE&#39;\u003C\u002Fcode> in one module and \u003Ccode>&#39;CACHE&#39;\u003C\u002Fcode> in another are the \u003Cem>same\u003C\u002Fem> token as far as a shared injector is concerned. Prefer a \u003Ccode>Symbol()\u003C\u002Fcode> or an app-wide constants file for non-class tokens once you have more than a couple.",{"id":289,"html":290,"text":290,"type":91,"level":31},"b57","Best practices",{"id":292,"type":97,"items":293,"ordered":18},"b58",[294,295,296,297,298,299],"\u003Cstrong>Default to \u003Ccode>Scope.DEFAULT\u003C\u002Fcode>.\u003C\u002Fstrong> It&#39;s the fastest option and correct for the overwhelming majority of providers — anything that doesn&#39;t hold per-request state.","\u003Cstrong>Own shared providers in one module, export them, and import that module everywhere else.\u003C\u002Fstrong> Never re-declare the same class in two \u003Ccode>providers\u003C\u002Fcode> arrays as a shortcut.","\u003Cstrong>Reach for \u003Ccode>REQUEST\u003C\u002Fcode> scope only for data that&#39;s truly per-request\u003C\u002Fstrong> (the current user, a correlation ID, tenant context) — and remember it will make everything upstream of it request-scoped too.","\u003Cstrong>Reach for \u003Ccode>TRANSIENT\u003C\u002Fcode> scope only when sharing would actually cause a bug\u003C\u002Fstrong> — a logger that should identify its caller is the common case; most services don&#39;t need it.","\u003Cstrong>Use string\u002Fsymbol tokens for anything that isn&#39;t a class\u003C\u002Fstrong> — config values, third-party clients, interfaces — and keep them in one place so two modules never accidentally collide on the same string.","\u003Cstrong>In tests, override providers rather than constructing real ones.\u003C\u002Fstrong> \u003Ccode>Test.createTestingModule({...}).overrideProvider(CacheService).useValue(fakeCache)\u003C\u002Fcode> swaps a token&#39;s resolution for a test double without touching how the rest of the module is wired — it&#39;s the exact same token\u002Fregistration mechanism this article covers, aimed at a test double instead of the real class.",{"id":301,"html":302,"type":83},"b59","\u003C!-- quiz:start -->",{"id":304,"html":305,"text":305,"type":91,"level":31},"b60","🧠 Test yourself",{"id":307,"html":308,"type":83},"b61","\u003Cp>Think it clicked? \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fnestjs-weekly-dependency-injection-providers-scopes\u002Fquiz\">Take the 9-question quiz →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":310,"html":311,"type":83},"b62","\u003Cp>\u003Cem>Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.\u003C\u002Fem>\u003C\u002Fp>",{"id":313,"html":314,"type":83},"b63","\u003C!-- quiz:end -->",{"id":316,"html":317,"text":317,"type":91,"level":31},"b64","FAQ",{"id":319,"html":320,"text":320,"type":91,"level":43},"b65","Is a NestJS provider actually a singleton?",{"id":322,"html":323,"type":83},"b66","\u003Cp>Within one registration, yes — \u003Ccode>DEFAULT\u003C\u002Fcode> scope guarantees one instance for the life of the app for that specific registration. It is not automatically an app-wide singleton if the same class is registered separately in more than one module; that produces multiple, independently &quot;singleton&quot; instances.\u003C\u002Fp>",{"id":325,"html":326,"text":326,"type":91,"level":43},"b67","How do I get two different instances of the same service on purpose?",{"id":328,"html":329,"type":83},"b68","\u003Cp>Either mark it \u003Ccode>Scope.TRANSIENT\u003C\u002Fcode> (a fresh instance per consumer), or register it twice under two different tokens using \u003Ccode>useClass\u003C\u002Fcode> — e.g. \u003Ccode>{ provide: &#39;PRIMARY_DB&#39;, useClass: DbConnection }\u003C\u002Fcode> and \u003Ccode>{ provide: &#39;REPLICA_DB&#39;, useClass: DbConnection }\u003C\u002Fcode>.\u003C\u002Fp>",{"id":331,"html":332,"text":332,"type":91,"level":43},"b69","Does exporting a provider create a new instance?",{"id":334,"html":335,"type":83},"b70","\u003Cp>No. \u003Ccode>exports\u003C\u002Fcode> doesn&#39;t instantiate anything — it makes an existing registration visible to modules that \u003Ccode>import\u003C\u002Fcode> the module doing the exporting. The instance is still created once, by whichever module has it in \u003Ccode>providers\u003C\u002Fcode>.\u003C\u002Fp>",{"id":337,"html":338,"text":339,"type":91,"level":43},"b71","Why does \u003Ccode>@Inject()\u003C\u002Fcode> show up on some constructor parameters and not others?","Why does @Inject() show up on some constructor parameters and not others?",{"id":341,"html":342,"type":83},"b72","\u003Cp>Nest can use a class as its own injection token automatically, because TypeScript&#39;s type metadata gives it something to match. A string, symbol, or interface token has no runtime type to read, so \u003Ccode>@Inject(&#39;TOKEN&#39;)\u003C\u002Fcode> tells Nest explicitly what to resolve.\u003C\u002Fp>",{"id":344,"html":345,"text":345,"type":91,"level":43},"b73","Does REQUEST scope work the same way in WebSocket gateways and microservices?",{"id":347,"html":348,"type":83},"b74","\u003Cp>Request-scoped providers are supported outside plain HTTP controllers too, but &quot;request&quot; means whatever triggers a handler in that transport (a socket event, a message) — always check that the perf tradeoff still makes sense for a transport that may see much higher throughput than typical HTTP traffic.\u003C\u002Fp>",{"id":350,"html":351,"text":351,"type":91,"level":31},"b75","Cheat sheet",{"id":353,"head":354,"rows":358,"type":403},"b76",[355,356,357],"Need","Syntax","Notes",[359,363,367,371,375,379,383,387,391,395,399],[360,361,362],"Basic provider","\u003Ccode>providers: [MyService]\u003C\u002Fcode>","Shorthand for \u003Ccode>{ provide: MyService, useClass: MyService }\u003C\u002Fcode>",[364,365,366],"Share one instance across modules","Export from an owner module, \u003Ccode>imports\u003C\u002Fcode> it elsewhere","Never re-list the class in a second \u003Ccode>providers\u003C\u002Fcode> array",[368,369,370],"Provide a plain value","\u003Ccode>{ provide: &#39;TOKEN&#39;, useValue: x }\u003C\u002Fcode>","Needs \u003Ccode>@Inject(&#39;TOKEN&#39;)\u003C\u002Fcode> at the injection site",[372,373,374],"Swap implementations","\u003Ccode>{ provide: Base, useClass: Impl }\u003C\u002Fcode>","Consumers still inject \u003Ccode>Base\u003C\u002Fcode>",[376,377,378],"Build at runtime with deps","\u003Ccode>{ provide: &#39;X&#39;, useFactory: fn, inject: [...] }\u003C\u002Fcode>","\u003Ccode>inject\u003C\u002Fcode> order must match \u003Ccode>fn\u003C\u002Fcode>&#39;s parameter order",[380,381,382],"Alias an existing token","\u003Ccode>{ provide: &#39;ALIAS&#39;, useExisting: Real }\u003C\u002Fcode>","Same instance, second name",[384,385,386],"One instance for the app","\u003Ccode>@Injectable()\u003C\u002Fcode> (default)","\u003Ccode>Scope.DEFAULT\u003C\u002Fcode>, built once at bootstrap",[388,389,390],"One instance per request","\u003Ccode>@Injectable({ scope: Scope.REQUEST })\u003C\u002Fcode>","Bubbles up to every consumer; ~5% latency cost when used narrowly",[392,393,394],"One instance per consumer","\u003Ccode>@Injectable({ scope: Scope.TRANSIENT })\u003C\u002Fcode>","Doesn&#39;t bubble; each injector gets its own copy",[396,397,398],"Reuse a REQUEST sub-tree by tenant","\u003Ccode>@Injectable({ scope: Scope.REQUEST, durable: true })\u003C\u002Fcode>","Multi-tenant optimization",[400,401,402],"Override in tests","\u003Ccode>Test.createTestingModule().overrideProvider(X).useValue(fake)\u003C\u002Fcode>","Same token mechanism, aimed at a test double","table",{"id":405,"html":406,"text":406,"type":91,"level":31},"b77","Key takeaways",{"id":408,"type":97,"items":409,"ordered":18},"b78",[410,411,412,413],"A provider&#39;s identity in Nest is \u003Cstrong>its token plus its registration\u003C\u002Fstrong> — not just its class name. The same class registered in two modules is two instances.","Share one instance by \u003Cstrong>exporting it from a single owning module\u003C\u002Fstrong> and importing that module everywhere it&#39;s needed — never by listing the class twice.","\u003Ccode>useValue\u003C\u002Fcode>, \u003Ccode>useClass\u003C\u002Fcode>, \u003Ccode>useFactory\u003C\u002Fcode>, and \u003Ccode>useExisting\u003C\u002Fcode> are four answers to &quot;what does this token resolve to,&quot; and non-class tokens need \u003Ccode>@Inject()\u003C\u002Fcode> because there&#39;s no type for Nest to read.","\u003Ccode>REQUEST\u003C\u002Fcode> and \u003Ccode>TRANSIENT\u003C\u002Fcode> scope solve real problems, but \u003Ccode>REQUEST\u003C\u002Fcode> scope \u003Cstrong>bubbles up\u003C\u002Fstrong> the entire dependency chain and comes with a real, if usually small, performance cost — reach for \u003Ccode>DEFAULT\u003C\u002Fcode> unless you specifically need per-request state.",{"id":415,"html":416,"type":83},"b79","\u003Cp>The \u003Ccode>CacheService\u003C\u002Fcode> bug from the top of this article has a one-line fix — move it into an exported, imported \u003Ccode>CacheModule\u003C\u002Fcode> — but the DI container doesn&#39;t tell you that&#39;s the problem. It just quietly builds what you asked for: two registrations, two instances, two counters, both correct on their own and wrong together. Once you&#39;re reading &quot;singleton&quot; as &quot;one instance per registration&quot; instead of &quot;one instance in the app,&quot; that class of bug stops being a mystery and starts being something you check for on sight.\u003C\u002Fp>",{"id":418,"html":419,"type":83},"b80","\u003Cp>What&#39;s the DI bug that cost you the most time to track down — a duplicate registration, a scope that bubbled somewhere you didn&#39;t expect, or something else? Drop it in the comments.\u003C\u002Fp>",{"id":421,"type":422},"b81","divider",{"id":424,"html":425,"type":83},"b82","\u003Cp>🚀 \u003Cstrong>Want more like this?\u003C\u002Fstrong> Every guide, playground, and quiz lives on \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002F\">bestpractic.org\u003C\u002Fa>\u003C\u002Fstrong> — open it and \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002F\">sign up free\u003C\u002Fa>\u003C\u002Fstrong> so the next one finds you.\u003C\u002Fp>",{"id":427,"html":428,"type":83},"b83","\u003Cp>\u003Cem>Thanks for reading! Let&#39;s stay connected:\u003C\u002Fem>\u003C\u002Fp>",{"id":430,"type":97,"items":431,"ordered":18},"b84",[432,433,434],"⭐ \u003Cstrong>GitHub\u003C\u002Fstrong> — follow me and star the projects: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fparsajiravand\">github.com\u002Fparsajiravand\u003C\u002Fa>","💬 \u003Cstrong>Discord\u003C\u002Fstrong> — join the frontend best-practices community: \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ\">discord.gg\u002Fd9KRhuAwQ\u003C\u002Fa>","📸 \u003Cstrong>Instagram\u003C\u002Fstrong> — frontend best practices, daily: \u003Ca href=\"https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F\">@bestpractice___\u003C\u002Fa>","Two feature modules, `OrdersModule` and `BillingModule`, both list `CacheService` in their `providers` array. Both inject it in a constructor. Both call `cache.increment('hits')`. In staging, the counter never goes above the value each module produced on its own — `OrdersModule` reports 40 hits, `BillingModule` reports 12, and the total the dashboard shows is wrong by definition, because there's no single counter to be wrong about.\n\n`CacheService` is decorated with `@Injectable()`. Nobody set a scope. By every definition you've read, it's a singleton. It is — just not the singleton you assumed.\n\n## What you'll learn\n\nBy the end of this article you'll be able to:\n\n- Explain what NestJS's dependency injection (DI) container actually does when it sees `constructor(private readonly cache: CacheService)`\n- State precisely what \"singleton\" means in Nest — and why the same `@Injectable()` class can end up as two separate instances\n- Choose between `useValue`, `useClass`, `useFactory`, and `useExisting` when a provider needs more than a bare class\n- Pick the right provider scope (`DEFAULT`, `REQUEST`, `TRANSIENT`) and predict the performance and correctness consequences of each\n- Recognize when a provider's scope \"bubbles up\" and forces something else in your app to become request-scoped too\n\n## Who this is for\n\nYou've written at least one NestJS service with `@Injectable()` and injected it into a controller's constructor. You don't need to have written a custom provider, a factory, or a scoped provider yet — we'll build all three from nothing.\n\nThis article is written against **NestJS 12.x** (verified against the `nestjs\u002Fnest` GitHub release history — `v12.0.0` shipped August 27, 2026). Provider registration and scopes are core-container behavior, unchanged in shape across the 10.x → 12.x line; nothing here depends on the v12 ESM migration specifically.\n\n## Table of contents\n\n- [The problem: a singleton that isn't](#the-problem-a-singleton-that-isnt)\n- [The mental model: registrations, not classes](#the-mental-model-registrations-not-classes)\n- [Stage 1: the simplest provider](#stage-1-the-simplest-provider)\n- [Stage 2: sharing one instance across modules](#stage-2-sharing-one-instance-across-modules)\n- [Stage 3: custom providers — when a class isn't enough](#stage-3-custom-providers-when-a-class-isnt-enough)\n- [Stage 4: provider scopes — DEFAULT, REQUEST, TRANSIENT](#stage-4-provider-scopes-default-request-transient)\n- [Stage 5: scope bubbling](#stage-5-scope-bubbling)\n- [Edge cases and gotchas](#edge-cases-and-gotchas)\n- [Best practices](#best-practices)\n- [FAQ](#faq)\n- [Cheat sheet](#cheat-sheet)\n\n## The problem: a singleton that isn't\n\nHere's the setup, trimmed to the part that matters:\n\n```ts\n\u002F\u002F cache.service.ts\n@Injectable()\nexport class CacheService {\n  private hits = 0;\n  increment(key: string) {\n    this.hits++;\n    return this.hits;\n  }\n}\n```\n\n```ts\n\u002F\u002F orders.module.ts\n@Module({\n  controllers: [OrdersController],\n  providers: [OrdersService, CacheService],\n})\nexport class OrdersModule {}\n```\n\n```ts\n\u002F\u002F billing.module.ts\n@Module({\n  controllers: [BillingController],\n  providers: [BillingService, CacheService],\n})\nexport class BillingModule {}\n```\n\nBoth `OrdersService` and `BillingService` inject `CacheService` through their constructors. Both trust that \"singleton\" means what it usually means in a dependency-injection framework: one instance, shared by whoever asks for it. That trust is reasonable — and wrong here, because of one detail that's easy to skim past: **`CacheService` appears in the `providers` array of two different modules.**\n\nNest doesn't ask \"has this class been instantiated anywhere in the app?\" It asks \"has this token been registered in *this module's* injector?\" `OrdersModule` and `BillingModule` never import each other or a shared module that exports `CacheService`, so Nest treats the two listings as two independent registrations — and builds two independent instances. Each service gets a real, working, entirely singleton `CacheService`. They're just not the *same* one.\n\n## The mental model: registrations, not classes\n\n**The mental model:** NestJS's DI container isn't one global map from class to instance. It's a **tree of injectors, one per module**, and each injector only knows about the providers *that module registered* — either directly in its own `providers` array, or indirectly, imported from another module that `export`s them.\n\nA provider's real identity is its **token** (by default, the class itself) *plus* **where it was registered**. \"Singleton\" is a promise about a registration, not about a class name: *within one injector's scope, this token resolves to one instance, created once.* If a class gets registered twice — once per module, with no import\u002Fexport connecting the two — you get two injectors, two registrations, two honestly-singleton instances that have never met.\n\nThis is why `exports` matters so much in Nest, and it's the missing piece in the bug above: to actually share one `CacheService`, exactly one module should own it and export it, and every consumer should import that module instead of re-listing the class.\n\n```ts\n\u002F\u002F cache.module.ts\n@Module({\n  providers: [CacheService],\n  exports: [CacheService],\n})\nexport class CacheModule {}\n```\n\n```ts\n\u002F\u002F orders.module.ts\n@Module({\n  imports: [CacheModule],\n  controllers: [OrdersController],\n  providers: [OrdersService], \u002F\u002F CacheService is NOT listed here\n})\nexport class OrdersModule {}\n```\n\n```ts\n\u002F\u002F billing.module.ts\n@Module({\n  imports: [CacheModule],\n  controllers: [BillingController],\n  providers: [BillingService], \u002F\u002F CacheService is NOT listed here either\n})\nexport class BillingModule {}\n```\n\nNow there's exactly one registration of `CacheService`, owned by `CacheModule`. `OrdersModule` and `BillingModule` both import it, so Nest resolves the same token to the same instance in both — one counter, correctly shared.\n\n**Key concept:** if you want one instance across your app, register the provider in exactly one place and *import* it everywhere else. Never re-list the class in a second module's `providers` array \"to be safe\" — that's the line that creates the second instance.\n\n\u003C!-- playground:start -->\n\n## 🎮 Try it yourself\n\n**[▶️ Open the interactive playground →](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fnestjs-weekly-dependency-injection-providers-scopes\u002Fplayground)**\n\n_Runs right in your browser — poke at it and watch the concept react live._\n\n\u003C!-- playground:end -->\n\n## Stage 1: the simplest provider\n\nThe smallest possible provider is just a decorated class:\n\n```ts\n@Injectable()\nexport class GreetingService {\n  greet(name: string) {\n    return `Hello, ${name}`;\n  }\n}\n```\n\n`@Injectable()` marks the class as something Nest's container is allowed to manage. Listing it in a module's `providers` array registers it — Nest instantiates it once, resolving its own constructor dependencies first (constructor injection is recursive: if `GreetingService` needed a `LoggerService`, Nest would build that first). Anything that injects `GreetingService` via its constructor type gets the same instance, because the class itself doubles as its injection **token**.\n\n## Stage 2: sharing one instance across modules\n\nCovered above — the fix is `exports` plus `imports`, not a second `providers` listing. It's worth restating as a rule, because it's the single most common DI mistake in a growing Nest app: **a provider is shared by being exported and imported, never by being declared twice.**\n\n## Stage 3: custom providers — when a class isn't enough\n\nNot every dependency is \"a class Nest can `new` up.\" Configuration objects, third-party SDK clients, and values that depend on other providers all need something more flexible than the shorthand `providers: [CacheService]`. Nest's provider registration accepts a full object instead, keyed by `provide` (the token) and one of four resolution strategies:\n\n```ts\n@Module({\n  providers: [\n    \u002F\u002F useValue — hand Nest an already-built value\n    { provide: 'API_BASE_URL', useValue: 'https:\u002F\u002Fapi.example.com' },\n\n    \u002F\u002F useClass — pick the implementation at registration time\n    { provide: PaymentsGateway, useClass: StripeGateway },\n\n    \u002F\u002F useFactory — build the value at runtime, with its own dependencies\n    {\n      provide: 'DB_CONNECTION',\n      useFactory: (config: ConfigService) => createConnection(config.get('DB_URL')),\n      inject: [ConfigService],\n    },\n\n    \u002F\u002F useExisting — an alias: a second token pointing at the same instance\n    { provide: 'LEGACY_CACHE', useExisting: CacheService },\n  ],\n})\nexport class AppModule {}\n```\n\n`'API_BASE_URL'` and `'DB_CONNECTION'` are **string tokens** — the class-as-token trick only works when the dependency is a class, so a plain value or an interface needs an explicit token instead. Injecting one of these requires `@Inject()`, since there's no type for Nest to read off the constructor parameter:\n\n```ts\n@Injectable()\nexport class PaymentsService {\n  constructor(@Inject('API_BASE_URL') private readonly baseUrl: string) {}\n}\n```\n\n**Key concept:** `useValue`, `useClass`, `useFactory`, and `useExisting` are four ways to answer the same question — \"what does this token resolve to?\" — not four unrelated features. `useFactory`'s `inject` array is exactly the same resolution the container already does for constructors; it's just spelled out explicitly because a factory function has no constructor for Nest to inspect.\n\n## Stage 4: provider scopes — DEFAULT, REQUEST, TRANSIENT\n\nEverything so far assumes the default: one instance, created once at bootstrap, reused for the life of the process. That's `Scope.DEFAULT`, and you never write it — it's what `@Injectable()` means with no options. Two other scopes exist, each trading that simplicity for something a shared singleton can't do:\n\n```ts\n@Injectable({ scope: Scope.REQUEST })\nexport class RequestContextService {\n  \u002F\u002F A new instance is created for every incoming request,\n  \u002F\u002F and garbage-collected once that request finishes.\n}\n```\n\n```ts\n@Injectable({ scope: Scope.TRANSIENT })\nexport class LoggerService {\n  \u002F\u002F A new instance is created for every consumer that injects it —\n  \u002F\u002F not shared, not tied to a request.\n}\n```\n\n`REQUEST` scope is for state that's genuinely per-request — the authenticated user, a request ID for tracing, tenant context in a multi-tenant app. `TRANSIENT` is for the rarer case where you don't want sharing at all, even within one request — a logger that should carry the name of whichever class asked for it is the textbook example.\n\nBoth cost something a singleton doesn't. NestJS's own documentation is explicit that request-scoped providers affect performance, because the container can no longer build the dependency graph once at bootstrap — it has to rebuild the request-scoped branch on every request. A properly designed app shouldn't lose more than roughly 5% latency to it, but \"properly designed\" is doing real work in that sentence: reach for `REQUEST` scope only for state that actually varies per request, not as a default habit.\n\nFor multi-tenant apps where many requests share the same tenant, Nest also supports **durable providers** — `@Injectable({ scope: Scope.REQUEST, durable: true })` — which let the container reuse a request-scoped sub-tree across requests that share a common attribute (like a tenant ID) instead of rebuilding it every single time.\n\n## Stage 5: scope bubbling\n\nScopes aren't isolated to the provider that declares them. If `OrdersController` injects `RequestContextService` (request-scoped) directly, `OrdersController` itself becomes request-scoped — Nest has to create a new controller instance per request too, because it can't build a `DEFAULT`-scoped controller once and hand it a dependency that only exists per-request. This is called **scope bubbling**: request scope propagates up the entire chain of things that (directly or transitively) depend on it.\n\n`TRANSIENT` doesn't bubble the same way. A `DEFAULT`-scoped service that injects a `TRANSIENT` logger stays `DEFAULT`-scoped — it just gets its own private logger instance, created once, same as any other dependency at bootstrap. Transience only means \"not shared between different consumers,\" not \"recreated per request.\"\n\n**Key concept:** before marking any provider `REQUEST`-scoped, check what already depends on it. One request-scoped leaf can turn an entire branch of your app — including controllers — into something rebuilt on every single request.\n\n## Edge cases and gotchas\n\n- **Two `providers` listings, zero shared state.** The bug that opened this article. If a \"singleton\" seems to be losing state, check whether it's registered in more than one module instead of exported from one and imported everywhere else.\n- **Circular provider dependencies.** If `ServiceA` needs `ServiceB` and `ServiceB` needs `ServiceA`, Nest can't decide which to build first. `forwardRef(() => ServiceB)` on both sides breaks the deadlock — but a true circular dependency between services is usually a sign one of them should be split.\n- **Injecting a request-scoped provider into a `DEFAULT`-scoped one you don't control** (a library service, for instance) silently makes *that* dependency chain request-scoped too, even though nothing about its own code changed. The bubbling happens at the injection site, not the declaration site.\n- **`useFactory` dependencies must be listed in `inject`, in the same order as the factory's parameters.** Nest resolves them positionally; a factory that takes `(config, logger)` but declares `inject: [LoggerService, ConfigService]` will hand each argument the wrong provider, with no error — just quietly wrong values.\n- **String tokens collide across modules if you're not careful.** `'CACHE'` in one module and `'CACHE'` in another are the *same* token as far as a shared injector is concerned. Prefer a `Symbol()` or an app-wide constants file for non-class tokens once you have more than a couple.\n\n## Best practices\n\n- **Default to `Scope.DEFAULT`.** It's the fastest option and correct for the overwhelming majority of providers — anything that doesn't hold per-request state.\n- **Own shared providers in one module, export them, and import that module everywhere else.** Never re-declare the same class in two `providers` arrays as a shortcut.\n- **Reach for `REQUEST` scope only for data that's truly per-request** (the current user, a correlation ID, tenant context) — and remember it will make everything upstream of it request-scoped too.\n- **Reach for `TRANSIENT` scope only when sharing would actually cause a bug** — a logger that should identify its caller is the common case; most services don't need it.\n- **Use string\u002Fsymbol tokens for anything that isn't a class** — config values, third-party clients, interfaces — and keep them in one place so two modules never accidentally collide on the same string.\n- **In tests, override providers rather than constructing real ones.** `Test.createTestingModule({...}).overrideProvider(CacheService).useValue(fakeCache)` swaps a token's resolution for a test double without touching how the rest of the module is wired — it's the exact same token\u002Fregistration mechanism this article covers, aimed at a test double instead of the real class.\n\n\u003C!-- quiz:start -->\n\n## 🧠 Test yourself\n\nThink it clicked? **[Take the 9-question quiz →](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fnestjs-weekly-dependency-injection-providers-scopes\u002Fquiz)**\n\n_Instant feedback, a hint on every question, and an explanation for each answer — right or wrong._\n\n\u003C!-- quiz:end -->\n\n## FAQ\n\n### Is a NestJS provider actually a singleton?\n\nWithin one registration, yes — `DEFAULT` scope guarantees one instance for the life of the app for that specific registration. It is not automatically an app-wide singleton if the same class is registered separately in more than one module; that produces multiple, independently \"singleton\" instances.\n\n### How do I get two different instances of the same service on purpose?\n\nEither mark it `Scope.TRANSIENT` (a fresh instance per consumer), or register it twice under two different tokens using `useClass` — e.g. `{ provide: 'PRIMARY_DB', useClass: DbConnection }` and `{ provide: 'REPLICA_DB', useClass: DbConnection }`.\n\n### Does exporting a provider create a new instance?\n\nNo. `exports` doesn't instantiate anything — it makes an existing registration visible to modules that `import` the module doing the exporting. The instance is still created once, by whichever module has it in `providers`.\n\n### Why does `@Inject()` show up on some constructor parameters and not others?\n\nNest can use a class as its own injection token automatically, because TypeScript's type metadata gives it something to match. A string, symbol, or interface token has no runtime type to read, so `@Inject('TOKEN')` tells Nest explicitly what to resolve.\n\n### Does REQUEST scope work the same way in WebSocket gateways and microservices?\n\nRequest-scoped providers are supported outside plain HTTP controllers too, but \"request\" means whatever triggers a handler in that transport (a socket event, a message) — always check that the perf tradeoff still makes sense for a transport that may see much higher throughput than typical HTTP traffic.\n\n## Cheat sheet\n\n| Need | Syntax | Notes |\n| --- | --- | --- |\n| Basic provider | `providers: [MyService]` | Shorthand for `{ provide: MyService, useClass: MyService }` |\n| Share one instance across modules | Export from an owner module, `imports` it elsewhere | Never re-list the class in a second `providers` array |\n| Provide a plain value | `{ provide: 'TOKEN', useValue: x }` | Needs `@Inject('TOKEN')` at the injection site |\n| Swap implementations | `{ provide: Base, useClass: Impl }` | Consumers still inject `Base` |\n| Build at runtime with deps | `{ provide: 'X', useFactory: fn, inject: [...] }` | `inject` order must match `fn`'s parameter order |\n| Alias an existing token | `{ provide: 'ALIAS', useExisting: Real }` | Same instance, second name |\n| One instance for the app | `@Injectable()` (default) | `Scope.DEFAULT`, built once at bootstrap |\n| One instance per request | `@Injectable({ scope: Scope.REQUEST })` | Bubbles up to every consumer; ~5% latency cost when used narrowly |\n| One instance per consumer | `@Injectable({ scope: Scope.TRANSIENT })` | Doesn't bubble; each injector gets its own copy |\n| Reuse a REQUEST sub-tree by tenant | `@Injectable({ scope: Scope.REQUEST, durable: true })` | Multi-tenant optimization |\n| Override in tests | `Test.createTestingModule().overrideProvider(X).useValue(fake)` | Same token mechanism, aimed at a test double |\n\n## Key takeaways\n\n- A provider's identity in Nest is **its token plus its registration** — not just its class name. The same class registered in two modules is two instances.\n- Share one instance by **exporting it from a single owning module** and importing that module everywhere it's needed — never by listing the class twice.\n- `useValue`, `useClass`, `useFactory`, and `useExisting` are four answers to \"what does this token resolve to,\" and non-class tokens need `@Inject()` because there's no type for Nest to read.\n- `REQUEST` and `TRANSIENT` scope solve real problems, but `REQUEST` scope **bubbles up** the entire dependency chain and comes with a real, if usually small, performance cost — reach for `DEFAULT` unless you specifically need per-request state.\n\nThe `CacheService` bug from the top of this article has a one-line fix — move it into an exported, imported `CacheModule` — but the DI container doesn't tell you that's the problem. It just quietly builds what you asked for: two registrations, two instances, two counters, both correct on their own and wrong together. Once you're reading \"singleton\" as \"one instance per registration\" instead of \"one instance in the app,\" that class of bug stops being a mystery and starts being something you check for on sight.\n\nWhat's the DI bug that cost you the most time to track down — a duplicate registration, a scope that bubbled somewhere you didn't expect, or something else? Drop it in the comments.\n\n---\n\n🚀 **Want more like this?** Every guide, playground, and quiz lives on **[bestpractic.org](https:\u002F\u002Fbestpractic.org\u002F)** — open it and **[sign up free](https:\u002F\u002Fbestpractic.org\u002F)** so the next one finds you.\n\n*Thanks for reading! Let's stay connected:*\n\n- ⭐ **GitHub** — follow me and star the projects: [github.com\u002Fparsajiravand](https:\u002F\u002Fgithub.com\u002Fparsajiravand)\n- 💬 **Discord** — join the frontend best-practices community: [discord.gg\u002Fd9KRhuAwQ](https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ)\n- 📸 **Instagram** — frontend best practices, daily: [@bestpractice___](https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F)",{"title":47,"canonical":437,"description":49},"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fnestjs-weekly-dependency-injection-providers-scopes","01a05e06-53b8-74fd-8918-103754ebb289",{"name":440,"part":31,"total":31,"items":441},"NestJS Deep Dive",[442,447],{"slug":443,"title":444,"publishedAt":445,"readingMinutes":446},"nestjs-weekly-request-lifecycle","NestJS Request Lifecycle Explained (with Cheat Sheet)","2026-08-28T17:01:41.941Z",13,{"slug":46,"title":47,"publishedAt":52,"readingMinutes":51},{"id":449,"locked":18},"01a05e06-53f3-722e-b8b8-a0357740b1c1",[451],{"id":452,"slug":46,"title":453,"_count":454},"01a05e06-5421-763d-96e3-447bbafba517","NestJS Dependency Injection",{"questions":455},9,[457],{"locale":13,"slug":46},{"id":452,"slug":46,"title":453,"_count":459,"questionCount":455},{"questions":455},[461,465,469,473,477,479,481,485,489,491,494,498],{"slug":462,"name":463,"articles":464},"webdev","Webdev",80,{"slug":466,"name":467,"articles":468},"frontend","Frontend",68,{"slug":470,"name":471,"articles":472},"javascript","Javascript",67,{"slug":474,"name":475,"articles":476},"css","Css",29,{"slug":71,"name":72,"articles":478},17,{"slug":65,"name":66,"articles":480},12,{"slug":482,"name":483,"articles":484},"performance","Performance",10,{"slug":486,"name":487,"articles":488},"react","React",8,{"slug":68,"name":69,"articles":490},6,{"slug":492,"name":493,"articles":490},"grammar","Grammar",{"slug":495,"name":496,"articles":497},"html","Html",5,{"slug":499,"name":500,"articles":497},"browser","Browser",{"items":502,"meta":623},[503,515,530,550,568,586,605],{"id":45,"slug":46,"title":47,"subtitle":48,"excerpt":49,"coverUrl":50,"locale":13,"readingMinutes":51,"publishedAt":52,"viewCount":504,"likeCount":19,"commentCount":19,"author":505,"vertical":506,"topic":507,"tags":508,"_count":513,"playground":514,"hasQuiz":17,"hasPlayground":17},28,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},[509,510,511,512],{"slug":61,"name":62,"color":48},{"slug":68,"name":69,"color":48},{"slug":65,"name":66,"color":48},{"slug":71,"name":72,"color":48},{"assessments":75},{"slug":46},{"id":516,"slug":443,"title":444,"subtitle":48,"excerpt":517,"coverUrl":518,"locale":13,"readingMinutes":446,"publishedAt":445,"viewCount":519,"likeCount":19,"commentCount":19,"author":520,"vertical":521,"topic":522,"tags":523,"_count":528,"playground":529,"hasQuiz":17,"hasPlayground":17},"01a03cdb-22ef-748a-b555-8071c7a905e6","A complete guide to the NestJS request lifecycle: the exact order middleware, guards, interceptors, pipes, and filters run, and why it matters.","\u002Fmedia\u002Fcovers\u002Fnestjs-weekly-request-lifecycle.png",199,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},[524,525,526,527],{"slug":61,"name":62,"color":48},{"slug":68,"name":69,"color":48},{"slug":65,"name":66,"color":48},{"slug":71,"name":72,"color":48},{"assessments":75},{"slug":443},{"id":531,"slug":532,"title":533,"subtitle":48,"excerpt":534,"coverUrl":535,"locale":13,"readingMinutes":536,"publishedAt":537,"viewCount":538,"likeCount":19,"commentCount":19,"author":539,"vertical":540,"topic":541,"tags":543,"_count":548,"playground":549,"hasQuiz":17,"hasPlayground":17},"019fe660-8bc3-7444-8c96-86953902f5e0","findlast-search-from-end","You copy and reverse the array to find the last match. `findLast()` searches from the end directly.","The usual workaround — `[...arr].reverse().find()` — allocates a full copy just to walk it backward. ES2023 added `findLast()` and `findLastIndex()` to search from the end without touching the original.","\u002Fmedia\u002Fcovers\u002Ffindlast-search-from-end.png",4,"2026-08-14T07:38:34.486Z",452,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":470,"name":542},"JavaScript",[544,545,546,547],{"slug":470,"name":471,"color":48},{"slug":462,"name":463,"color":48},{"slug":466,"name":467,"color":48},{"slug":65,"name":66,"color":48},{"assessments":75},{"slug":532},{"id":551,"slug":552,"title":553,"subtitle":48,"excerpt":554,"coverUrl":555,"locale":13,"readingMinutes":536,"publishedAt":556,"viewCount":557,"likeCount":19,"commentCount":19,"author":558,"vertical":559,"topic":560,"tags":561,"_count":566,"playground":567,"hasQuiz":17,"hasPlayground":17},"019ff19b-f047-748a-800d-00912a4d95c9","object-hasown-safe-property-check","You use `obj.hasOwnProperty(key)` to check property ownership. It can silently fail. `Object.hasOwn()` is the safe replacement.","Two real cases where `obj.hasOwnProperty(key)` throws or returns wrong results — and why `Object.hasOwn(obj, key)` is the ES2022 fix that ESLint's `no-prototype-builtins` rule has been nudging you toward for years.","\u002Fmedia\u002Fcovers\u002Fobject-hasown-safe-property-check.png","2026-08-06T08:44:20.722Z",213,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":470,"name":542},[562,563,564,565],{"slug":470,"name":471,"color":48},{"slug":462,"name":463,"color":48},{"slug":466,"name":467,"color":48},{"slug":65,"name":66,"color":48},{"assessments":75},{"slug":552},{"id":569,"slug":570,"title":571,"subtitle":48,"excerpt":572,"coverUrl":573,"locale":13,"readingMinutes":497,"publishedAt":574,"viewCount":575,"likeCount":19,"commentCount":19,"author":576,"vertical":577,"topic":578,"tags":579,"_count":584,"playground":585,"hasQuiz":17,"hasPlayground":17},"019fe660-b8d7-7515-892c-bd576110158c","url-parse-safe-parsing","You've been wrapping `new URL()` in try\u002Fcatch. `URL.parse()` does it natively.","Validating an untrusted URL before parsing it used to mean a try\u002Fcatch wrapper or a regex. `URL.canParse()` checks validity without constructing. `URL.parse()` parses and returns null on failure. Both are Baseline 2024 — no wrapper needed.","\u002Fmedia\u002Fcovers\u002Furl-parse-safe-parsing.png","2026-08-01T08:27:13.710Z",290,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":470,"name":542},[580,581,582,583],{"slug":470,"name":471,"color":48},{"slug":462,"name":463,"color":48},{"slug":466,"name":467,"color":48},{"slug":65,"name":66,"color":48},{"assessments":75},{"slug":570},{"id":587,"slug":588,"title":589,"subtitle":48,"excerpt":590,"coverUrl":591,"locale":13,"readingMinutes":536,"publishedAt":592,"viewCount":593,"likeCount":19,"commentCount":19,"author":594,"vertical":595,"topic":596,"tags":598,"_count":603,"playground":604,"hasQuiz":17,"hasPlayground":17},"019fe660-75da-727d-a751-32f8723b0b38","using-explicit-resource-management","You still write `finally { resource.close() }`. The `using` keyword does it automatically.","The Explicit Resource Management proposal adds a `using` declaration that calls cleanup the moment a scope exits — normal return, early return, or throw. No more try\u002Ffinally boilerplate for timers, event listeners, connections, or any other resource you need to release.","\u002Fmedia\u002Fcovers\u002Fusing-explicit-resource-management.png","2026-07-24T08:33:28.459Z",242,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":65,"name":597},"TypeScript",[599,600,601,602],{"slug":65,"name":66,"color":48},{"slug":470,"name":471,"color":48},{"slug":462,"name":463,"color":48},{"slug":466,"name":467,"color":48},{"assessments":75},{"slug":588},{"id":606,"slug":607,"title":608,"subtitle":48,"excerpt":609,"coverUrl":610,"locale":13,"readingMinutes":536,"publishedAt":611,"viewCount":612,"likeCount":19,"commentCount":19,"author":613,"vertical":614,"topic":615,"tags":616,"_count":621,"playground":622,"hasQuiz":17,"hasPlayground":17},"019fe660-6e7e-72cb-bd34-bc123056cfeb","set-methods-union-intersection","You've been doing Set math by hand. JavaScript finally shipped `.union()`, `.intersection()`, and friends.","Set has always been missing its obvious operations. ES2025 adds `.union()`, `.intersection()`, `.difference()`, `.symmetricDifference()`, and three boolean predicates — native methods that used to require four lines of spread syntax each.","\u002Fmedia\u002Fcovers\u002Fset-methods-union-intersection.png","2026-07-23T08:37:02.144Z",223,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":470,"name":542},[617,618,619,620],{"slug":470,"name":471,"color":48},{"slug":462,"name":463,"color":48},{"slug":466,"name":467,"color":48},{"slug":65,"name":66,"color":48},{"assessments":75},{"slug":607},{"page":75,"perPage":624,"total":480,"totalPages":31},7,"\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-cmnt\">\u002F\u002F cache.service.ts\n\u003C\u002Fspan>@\u003Cspan class=\"shj-class\">Injectable\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">CacheService\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">private\u003C\u002Fspan> hits \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-num\">0\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-func\">increment\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>key\u003Cspan class=\"shj-type\">: string\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>hits\u003Cspan class=\"shj-oper\">++\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>hits;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-cmnt\">\u002F\u002F orders.module.ts\n\u003C\u002Fspan>@\u003Cspan class=\"shj-class\">Module\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  controllers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">OrdersController\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  providers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">OrdersService\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-class\">CacheService\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">OrdersModule\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-cmnt\">\u002F\u002F billing.module.ts\n\u003C\u002Fspan>@\u003Cspan class=\"shj-class\">Module\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  controllers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">BillingController\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  providers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">BillingService\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-class\">CacheService\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">BillingModule\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-cmnt\">\u002F\u002F cache.module.ts\n\u003C\u002Fspan>@\u003Cspan class=\"shj-class\">Module\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  providers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">CacheService\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  exports\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">CacheService\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">CacheModule\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-cmnt\">\u002F\u002F orders.module.ts\n\u003C\u002Fspan>@\u003Cspan class=\"shj-class\">Module\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  imports\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">CacheModule\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  controllers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">OrdersController\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  providers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">OrdersService\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-cmnt\">\u002F\u002F CacheService is NOT listed here\n\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">OrdersModule\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-cmnt\">\u002F\u002F billing.module.ts\n\u003C\u002Fspan>@\u003Cspan class=\"shj-class\">Module\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  imports\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">CacheModule\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  controllers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">BillingController\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  providers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">BillingService\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-cmnt\">\u002F\u002F CacheService is NOT listed here either\n\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">BillingModule\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">@\u003Cspan class=\"shj-class\">Injectable\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">GreetingService\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-func\">greet\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>name\u003Cspan class=\"shj-type\">: string\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> \u003Cspan class=\"shj-str\">`Hello, \u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>name\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003Cdiv>10\u003C\u002Fdiv>\u003Cdiv>11\u003C\u002Fdiv>\u003Cdiv>12\u003C\u002Fdiv>\u003Cdiv>13\u003C\u002Fdiv>\u003Cdiv>14\u003C\u002Fdiv>\u003Cdiv>15\u003C\u002Fdiv>\u003Cdiv>16\u003C\u002Fdiv>\u003Cdiv>17\u003C\u002Fdiv>\u003Cdiv>18\u003C\u002Fdiv>\u003Cdiv>19\u003C\u002Fdiv>\u003Cdiv>20\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">@\u003Cspan class=\"shj-class\">Module\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  providers\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\n    \u003Cspan class=\"shj-cmnt\">\u002F\u002F useValue — hand Nest an already-built value\n\u003C\u002Fspan>    \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> provide\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'API_BASE_URL'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> useValue\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'https:\u002F\u002Fapi.example.com'\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\n    \u003Cspan class=\"shj-cmnt\">\u002F\u002F useClass — pick the implementation at registration time\n\u003C\u002Fspan>    \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> provide\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-class\">PaymentsGateway\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> useClass\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-class\">StripeGateway\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\n    \u003Cspan class=\"shj-cmnt\">\u002F\u002F useFactory — build the value at runtime, with its own dependencies\n\u003C\u002Fspan>    \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n      provide\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'DB_CONNECTION'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n      useFactory\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>config\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-class\">ConfigService\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-func\">createConnection\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>config\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">get\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'DB_URL'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n      inject\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">ConfigService\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n    \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\n    \u003Cspan class=\"shj-cmnt\">\u002F\u002F useExisting — an alias: a second token pointing at the same instance\n\u003C\u002Fspan>    \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> provide\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'LEGACY_CACHE'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> useExisting\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-class\">CacheService\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  \u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">AppModule\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">@\u003Cspan class=\"shj-class\">Injectable\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">PaymentsService\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">constructor\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>@\u003Cspan class=\"shj-class\">Inject\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'API_BASE_URL'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">private\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">readonly\u003C\u002Fspan> baseUrl\u003Cspan class=\"shj-type\">: string\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">@\u003Cspan class=\"shj-class\">Injectable\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> scope\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Scope\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-num\">REQUEST\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">RequestContextService\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-cmnt\">\u002F\u002F A new instance is created for every incoming request,\n\u003C\u002Fspan>  \u003Cspan class=\"shj-cmnt\">\u002F\u002F and garbage-collected once that request finishes.\n\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">@\u003Cspan class=\"shj-class\">Injectable\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> scope\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Scope\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-num\">TRANSIENT\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">export\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">LoggerService\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-cmnt\">\u002F\u002F A new instance is created for every consumer that injects it —\n\u003C\u002Fspan>  \u003Cspan class=\"shj-cmnt\">\u002F\u002F not shared, not tied to a request.\n\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>",{"locked":18,"total":19,"comments":637},[]]