[{"data":1,"prerenderedAt":3559},["ShallowReactive",2],{"navigation":3,"docs-path-index":152,"-docs-core-features-container":198,"-docs-core-features-container-surround":3554},[4],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":52},"Docs","i-lucide-book-marked","\u002Fdocs","docs",[10,26,53,138],{"title":11,"path":12,"stem":13,"children":14,"icon":25},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started\u002F1.index",[15,17,21],{"title":16,"path":12,"stem":13},"Introduction",{"title":18,"path":19,"stem":20},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F2.installation",{"title":22,"path":23,"stem":24},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F1.getting-started\u002F3.examples","i-lucide-rocket",{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":52},"Core features","i-lucide-square-function","\u002Fdocs\u002Fcore-features","docs\u002F2.core-features",[32,36,40,44,48],{"title":33,"path":34,"stem":35},"Configuration","\u002Fdocs\u002Fcore-features\u002Fconfiguration","docs\u002F2.core-features\u002F0.configuration",{"title":37,"path":38,"stem":39},"Dependency Injection","\u002Fdocs\u002Fcore-features\u002Fcontainer","docs\u002F2.core-features\u002F1.container",{"title":41,"path":42,"stem":43},"Controllers","\u002Fdocs\u002Fcore-features\u002Fcontrollers","docs\u002F2.core-features\u002F2.controllers",{"title":45,"path":46,"stem":47},"Middlewares","\u002Fdocs\u002Fcore-features\u002Fmiddlewares","docs\u002F2.core-features\u002F3.middlewares",{"title":49,"path":50,"stem":51},"Validation","\u002Fdocs\u002Fcore-features\u002Fvalidation","docs\u002F2.core-features\u002F4.validation",false,{"title":54,"icon":55,"defaultOpen":56,"path":57,"stem":58,"children":59,"page":52},"Modules","i-lucide-boxes",true,"\u002Fdocs\u002Fmodules","docs\u002F3.modules",[60,77,93,109,123,134],{"title":61,"icon":52,"defaultOpen":52,"path":62,"stem":63,"children":64,"page":52},"Auth","\u002Fdocs\u002Fmodules\u002Fauth","docs\u002F3.modules\u002F1.auth",[65,69,73],{"title":66,"path":67,"stem":68},"Overview","\u002Fdocs\u002Fmodules\u002Fauth\u002Foverview","docs\u002F3.modules\u002F1.auth\u002F0.overview",{"title":70,"path":71,"stem":72},"Decorators","\u002Fdocs\u002Fmodules\u002Fauth\u002Fdecorators","docs\u002F3.modules\u002F1.auth\u002F1.decorators",{"title":74,"path":75,"stem":76},"API Reference","\u002Fdocs\u002Fmodules\u002Fauth\u002Fapi","docs\u002F3.modules\u002F1.auth\u002F2.api",{"title":78,"icon":52,"defaultOpen":52,"path":79,"stem":80,"children":81,"page":52},"Logger","\u002Fdocs\u002Fmodules\u002Flogger","docs\u002F3.modules\u002F2.logger",[82,85,89],{"title":66,"path":83,"stem":84},"\u002Fdocs\u002Fmodules\u002Flogger\u002Foverview","docs\u002F3.modules\u002F2.logger\u002F0.overview",{"title":86,"path":87,"stem":88},"Drivers","\u002Fdocs\u002Fmodules\u002Flogger\u002Fdrivers","docs\u002F3.modules\u002F2.logger\u002F1.drivers",{"title":90,"path":91,"stem":92},"API","\u002Fdocs\u002Fmodules\u002Flogger\u002Fapi","docs\u002F3.modules\u002F2.logger\u002F2.api",{"title":94,"icon":52,"defaultOpen":52,"path":95,"stem":96,"children":97,"page":52},"Serverless","\u002Fdocs\u002Fmodules\u002Fserverless","docs\u002F3.modules\u002F3.serverless",[98,101,105],{"title":66,"path":99,"stem":100},"\u002Fdocs\u002Fmodules\u002Fserverless\u002Foverview","docs\u002F3.modules\u002F3.serverless\u002F0.overview",{"title":102,"path":103,"stem":104},"AWS Lambda","\u002Fdocs\u002Fmodules\u002Fserverless\u002Faws-lambda","docs\u002F3.modules\u002F3.serverless\u002F1.aws-lambda",{"title":106,"path":107,"stem":108},"Azure Functions","\u002Fdocs\u002Fmodules\u002Fserverless\u002Fazure-functions","docs\u002F3.modules\u002F3.serverless\u002F2.azure-functions",{"title":110,"icon":52,"defaultOpen":52,"path":111,"stem":112,"children":113,"page":52},"Storage","\u002Fdocs\u002Fmodules\u002Fstorage","docs\u002F3.modules\u002F4.storage",[114,117,120],{"title":66,"path":115,"stem":116},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Foverview","docs\u002F3.modules\u002F4.storage\u002F0.overview",{"title":86,"path":118,"stem":119},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Fdrivers","docs\u002F3.modules\u002F4.storage\u002F1.drivers",{"title":90,"path":121,"stem":122},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Fapi","docs\u002F3.modules\u002F4.storage\u002F2.api",{"title":124,"icon":52,"defaultOpen":52,"path":125,"stem":126,"children":127,"page":52},"Web Sockets","\u002Fdocs\u002Fmodules\u002Fweb-sockets","docs\u002F3.modules\u002F5.web-sockets",[128,131],{"title":66,"path":129,"stem":130},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Foverview","docs\u002F3.modules\u002F5.web-sockets\u002F0.overview",{"title":90,"path":132,"stem":133},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Fapi","docs\u002F3.modules\u002F5.web-sockets\u002F1.api",{"title":135,"path":136,"stem":137},"MCP","\u002Fdocs\u002Fmodules\u002Fmcp","docs\u002F3.modules\u002F6.mcp",{"title":139,"icon":140,"defaultOpen":52,"path":141,"stem":142,"children":143,"page":52},"Advanced","i-lucide-brain","\u002Fdocs\u002Fadvanced","docs\u002F99.advanced",[144,148],{"title":145,"path":146,"stem":147},"Custom Decorator","\u002Fdocs\u002Fadvanced\u002Fcustom-decorator","docs\u002F99.advanced\u002F1.custom-decorator",{"title":149,"path":150,"stem":151},"Custom Plugin","\u002Fdocs\u002Fadvanced\u002Fcustom-plugin","docs\u002F99.advanced\u002F2.custom-plugin",[153,155,157,158,159,160,162,163,164,165,166,167,169,171,172,173,174,176,177,178,179,181,182,183,184,186,187,188,189,191,192,193,194,196,197],{"path":154},"\u002Fdocs\u002F.navigation",{"path":156},"\u002Fdocs\u002Fgetting-started\u002F.navigation",{"path":12},{"path":19},{"path":23},{"path":161},"\u002Fdocs\u002Fcore-features\u002F.navigation",{"path":34},{"path":38},{"path":42},{"path":46},{"path":50},{"path":168},"\u002Fdocs\u002Fmodules\u002F.navigation",{"path":170},"\u002Fdocs\u002Fmodules\u002Fauth\u002F.navigation",{"path":67},{"path":71},{"path":75},{"path":175},"\u002Fdocs\u002Fmodules\u002Flogger\u002F.navigation",{"path":83},{"path":87},{"path":91},{"path":180},"\u002Fdocs\u002Fmodules\u002Fserverless\u002F.navigation",{"path":99},{"path":103},{"path":107},{"path":185},"\u002Fdocs\u002Fmodules\u002Fstorage\u002F.navigation",{"path":115},{"path":118},{"path":121},{"path":190},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002F.navigation",{"path":129},{"path":132},{"path":136},{"path":195},"\u002Fdocs\u002Fadvanced\u002F.navigation",{"path":146},{"path":150},{"id":199,"title":37,"body":200,"description":3548,"extension":3549,"links":3550,"meta":3551,"navigation":56,"path":38,"seo":3552,"stem":39,"__hash__":3553},"docs\u002Fdocs\u002F2.core-features\u002F1.container.md",{"type":201,"value":202,"toc":3511},"minimark",[203,207,212,215,220,360,364,448,452,455,460,464,471,525,531,559,565,591,597,606,610,614,617,740,744,747,861,865,872,1053,1063,1067,1070,1074,1077,1125,1129,1135,1139,1142,1165,1169,1174,1178,1181,1229,1234,1238,1241,1245,1304,1377,1484,1488,1542,1604,1629,1668,1672,1675,1678,1733,1796,1799,1803,1810,1983,1987,1994,2007,2126,2130,2133,2546,2553,2557,2560,2669,2675,2679,2683,2686,2838,2842,2848,2980,2986,3045,3051,3115,3121,3275,3279,3283,3286,3316,3322,3344,3348,3379,3387,3410,3414,3417,3507],[204,205,206],"p",{},"Dependency Injection (DI) is a design pattern that helps you build maintainable, testable, and flexible applications. The DI Container in Vercube manages your application's dependencies automatically, making your code cleaner and easier to work with.",[208,209,211],"h2",{"id":210},"what-is-dependency-injection","What is Dependency Injection?",[204,213,214],{},"Imagine you're building a house. Instead of each room creating its own electricity generator, water pump, and heating system, you connect them to centralized utilities. Dependency Injection works the same way - instead of each class creating its own dependencies, the container provides them.",[216,217,219],"h3",{"id":218},"without-dependency-injection","Without Dependency Injection",[221,222,227],"pre",{"className":223,"code":224,"language":225,"meta":226,"style":226},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","class UserService {\n  private database: Database;\n  private logger: Logger;\n  \n  constructor() {\n    \u002F\u002F Hard to test - creates concrete instances\n    this.database = new PostgresDatabase();\n    this.logger = new FileLogger();\n  }\n}\n","ts","",[228,229,230,247,266,281,288,299,306,329,348,354],"code",{"__ignoreMap":226},[231,232,235,239,243],"span",{"class":233,"line":234},"line",1,[231,236,238],{"class":237},"spNyl","class",[231,240,242],{"class":241},"sBMFI"," UserService",[231,244,246],{"class":245},"sMK4o"," {\n",[231,248,250,253,257,260,263],{"class":233,"line":249},2,[231,251,252],{"class":237},"  private",[231,254,256],{"class":255},"swJcz"," database",[231,258,259],{"class":245},":",[231,261,262],{"class":241}," Database",[231,264,265],{"class":245},";\n",[231,267,269,271,274,276,279],{"class":233,"line":268},3,[231,270,252],{"class":237},[231,272,273],{"class":255}," logger",[231,275,259],{"class":245},[231,277,278],{"class":241}," Logger",[231,280,265],{"class":245},[231,282,284],{"class":233,"line":283},4,[231,285,287],{"class":286},"sTEyZ","  \n",[231,289,291,294,297],{"class":233,"line":290},5,[231,292,293],{"class":237},"  constructor",[231,295,296],{"class":245},"()",[231,298,246],{"class":245},[231,300,302],{"class":233,"line":301},6,[231,303,305],{"class":304},"sHwdD","    \u002F\u002F Hard to test - creates concrete instances\n",[231,307,309,312,315,318,321,325,327],{"class":233,"line":308},7,[231,310,311],{"class":245},"    this.",[231,313,314],{"class":286},"database",[231,316,317],{"class":245}," =",[231,319,320],{"class":245}," new",[231,322,324],{"class":323},"s2Zo4"," PostgresDatabase",[231,326,296],{"class":255},[231,328,265],{"class":245},[231,330,332,334,337,339,341,344,346],{"class":233,"line":331},8,[231,333,311],{"class":245},[231,335,336],{"class":286},"logger",[231,338,317],{"class":245},[231,340,320],{"class":245},[231,342,343],{"class":323}," FileLogger",[231,345,296],{"class":255},[231,347,265],{"class":245},[231,349,351],{"class":233,"line":350},9,[231,352,353],{"class":245},"  }\n",[231,355,357],{"class":233,"line":356},10,[231,358,359],{"class":245},"}\n",[216,361,363],{"id":362},"with-dependency-injection","With Dependency Injection",[221,365,367],{"className":223,"code":366,"language":225,"meta":226,"style":226},"class UserService {\n\n  @Inject(Database)\n  private database: Database;\n\n  @Inject(Logger)\n  private logger: Logger;\n\n  \u002F\u002F Easy to test - dependencies injected from outside\n  \n}\n",[228,368,369,377,382,393,405,409,418,430,434,439,443],{"__ignoreMap":226},[231,370,371,373,375],{"class":233,"line":234},[231,372,238],{"class":237},[231,374,242],{"class":241},[231,376,246],{"class":245},[231,378,379],{"class":233,"line":249},[231,380,381],{"emptyLinePlaceholder":56},"\n",[231,383,384,387,390],{"class":233,"line":268},[231,385,386],{"class":245},"  @",[231,388,389],{"class":323},"Inject",[231,391,392],{"class":286},"(Database)\n",[231,394,395,397,399,401,403],{"class":233,"line":283},[231,396,252],{"class":237},[231,398,256],{"class":255},[231,400,259],{"class":245},[231,402,262],{"class":241},[231,404,265],{"class":245},[231,406,407],{"class":233,"line":290},[231,408,381],{"emptyLinePlaceholder":56},[231,410,411,413,415],{"class":233,"line":301},[231,412,386],{"class":245},[231,414,389],{"class":323},[231,416,417],{"class":286},"(Logger)\n",[231,419,420,422,424,426,428],{"class":233,"line":308},[231,421,252],{"class":237},[231,423,273],{"class":255},[231,425,259],{"class":245},[231,427,278],{"class":241},[231,429,265],{"class":245},[231,431,432],{"class":233,"line":331},[231,433,381],{"emptyLinePlaceholder":56},[231,435,436],{"class":233,"line":350},[231,437,438],{"class":304},"  \u002F\u002F Easy to test - dependencies injected from outside\n",[231,440,441],{"class":233,"line":356},[231,442,287],{"class":286},[231,444,446],{"class":233,"line":445},11,[231,447,359],{"class":245},[208,449,451],{"id":450},"how-the-container-works","How the Container Works",[204,453,454],{},"The Container acts as a centralized registry that knows how to create and manage all your application's dependencies. Here's a visual representation:",[456,457],"img",{"src":458,"alt":459},"\u002Fimages\u002Fioc-1.svg","How the container works",[216,461,463],{"id":462},"key-benefits","Key Benefits",[204,465,466,470],{},[467,468,469],"strong",{},"Testability"," - Easily replace real services with mocks in tests",[221,472,474],{"className":223,"code":473,"language":225,"meta":226,"style":226},"\u002F\u002F In tests, swap real database with a mock\ncontainer.bindMock(Database, { query: jest.fn() });\n",[228,475,476,481],{"__ignoreMap":226},[231,477,478],{"class":233,"line":234},[231,479,480],{"class":304},"\u002F\u002F In tests, swap real database with a mock\n",[231,482,483,486,489,492,495,498,501,504,506,509,511,514,517,520,523],{"class":233,"line":249},[231,484,485],{"class":286},"container",[231,487,488],{"class":245},".",[231,490,491],{"class":323},"bindMock",[231,493,494],{"class":286},"(Database",[231,496,497],{"class":245},",",[231,499,500],{"class":245}," {",[231,502,503],{"class":255}," query",[231,505,259],{"class":245},[231,507,508],{"class":286}," jest",[231,510,488],{"class":245},[231,512,513],{"class":323},"fn",[231,515,516],{"class":286},"() ",[231,518,519],{"class":245},"}",[231,521,522],{"class":286},")",[231,524,265],{"class":245},[204,526,527,530],{},[467,528,529],{},"Flexibility"," - Change implementations without modifying code",[221,532,534],{"className":223,"code":533,"language":225,"meta":226,"style":226},"\u002F\u002F Switch from PostgreSQL to MongoDB without touching UserService\ncontainer.bind(Database, MongoDatabase);\n",[228,535,536,541],{"__ignoreMap":226},[231,537,538],{"class":233,"line":234},[231,539,540],{"class":304},"\u002F\u002F Switch from PostgreSQL to MongoDB without touching UserService\n",[231,542,543,545,547,550,552,554,557],{"class":233,"line":249},[231,544,485],{"class":286},[231,546,488],{"class":245},[231,548,549],{"class":323},"bind",[231,551,494],{"class":286},[231,553,497],{"class":245},[231,555,556],{"class":286}," MongoDatabase)",[231,558,265],{"class":245},[204,560,561,564],{},[467,562,563],{},"Maintainability"," - Clear dependency relationships",[221,566,568],{"className":223,"code":567,"language":225,"meta":226,"style":226},"\u002F\u002F Just look at the constructor to see what a class needs\nconstructor(private db: Database, private cache: Cache) {}\n",[228,569,570,575],{"__ignoreMap":226},[231,571,572],{"class":233,"line":234},[231,573,574],{"class":304},"\u002F\u002F Just look at the constructor to see what a class needs\n",[231,576,577,580,583,585,588],{"class":233,"line":249},[231,578,579],{"class":323},"constructor",[231,581,582],{"class":286},"(private db: Database",[231,584,497],{"class":245},[231,586,587],{"class":286}," private cache: Cache) ",[231,589,590],{"class":245},"{}\n",[204,592,593,596],{},[467,594,595],{},"Single Responsibility"," - Classes focus on their job, not creating dependencies",[221,598,600],{"className":223,"code":599,"language":225,"meta":226,"style":226},"\u002F\u002F UserService focuses on users, not database connection logic\n",[228,601,602],{"__ignoreMap":226},[231,603,604],{"class":233,"line":234},[231,605,599],{"class":304},[208,607,609],{"id":608},"basic-usage","Basic Usage",[216,611,613],{"id":612},"step-1-create-your-service","Step 1: Create Your Service",[204,615,616],{},"Create a regular TypeScript class. The container will handle creating instances.",[221,618,621],{"className":223,"code":619,"filename":620,"language":225,"meta":226,"style":226},"export class UserService {\n  public getUsers(): User[] {\n    return [\n      { id: 1, name: 'Alice' },\n      { id: 2, name: 'Bob' }\n    ];\n  }\n}\n","UserService.ts",[228,622,623,636,656,664,698,725,732,736],{"__ignoreMap":226},[231,624,625,629,632,634],{"class":233,"line":234},[231,626,628],{"class":627},"s7zQu","export",[231,630,631],{"class":237}," class",[231,633,242],{"class":241},[231,635,246],{"class":245},[231,637,638,641,644,647,650,653],{"class":233,"line":249},[231,639,640],{"class":237},"  public",[231,642,643],{"class":255}," getUsers",[231,645,646],{"class":245},"():",[231,648,649],{"class":241}," User",[231,651,652],{"class":286},"[] ",[231,654,655],{"class":245},"{\n",[231,657,658,661],{"class":233,"line":268},[231,659,660],{"class":627},"    return",[231,662,663],{"class":255}," [\n",[231,665,666,669,672,674,678,680,683,685,688,692,695],{"class":233,"line":283},[231,667,668],{"class":245},"      {",[231,670,671],{"class":255}," id",[231,673,259],{"class":245},[231,675,677],{"class":676},"sbssI"," 1",[231,679,497],{"class":245},[231,681,682],{"class":255}," name",[231,684,259],{"class":245},[231,686,687],{"class":245}," '",[231,689,691],{"class":690},"sfazB","Alice",[231,693,694],{"class":245},"'",[231,696,697],{"class":245}," },\n",[231,699,700,702,704,706,709,711,713,715,717,720,722],{"class":233,"line":290},[231,701,668],{"class":245},[231,703,671],{"class":255},[231,705,259],{"class":245},[231,707,708],{"class":676}," 2",[231,710,497],{"class":245},[231,712,682],{"class":255},[231,714,259],{"class":245},[231,716,687],{"class":245},[231,718,719],{"class":690},"Bob",[231,721,694],{"class":245},[231,723,724],{"class":245}," }\n",[231,726,727,730],{"class":233,"line":301},[231,728,729],{"class":255},"    ]",[231,731,265],{"class":245},[231,733,734],{"class":233,"line":308},[231,735,353],{"class":245},[231,737,738],{"class":233,"line":331},[231,739,359],{"class":245},[216,741,743],{"id":742},"step-2-register-in-container","Step 2: Register in Container",[204,745,746],{},"Tell the container about your service during application setup.",[221,748,751],{"className":223,"code":749,"filename":750,"language":225,"meta":226,"style":226},"import { type App } from '@vercube\u002Fcore';\nimport { UserService } from '.\u002Fservices\u002FUserService';\n\nexport function setup(app: App): void {\n  app.container.bind(UserService);\n}\n","setup.ts",[228,752,753,781,802,806,835,857],{"__ignoreMap":226},[231,754,755,758,760,763,766,769,772,774,777,779],{"class":233,"line":234},[231,756,757],{"class":627},"import",[231,759,500],{"class":245},[231,761,762],{"class":627}," type",[231,764,765],{"class":286}," App",[231,767,768],{"class":245}," }",[231,770,771],{"class":627}," from",[231,773,687],{"class":245},[231,775,776],{"class":690},"@vercube\u002Fcore",[231,778,694],{"class":245},[231,780,265],{"class":245},[231,782,783,785,787,789,791,793,795,798,800],{"class":233,"line":249},[231,784,757],{"class":627},[231,786,500],{"class":245},[231,788,242],{"class":286},[231,790,768],{"class":245},[231,792,771],{"class":627},[231,794,687],{"class":245},[231,796,797],{"class":690},".\u002Fservices\u002FUserService",[231,799,694],{"class":245},[231,801,265],{"class":245},[231,803,804],{"class":233,"line":268},[231,805,381],{"emptyLinePlaceholder":56},[231,807,808,810,813,816,819,823,825,827,830,833],{"class":233,"line":283},[231,809,628],{"class":627},[231,811,812],{"class":237}," function",[231,814,815],{"class":323}," setup",[231,817,818],{"class":245},"(",[231,820,822],{"class":821},"sHdIc","app",[231,824,259],{"class":245},[231,826,765],{"class":241},[231,828,829],{"class":245},"):",[231,831,832],{"class":241}," void",[231,834,246],{"class":245},[231,836,837,840,842,844,846,848,850,853,855],{"class":233,"line":290},[231,838,839],{"class":286},"  app",[231,841,488],{"class":245},[231,843,485],{"class":286},[231,845,488],{"class":245},[231,847,549],{"class":323},[231,849,818],{"class":255},[231,851,852],{"class":286},"UserService",[231,854,522],{"class":255},[231,856,265],{"class":245},[231,858,859],{"class":233,"line":301},[231,860,359],{"class":245},[216,862,864],{"id":863},"step-3-inject-dependencies","Step 3: Inject Dependencies",[204,866,867,868,871],{},"Use the ",[228,869,870],{},"@Inject"," decorator to request dependencies in your controllers.",[221,873,876],{"className":223,"code":874,"filename":875,"language":225,"meta":226,"style":226},"import { Controller, Get, Inject } from '@vercube\u002Fcore';\nimport { UserService } from '.\u002Fservices\u002FUserService';\n\n@Controller('\u002Fusers')\nexport class UserController {\n  \n  @Inject(UserService)\n  private userService!: UserService;\n  \n  @Get('\u002F')\n  public getUsers() {\n    return this.userService.getUsers();\n  }\n}\n","UserController.ts",[228,877,878,909,929,933,953,964,968,977,991,995,1013,1023,1043,1048],{"__ignoreMap":226},[231,879,880,882,884,887,889,892,894,897,899,901,903,905,907],{"class":233,"line":234},[231,881,757],{"class":627},[231,883,500],{"class":245},[231,885,886],{"class":286}," Controller",[231,888,497],{"class":245},[231,890,891],{"class":286}," Get",[231,893,497],{"class":245},[231,895,896],{"class":286}," Inject",[231,898,768],{"class":245},[231,900,771],{"class":627},[231,902,687],{"class":245},[231,904,776],{"class":690},[231,906,694],{"class":245},[231,908,265],{"class":245},[231,910,911,913,915,917,919,921,923,925,927],{"class":233,"line":249},[231,912,757],{"class":627},[231,914,500],{"class":245},[231,916,242],{"class":286},[231,918,768],{"class":245},[231,920,771],{"class":627},[231,922,687],{"class":245},[231,924,797],{"class":690},[231,926,694],{"class":245},[231,928,265],{"class":245},[231,930,931],{"class":233,"line":268},[231,932,381],{"emptyLinePlaceholder":56},[231,934,935,938,941,943,945,948,950],{"class":233,"line":283},[231,936,937],{"class":245},"@",[231,939,940],{"class":323},"Controller",[231,942,818],{"class":286},[231,944,694],{"class":245},[231,946,947],{"class":690},"\u002Fusers",[231,949,694],{"class":245},[231,951,952],{"class":286},")\n",[231,954,955,957,959,962],{"class":233,"line":290},[231,956,628],{"class":627},[231,958,631],{"class":237},[231,960,961],{"class":241}," UserController",[231,963,246],{"class":245},[231,965,966],{"class":233,"line":301},[231,967,287],{"class":286},[231,969,970,972,974],{"class":233,"line":308},[231,971,386],{"class":245},[231,973,389],{"class":323},[231,975,976],{"class":286},"(UserService)\n",[231,978,979,981,984,987,989],{"class":233,"line":331},[231,980,252],{"class":237},[231,982,983],{"class":255}," userService",[231,985,986],{"class":245},"!:",[231,988,242],{"class":241},[231,990,265],{"class":245},[231,992,993],{"class":233,"line":350},[231,994,287],{"class":286},[231,996,997,999,1002,1004,1006,1009,1011],{"class":233,"line":356},[231,998,386],{"class":245},[231,1000,1001],{"class":323},"Get",[231,1003,818],{"class":286},[231,1005,694],{"class":245},[231,1007,1008],{"class":690},"\u002F",[231,1010,694],{"class":245},[231,1012,952],{"class":286},[231,1014,1015,1017,1019,1021],{"class":233,"line":445},[231,1016,640],{"class":237},[231,1018,643],{"class":255},[231,1020,296],{"class":245},[231,1022,246],{"class":245},[231,1024,1026,1028,1031,1034,1036,1039,1041],{"class":233,"line":1025},12,[231,1027,660],{"class":627},[231,1029,1030],{"class":245}," this.",[231,1032,1033],{"class":286},"userService",[231,1035,488],{"class":245},[231,1037,1038],{"class":323},"getUsers",[231,1040,296],{"class":255},[231,1042,265],{"class":245},[231,1044,1046],{"class":233,"line":1045},13,[231,1047,353],{"class":245},[231,1049,1051],{"class":233,"line":1050},14,[231,1052,359],{"class":245},[1054,1055,1056],"note",{},[204,1057,1058,1059,1062],{},"The ",[228,1060,1061],{},"!"," after the property name is TypeScript's \"definite assignment assertion\". It tells TypeScript \"trust me, this will be assigned before I use it\" - which is true because the container injects it.",[208,1064,1066],{"id":1065},"service-lifetimes","Service Lifetimes",[204,1068,1069],{},"The container supports different lifetimes for your services, controlling when instances are created and how long they live.",[216,1071,1073],{"id":1072},"singleton-default","Singleton (Default)",[204,1075,1076],{},"One instance is created and shared across your entire application.",[221,1078,1080],{"className":223,"code":1079,"language":225,"meta":226,"style":226},"app.container.bind(Database);\n\u002F\u002F or explicitly\napp.container.bind(Database, PostgresDatabase);\n",[228,1081,1082,1099,1104],{"__ignoreMap":226},[231,1083,1084,1086,1088,1090,1092,1094,1097],{"class":233,"line":234},[231,1085,822],{"class":286},[231,1087,488],{"class":245},[231,1089,485],{"class":286},[231,1091,488],{"class":245},[231,1093,549],{"class":323},[231,1095,1096],{"class":286},"(Database)",[231,1098,265],{"class":245},[231,1100,1101],{"class":233,"line":249},[231,1102,1103],{"class":304},"\u002F\u002F or explicitly\n",[231,1105,1106,1108,1110,1112,1114,1116,1118,1120,1123],{"class":233,"line":268},[231,1107,822],{"class":286},[231,1109,488],{"class":245},[231,1111,485],{"class":286},[231,1113,488],{"class":245},[231,1115,549],{"class":323},[231,1117,494],{"class":286},[231,1119,497],{"class":245},[231,1121,1122],{"class":286}," PostgresDatabase)",[231,1124,265],{"class":245},[456,1126],{"src":1127,"alt":1128},"\u002Fimages\u002Fioc-2.svg","Singleton",[204,1130,1131,1134],{},[467,1132,1133],{},"Use for:"," Services that maintain state or are expensive to create (database connections, caches, configuration)",[216,1136,1138],{"id":1137},"transient","Transient",[204,1140,1141],{},"A new instance is created every time it's requested.",[221,1143,1145],{"className":223,"code":1144,"language":225,"meta":226,"style":226},"app.container.bindTransient(RequestLogger);\n",[228,1146,1147],{"__ignoreMap":226},[231,1148,1149,1151,1153,1155,1157,1160,1163],{"class":233,"line":234},[231,1150,822],{"class":286},[231,1152,488],{"class":245},[231,1154,485],{"class":286},[231,1156,488],{"class":245},[231,1158,1159],{"class":323},"bindTransient",[231,1161,1162],{"class":286},"(RequestLogger)",[231,1164,265],{"class":245},[456,1166],{"src":1167,"alt":1168},"\u002Fimages\u002Fioc-3.svg","Bind Transient",[204,1170,1171,1173],{},[467,1172,1133],{}," Stateless services or when you need isolation between uses",[216,1175,1177],{"id":1176},"instance","Instance",[204,1179,1180],{},"Bind an already-created instance to the container.",[221,1182,1184],{"className":223,"code":1183,"language":225,"meta":226,"style":226},"const config = new AppConfig();\napp.container.bindInstance(AppConfig, config);\n",[228,1185,1186,1206],{"__ignoreMap":226},[231,1187,1188,1191,1194,1197,1199,1202,1204],{"class":233,"line":234},[231,1189,1190],{"class":237},"const",[231,1192,1193],{"class":286}," config ",[231,1195,1196],{"class":245},"=",[231,1198,320],{"class":245},[231,1200,1201],{"class":323}," AppConfig",[231,1203,296],{"class":286},[231,1205,265],{"class":245},[231,1207,1208,1210,1212,1214,1216,1219,1222,1224,1227],{"class":233,"line":249},[231,1209,822],{"class":286},[231,1211,488],{"class":245},[231,1213,485],{"class":286},[231,1215,488],{"class":245},[231,1217,1218],{"class":323},"bindInstance",[231,1220,1221],{"class":286},"(AppConfig",[231,1223,497],{"class":245},[231,1225,1226],{"class":286}," config)",[231,1228,265],{"class":245},[204,1230,1231,1233],{},[467,1232,1133],{}," Pre-configured objects, global singletons, or sharing instances between containers",[208,1235,1237],{"id":1236},"working-with-interfaces-and-abstract-classes","Working with Interfaces and Abstract Classes",[204,1239,1240],{},"TypeScript interfaces don't exist at runtime, so the container can't use them directly. Instead, use symbols or abstract classes as service identifiers.",[216,1242,1244],{"id":1243},"using-symbols","Using Symbols",[221,1246,1249],{"className":223,"code":1247,"filename":1248,"language":225,"meta":226,"style":226},"import { Identity } from '@vercube\u002Fdi';\n\nexport const $Database = Identity('Database');\n","symbols.ts",[228,1250,1251,1273,1277],{"__ignoreMap":226},[231,1252,1253,1255,1257,1260,1262,1264,1266,1269,1271],{"class":233,"line":234},[231,1254,757],{"class":627},[231,1256,500],{"class":245},[231,1258,1259],{"class":286}," Identity",[231,1261,768],{"class":245},[231,1263,771],{"class":627},[231,1265,687],{"class":245},[231,1267,1268],{"class":690},"@vercube\u002Fdi",[231,1270,694],{"class":245},[231,1272,265],{"class":245},[231,1274,1275],{"class":233,"line":249},[231,1276,381],{"emptyLinePlaceholder":56},[231,1278,1279,1281,1284,1287,1289,1291,1293,1295,1298,1300,1302],{"class":233,"line":268},[231,1280,628],{"class":627},[231,1282,1283],{"class":237}," const",[231,1285,1286],{"class":286}," $Database ",[231,1288,1196],{"class":245},[231,1290,1259],{"class":323},[231,1292,818],{"class":286},[231,1294,694],{"class":245},[231,1296,1297],{"class":690},"Database",[231,1299,694],{"class":245},[231,1301,522],{"class":286},[231,1303,265],{"class":245},[221,1305,1307],{"className":223,"code":1306,"filename":750,"language":225,"meta":226,"style":226},"import { $Database } from '.\u002Fsymbols';\nimport { PostgresDatabase } from '.\u002Fservices\u002FPostgresDatabase';\n\napp.container.bind($Database, PostgresDatabase);\n",[228,1308,1309,1331,1352,1356],{"__ignoreMap":226},[231,1310,1311,1313,1315,1318,1320,1322,1324,1327,1329],{"class":233,"line":234},[231,1312,757],{"class":627},[231,1314,500],{"class":245},[231,1316,1317],{"class":286}," $Database",[231,1319,768],{"class":245},[231,1321,771],{"class":627},[231,1323,687],{"class":245},[231,1325,1326],{"class":690},".\u002Fsymbols",[231,1328,694],{"class":245},[231,1330,265],{"class":245},[231,1332,1333,1335,1337,1339,1341,1343,1345,1348,1350],{"class":233,"line":249},[231,1334,757],{"class":627},[231,1336,500],{"class":245},[231,1338,324],{"class":286},[231,1340,768],{"class":245},[231,1342,771],{"class":627},[231,1344,687],{"class":245},[231,1346,1347],{"class":690},".\u002Fservices\u002FPostgresDatabase",[231,1349,694],{"class":245},[231,1351,265],{"class":245},[231,1353,1354],{"class":233,"line":268},[231,1355,381],{"emptyLinePlaceholder":56},[231,1357,1358,1360,1362,1364,1366,1368,1371,1373,1375],{"class":233,"line":283},[231,1359,822],{"class":286},[231,1361,488],{"class":245},[231,1363,485],{"class":286},[231,1365,488],{"class":245},[231,1367,549],{"class":323},[231,1369,1370],{"class":286},"($Database",[231,1372,497],{"class":245},[231,1374,1122],{"class":286},[231,1376,265],{"class":245},[221,1378,1380],{"className":223,"code":1379,"filename":620,"language":225,"meta":226,"style":226},"import { Inject } from '@vercube\u002Fcore';\nimport { $Database } from '.\u002Fsymbols';\nimport type { Database } from '.\u002Finterfaces\u002FDatabase';\n\nexport class UserService {\n  @Inject($Database)\n  private database!: Database;\n}\n",[228,1381,1382,1402,1422,1445,1449,1459,1468,1480],{"__ignoreMap":226},[231,1383,1384,1386,1388,1390,1392,1394,1396,1398,1400],{"class":233,"line":234},[231,1385,757],{"class":627},[231,1387,500],{"class":245},[231,1389,896],{"class":286},[231,1391,768],{"class":245},[231,1393,771],{"class":627},[231,1395,687],{"class":245},[231,1397,776],{"class":690},[231,1399,694],{"class":245},[231,1401,265],{"class":245},[231,1403,1404,1406,1408,1410,1412,1414,1416,1418,1420],{"class":233,"line":249},[231,1405,757],{"class":627},[231,1407,500],{"class":245},[231,1409,1317],{"class":286},[231,1411,768],{"class":245},[231,1413,771],{"class":627},[231,1415,687],{"class":245},[231,1417,1326],{"class":690},[231,1419,694],{"class":245},[231,1421,265],{"class":245},[231,1423,1424,1426,1428,1430,1432,1434,1436,1438,1441,1443],{"class":233,"line":268},[231,1425,757],{"class":627},[231,1427,762],{"class":627},[231,1429,500],{"class":245},[231,1431,262],{"class":286},[231,1433,768],{"class":245},[231,1435,771],{"class":627},[231,1437,687],{"class":245},[231,1439,1440],{"class":690},".\u002Finterfaces\u002FDatabase",[231,1442,694],{"class":245},[231,1444,265],{"class":245},[231,1446,1447],{"class":233,"line":283},[231,1448,381],{"emptyLinePlaceholder":56},[231,1450,1451,1453,1455,1457],{"class":233,"line":290},[231,1452,628],{"class":627},[231,1454,631],{"class":237},[231,1456,242],{"class":241},[231,1458,246],{"class":245},[231,1460,1461,1463,1465],{"class":233,"line":301},[231,1462,386],{"class":245},[231,1464,389],{"class":323},[231,1466,1467],{"class":286},"($Database)\n",[231,1469,1470,1472,1474,1476,1478],{"class":233,"line":308},[231,1471,252],{"class":237},[231,1473,256],{"class":255},[231,1475,986],{"class":245},[231,1477,262],{"class":241},[231,1479,265],{"class":245},[231,1481,1482],{"class":233,"line":331},[231,1483,359],{"class":245},[216,1485,1487],{"id":1486},"using-abstract-classes","Using Abstract Classes",[221,1489,1492],{"className":223,"code":1490,"filename":1491,"language":225,"meta":226,"style":226},"export abstract class Database {\n  abstract query(sql: string): Promise\u003Cany>;\n}\n","Database.ts",[228,1493,1494,1507,1538],{"__ignoreMap":226},[231,1495,1496,1498,1501,1503,1505],{"class":233,"line":234},[231,1497,628],{"class":627},[231,1499,1500],{"class":237}," abstract",[231,1502,631],{"class":237},[231,1504,262],{"class":241},[231,1506,246],{"class":245},[231,1508,1509,1512,1514,1516,1519,1521,1524,1526,1529,1532,1535],{"class":233,"line":249},[231,1510,1511],{"class":237},"  abstract",[231,1513,503],{"class":255},[231,1515,818],{"class":245},[231,1517,1518],{"class":821},"sql",[231,1520,259],{"class":245},[231,1522,1523],{"class":241}," string",[231,1525,829],{"class":245},[231,1527,1528],{"class":241}," Promise",[231,1530,1531],{"class":245},"\u003C",[231,1533,1534],{"class":241},"any",[231,1536,1537],{"class":245},">;\n",[231,1539,1540],{"class":233,"line":268},[231,1541,359],{"class":245},[221,1543,1546],{"className":223,"code":1544,"filename":1545,"language":225,"meta":226,"style":226},"export class PostgresDatabase extends Database {\n  async query(sql: string): Promise\u003Cany> {\n    \u002F\u002F Implementation\n  }\n}\n","PostgresDatabase.ts",[228,1547,1548,1563,1591,1596,1600],{"__ignoreMap":226},[231,1549,1550,1552,1554,1556,1559,1561],{"class":233,"line":234},[231,1551,628],{"class":627},[231,1553,631],{"class":237},[231,1555,324],{"class":241},[231,1557,1558],{"class":237}," extends",[231,1560,262],{"class":241},[231,1562,246],{"class":245},[231,1564,1565,1568,1570,1572,1574,1576,1578,1580,1582,1584,1586,1589],{"class":233,"line":249},[231,1566,1567],{"class":237},"  async",[231,1569,503],{"class":255},[231,1571,818],{"class":245},[231,1573,1518],{"class":821},[231,1575,259],{"class":245},[231,1577,1523],{"class":241},[231,1579,829],{"class":245},[231,1581,1528],{"class":241},[231,1583,1531],{"class":245},[231,1585,1534],{"class":241},[231,1587,1588],{"class":245},">",[231,1590,246],{"class":245},[231,1592,1593],{"class":233,"line":268},[231,1594,1595],{"class":304},"    \u002F\u002F Implementation\n",[231,1597,1598],{"class":233,"line":283},[231,1599,353],{"class":245},[231,1601,1602],{"class":233,"line":290},[231,1603,359],{"class":245},[221,1605,1607],{"className":223,"code":1606,"filename":750,"language":225,"meta":226,"style":226},"app.container.bind(Database, PostgresDatabase);\n",[228,1608,1609],{"__ignoreMap":226},[231,1610,1611,1613,1615,1617,1619,1621,1623,1625,1627],{"class":233,"line":234},[231,1612,822],{"class":286},[231,1614,488],{"class":245},[231,1616,485],{"class":286},[231,1618,488],{"class":245},[231,1620,549],{"class":323},[231,1622,494],{"class":286},[231,1624,497],{"class":245},[231,1626,1122],{"class":286},[231,1628,265],{"class":245},[221,1630,1632],{"className":223,"code":1631,"filename":620,"language":225,"meta":226,"style":226},"export class UserService {\n  @Inject(Database)\n  private database!: Database;\n}\n",[228,1633,1634,1644,1652,1664],{"__ignoreMap":226},[231,1635,1636,1638,1640,1642],{"class":233,"line":234},[231,1637,628],{"class":627},[231,1639,631],{"class":237},[231,1641,242],{"class":241},[231,1643,246],{"class":245},[231,1645,1646,1648,1650],{"class":233,"line":249},[231,1647,386],{"class":245},[231,1649,389],{"class":323},[231,1651,392],{"class":286},[231,1653,1654,1656,1658,1660,1662],{"class":233,"line":268},[231,1655,252],{"class":237},[231,1657,256],{"class":255},[231,1659,986],{"class":245},[231,1661,262],{"class":241},[231,1663,265],{"class":245},[231,1665,1666],{"class":233,"line":283},[231,1667,359],{"class":245},[208,1669,1671],{"id":1670},"dependency-chains","Dependency Chains",[204,1673,1674],{},"The container automatically resolves nested dependencies - when Service A needs Service B, and Service B needs Service C, everything just works.",[456,1676],{"src":1677,"alt":1671},"\u002Fimages\u002Fioc-4.svg",[221,1679,1681],{"className":223,"code":1680,"filename":875,"language":225,"meta":226,"style":226},"@Controller('\u002Fusers')\nexport class UserController {\n  @Inject(UserService)\n  private userService!: UserService;\n}\n",[228,1682,1683,1699,1709,1717,1729],{"__ignoreMap":226},[231,1684,1685,1687,1689,1691,1693,1695,1697],{"class":233,"line":234},[231,1686,937],{"class":245},[231,1688,940],{"class":323},[231,1690,818],{"class":286},[231,1692,694],{"class":245},[231,1694,947],{"class":690},[231,1696,694],{"class":245},[231,1698,952],{"class":286},[231,1700,1701,1703,1705,1707],{"class":233,"line":249},[231,1702,628],{"class":627},[231,1704,631],{"class":237},[231,1706,961],{"class":241},[231,1708,246],{"class":245},[231,1710,1711,1713,1715],{"class":233,"line":268},[231,1712,386],{"class":245},[231,1714,389],{"class":323},[231,1716,976],{"class":286},[231,1718,1719,1721,1723,1725,1727],{"class":233,"line":283},[231,1720,252],{"class":237},[231,1722,983],{"class":255},[231,1724,986],{"class":245},[231,1726,242],{"class":241},[231,1728,265],{"class":245},[231,1730,1731],{"class":233,"line":290},[231,1732,359],{"class":245},[221,1734,1736],{"className":223,"code":1735,"filename":620,"language":225,"meta":226,"style":226},"export class UserService {\n  @Inject(Database)\n  private database!: Database;\n  \n  @Inject(Logger)\n  private logger!: Logger;\n}\n",[228,1737,1738,1748,1756,1768,1772,1780,1792],{"__ignoreMap":226},[231,1739,1740,1742,1744,1746],{"class":233,"line":234},[231,1741,628],{"class":627},[231,1743,631],{"class":237},[231,1745,242],{"class":241},[231,1747,246],{"class":245},[231,1749,1750,1752,1754],{"class":233,"line":249},[231,1751,386],{"class":245},[231,1753,389],{"class":323},[231,1755,392],{"class":286},[231,1757,1758,1760,1762,1764,1766],{"class":233,"line":268},[231,1759,252],{"class":237},[231,1761,256],{"class":255},[231,1763,986],{"class":245},[231,1765,262],{"class":241},[231,1767,265],{"class":245},[231,1769,1770],{"class":233,"line":283},[231,1771,287],{"class":286},[231,1773,1774,1776,1778],{"class":233,"line":290},[231,1775,386],{"class":245},[231,1777,389],{"class":323},[231,1779,417],{"class":286},[231,1781,1782,1784,1786,1788,1790],{"class":233,"line":301},[231,1783,252],{"class":237},[231,1785,273],{"class":255},[231,1787,986],{"class":245},[231,1789,278],{"class":241},[231,1791,265],{"class":245},[231,1793,1794],{"class":233,"line":308},[231,1795,359],{"class":245},[204,1797,1798],{},"The container handles the entire chain automatically!",[208,1800,1802],{"id":1801},"optional-dependencies","Optional Dependencies",[204,1804,1805,1806,1809],{},"Sometimes a dependency might not be available, and that's okay. Use ",[228,1807,1808],{},"@InjectOptional"," for dependencies that may or may not exist.",[221,1811,1814],{"className":223,"code":1812,"filename":1813,"language":225,"meta":226,"style":226},"import { InjectOptional } from '@vercube\u002Fcore';\n\nexport class EmailService {\n  @InjectOptional(TemplateEngine)\n  private templateEngine?: TemplateEngine | null;\n  \n  public sendEmail(to: string, message: string) {\n    if (this.templateEngine) {\n      \u002F\u002F Use fancy templates\n      message = this.templateEngine.render(message);\n    }\n    \u002F\u002F Send email\n  }\n}\n","EmailService.ts",[228,1815,1816,1837,1841,1852,1862,1883,1887,1916,1935,1940,1965,1970,1975,1979],{"__ignoreMap":226},[231,1817,1818,1820,1822,1825,1827,1829,1831,1833,1835],{"class":233,"line":234},[231,1819,757],{"class":627},[231,1821,500],{"class":245},[231,1823,1824],{"class":286}," InjectOptional",[231,1826,768],{"class":245},[231,1828,771],{"class":627},[231,1830,687],{"class":245},[231,1832,776],{"class":690},[231,1834,694],{"class":245},[231,1836,265],{"class":245},[231,1838,1839],{"class":233,"line":249},[231,1840,381],{"emptyLinePlaceholder":56},[231,1842,1843,1845,1847,1850],{"class":233,"line":268},[231,1844,628],{"class":627},[231,1846,631],{"class":237},[231,1848,1849],{"class":241}," EmailService",[231,1851,246],{"class":245},[231,1853,1854,1856,1859],{"class":233,"line":283},[231,1855,386],{"class":245},[231,1857,1858],{"class":323},"InjectOptional",[231,1860,1861],{"class":286},"(TemplateEngine)\n",[231,1863,1864,1866,1869,1872,1875,1878,1881],{"class":233,"line":290},[231,1865,252],{"class":237},[231,1867,1868],{"class":255}," templateEngine",[231,1870,1871],{"class":245},"?:",[231,1873,1874],{"class":241}," TemplateEngine",[231,1876,1877],{"class":245}," |",[231,1879,1880],{"class":241}," null",[231,1882,265],{"class":245},[231,1884,1885],{"class":233,"line":301},[231,1886,287],{"class":286},[231,1888,1889,1891,1894,1896,1899,1901,1903,1905,1908,1910,1912,1914],{"class":233,"line":308},[231,1890,640],{"class":237},[231,1892,1893],{"class":255}," sendEmail",[231,1895,818],{"class":245},[231,1897,1898],{"class":821},"to",[231,1900,259],{"class":245},[231,1902,1523],{"class":241},[231,1904,497],{"class":245},[231,1906,1907],{"class":821}," message",[231,1909,259],{"class":245},[231,1911,1523],{"class":241},[231,1913,522],{"class":245},[231,1915,246],{"class":245},[231,1917,1918,1921,1924,1927,1930,1933],{"class":233,"line":331},[231,1919,1920],{"class":627},"    if",[231,1922,1923],{"class":255}," (",[231,1925,1926],{"class":245},"this.",[231,1928,1929],{"class":286},"templateEngine",[231,1931,1932],{"class":255},") ",[231,1934,655],{"class":245},[231,1936,1937],{"class":233,"line":350},[231,1938,1939],{"class":304},"      \u002F\u002F Use fancy templates\n",[231,1941,1942,1945,1947,1949,1951,1953,1956,1958,1961,1963],{"class":233,"line":356},[231,1943,1944],{"class":286},"      message",[231,1946,317],{"class":245},[231,1948,1030],{"class":245},[231,1950,1929],{"class":286},[231,1952,488],{"class":245},[231,1954,1955],{"class":323},"render",[231,1957,818],{"class":255},[231,1959,1960],{"class":286},"message",[231,1962,522],{"class":255},[231,1964,265],{"class":245},[231,1966,1967],{"class":233,"line":445},[231,1968,1969],{"class":245},"    }\n",[231,1971,1972],{"class":233,"line":1025},[231,1973,1974],{"class":304},"    \u002F\u002F Send email\n",[231,1976,1977],{"class":233,"line":1045},[231,1978,353],{"class":245},[231,1980,1981],{"class":233,"line":1050},[231,1982,359],{"class":245},[208,1984,1986],{"id":1985},"manual-resolution","Manual Resolution",[204,1988,1989,1990,1993],{},"Sometimes you need to create instances manually - use ",[228,1991,1992],{},"container.resolve()"," for this.",[204,1995,1996,1997,1999,2000,2003,2004,2006],{},"By using ",[228,1998,1992],{},", you create a new instance of the desired service. The key difference compared to using the ",[228,2001,2002],{},"new"," operator directly is that ",[228,2005,1992],{}," will automatically resolve and inject all dependencies required by the class, following the IoC pattern. This ensures your new instance is fully constructed with everything it needs, without you having to manually create or pass any dependencies.",[221,2008,2010],{"className":223,"code":2009,"language":225,"meta":226,"style":226},"export class ReportGenerator {\n  @Inject(Container)\n  private container!: Container;\n  \n  public generateReport(type: string) {\n    \u002F\u002F Dynamically create service based on report type\n    const service = this.container.resolve(ReportService);\n    return service.generate();\n  }\n}\n",[228,2011,2012,2023,2032,2046,2050,2070,2075,2103,2118,2122],{"__ignoreMap":226},[231,2013,2014,2016,2018,2021],{"class":233,"line":234},[231,2015,628],{"class":627},[231,2017,631],{"class":237},[231,2019,2020],{"class":241}," ReportGenerator",[231,2022,246],{"class":245},[231,2024,2025,2027,2029],{"class":233,"line":249},[231,2026,386],{"class":245},[231,2028,389],{"class":323},[231,2030,2031],{"class":286},"(Container)\n",[231,2033,2034,2036,2039,2041,2044],{"class":233,"line":268},[231,2035,252],{"class":237},[231,2037,2038],{"class":255}," container",[231,2040,986],{"class":245},[231,2042,2043],{"class":241}," Container",[231,2045,265],{"class":245},[231,2047,2048],{"class":233,"line":283},[231,2049,287],{"class":286},[231,2051,2052,2054,2057,2059,2062,2064,2066,2068],{"class":233,"line":290},[231,2053,640],{"class":237},[231,2055,2056],{"class":255}," generateReport",[231,2058,818],{"class":245},[231,2060,2061],{"class":821},"type",[231,2063,259],{"class":245},[231,2065,1523],{"class":241},[231,2067,522],{"class":245},[231,2069,246],{"class":245},[231,2071,2072],{"class":233,"line":301},[231,2073,2074],{"class":304},"    \u002F\u002F Dynamically create service based on report type\n",[231,2076,2077,2080,2083,2085,2087,2089,2091,2094,2096,2099,2101],{"class":233,"line":308},[231,2078,2079],{"class":237},"    const",[231,2081,2082],{"class":286}," service",[231,2084,317],{"class":245},[231,2086,1030],{"class":245},[231,2088,485],{"class":286},[231,2090,488],{"class":245},[231,2092,2093],{"class":323},"resolve",[231,2095,818],{"class":255},[231,2097,2098],{"class":286},"ReportService",[231,2100,522],{"class":255},[231,2102,265],{"class":245},[231,2104,2105,2107,2109,2111,2114,2116],{"class":233,"line":331},[231,2106,660],{"class":627},[231,2108,2082],{"class":286},[231,2110,488],{"class":245},[231,2112,2113],{"class":323},"generate",[231,2115,296],{"class":255},[231,2117,265],{"class":245},[231,2119,2120],{"class":233,"line":350},[231,2121,353],{"class":245},[231,2123,2124],{"class":233,"line":356},[231,2125,359],{"class":245},[208,2127,2129],{"id":2128},"testing-with-mocks","Testing with Mocks",[204,2131,2132],{},"The container makes testing incredibly easy. Replace real services with mocks for isolated testing.",[221,2134,2137],{"className":223,"code":2135,"filename":2136,"language":225,"meta":226,"style":226},"import { Container } from '@vercube\u002Fdi';\nimport { UserService } from '.\u002FUserService';\nimport type { Database } from '.\u002FDatabase';\n\ndescribe('UserService', () => {\n  it('should get users from database', async () => {\n    \u002F\u002F Create test container\n    const container = new Container();\n    \n    \u002F\u002F Mock the database\n    container.bindMock(Database, {\n      query: jest.fn().mockResolvedValue([\n        { id: 1, name: 'Test User' }\n      ])\n    });\n    \n    \u002F\u002F Register service\n    container.bind(UserService);\n    \n    \u002F\u002F Get service and test\n    const service = container.get(UserService);\n    const users = await service.getUsers();\n    \n    expect(users).toHaveLength(1);\n    expect(users[0].name).toBe('Test User');\n  });\n});\n","UserService.test.ts",[228,2138,2139,2159,2180,2203,2207,2230,2255,2260,2276,2281,2286,2303,2326,2352,2357,2367,2372,2378,2395,2400,2406,2430,2453,2458,2485,2527,2537],{"__ignoreMap":226},[231,2140,2141,2143,2145,2147,2149,2151,2153,2155,2157],{"class":233,"line":234},[231,2142,757],{"class":627},[231,2144,500],{"class":245},[231,2146,2043],{"class":286},[231,2148,768],{"class":245},[231,2150,771],{"class":627},[231,2152,687],{"class":245},[231,2154,1268],{"class":690},[231,2156,694],{"class":245},[231,2158,265],{"class":245},[231,2160,2161,2163,2165,2167,2169,2171,2173,2176,2178],{"class":233,"line":249},[231,2162,757],{"class":627},[231,2164,500],{"class":245},[231,2166,242],{"class":286},[231,2168,768],{"class":245},[231,2170,771],{"class":627},[231,2172,687],{"class":245},[231,2174,2175],{"class":690},".\u002FUserService",[231,2177,694],{"class":245},[231,2179,265],{"class":245},[231,2181,2182,2184,2186,2188,2190,2192,2194,2196,2199,2201],{"class":233,"line":268},[231,2183,757],{"class":627},[231,2185,762],{"class":627},[231,2187,500],{"class":245},[231,2189,262],{"class":286},[231,2191,768],{"class":245},[231,2193,771],{"class":627},[231,2195,687],{"class":245},[231,2197,2198],{"class":690},".\u002FDatabase",[231,2200,694],{"class":245},[231,2202,265],{"class":245},[231,2204,2205],{"class":233,"line":283},[231,2206,381],{"emptyLinePlaceholder":56},[231,2208,2209,2212,2214,2216,2218,2220,2222,2225,2228],{"class":233,"line":290},[231,2210,2211],{"class":323},"describe",[231,2213,818],{"class":286},[231,2215,694],{"class":245},[231,2217,852],{"class":690},[231,2219,694],{"class":245},[231,2221,497],{"class":245},[231,2223,2224],{"class":245}," ()",[231,2226,2227],{"class":237}," =>",[231,2229,246],{"class":245},[231,2231,2232,2235,2237,2239,2242,2244,2246,2249,2251,2253],{"class":233,"line":301},[231,2233,2234],{"class":323},"  it",[231,2236,818],{"class":255},[231,2238,694],{"class":245},[231,2240,2241],{"class":690},"should get users from database",[231,2243,694],{"class":245},[231,2245,497],{"class":245},[231,2247,2248],{"class":237}," async",[231,2250,2224],{"class":245},[231,2252,2227],{"class":237},[231,2254,246],{"class":245},[231,2256,2257],{"class":233,"line":308},[231,2258,2259],{"class":304},"    \u002F\u002F Create test container\n",[231,2261,2262,2264,2266,2268,2270,2272,2274],{"class":233,"line":331},[231,2263,2079],{"class":237},[231,2265,2038],{"class":286},[231,2267,317],{"class":245},[231,2269,320],{"class":245},[231,2271,2043],{"class":323},[231,2273,296],{"class":255},[231,2275,265],{"class":245},[231,2277,2278],{"class":233,"line":350},[231,2279,2280],{"class":255},"    \n",[231,2282,2283],{"class":233,"line":356},[231,2284,2285],{"class":304},"    \u002F\u002F Mock the database\n",[231,2287,2288,2291,2293,2295,2297,2299,2301],{"class":233,"line":445},[231,2289,2290],{"class":286},"    container",[231,2292,488],{"class":245},[231,2294,491],{"class":323},[231,2296,818],{"class":255},[231,2298,1297],{"class":286},[231,2300,497],{"class":245},[231,2302,246],{"class":245},[231,2304,2305,2308,2310,2312,2314,2316,2318,2320,2323],{"class":233,"line":1025},[231,2306,2307],{"class":255},"      query",[231,2309,259],{"class":245},[231,2311,508],{"class":286},[231,2313,488],{"class":245},[231,2315,513],{"class":323},[231,2317,296],{"class":255},[231,2319,488],{"class":245},[231,2321,2322],{"class":323},"mockResolvedValue",[231,2324,2325],{"class":255},"([\n",[231,2327,2328,2331,2333,2335,2337,2339,2341,2343,2345,2348,2350],{"class":233,"line":1045},[231,2329,2330],{"class":245},"        {",[231,2332,671],{"class":255},[231,2334,259],{"class":245},[231,2336,677],{"class":676},[231,2338,497],{"class":245},[231,2340,682],{"class":255},[231,2342,259],{"class":245},[231,2344,687],{"class":245},[231,2346,2347],{"class":690},"Test User",[231,2349,694],{"class":245},[231,2351,724],{"class":245},[231,2353,2354],{"class":233,"line":1050},[231,2355,2356],{"class":255},"      ])\n",[231,2358,2360,2363,2365],{"class":233,"line":2359},15,[231,2361,2362],{"class":245},"    }",[231,2364,522],{"class":255},[231,2366,265],{"class":245},[231,2368,2370],{"class":233,"line":2369},16,[231,2371,2280],{"class":255},[231,2373,2375],{"class":233,"line":2374},17,[231,2376,2377],{"class":304},"    \u002F\u002F Register service\n",[231,2379,2381,2383,2385,2387,2389,2391,2393],{"class":233,"line":2380},18,[231,2382,2290],{"class":286},[231,2384,488],{"class":245},[231,2386,549],{"class":323},[231,2388,818],{"class":255},[231,2390,852],{"class":286},[231,2392,522],{"class":255},[231,2394,265],{"class":245},[231,2396,2398],{"class":233,"line":2397},19,[231,2399,2280],{"class":255},[231,2401,2403],{"class":233,"line":2402},20,[231,2404,2405],{"class":304},"    \u002F\u002F Get service and test\n",[231,2407,2409,2411,2413,2415,2417,2419,2422,2424,2426,2428],{"class":233,"line":2408},21,[231,2410,2079],{"class":237},[231,2412,2082],{"class":286},[231,2414,317],{"class":245},[231,2416,2038],{"class":286},[231,2418,488],{"class":245},[231,2420,2421],{"class":323},"get",[231,2423,818],{"class":255},[231,2425,852],{"class":286},[231,2427,522],{"class":255},[231,2429,265],{"class":245},[231,2431,2433,2435,2438,2440,2443,2445,2447,2449,2451],{"class":233,"line":2432},22,[231,2434,2079],{"class":237},[231,2436,2437],{"class":286}," users",[231,2439,317],{"class":245},[231,2441,2442],{"class":627}," await",[231,2444,2082],{"class":286},[231,2446,488],{"class":245},[231,2448,1038],{"class":323},[231,2450,296],{"class":255},[231,2452,265],{"class":245},[231,2454,2456],{"class":233,"line":2455},23,[231,2457,2280],{"class":255},[231,2459,2461,2464,2466,2469,2471,2473,2476,2478,2481,2483],{"class":233,"line":2460},24,[231,2462,2463],{"class":323},"    expect",[231,2465,818],{"class":255},[231,2467,2468],{"class":286},"users",[231,2470,522],{"class":255},[231,2472,488],{"class":245},[231,2474,2475],{"class":323},"toHaveLength",[231,2477,818],{"class":255},[231,2479,2480],{"class":676},"1",[231,2482,522],{"class":255},[231,2484,265],{"class":245},[231,2486,2488,2490,2492,2494,2497,2500,2503,2505,2508,2510,2512,2515,2517,2519,2521,2523,2525],{"class":233,"line":2487},25,[231,2489,2463],{"class":323},[231,2491,818],{"class":255},[231,2493,2468],{"class":286},[231,2495,2496],{"class":255},"[",[231,2498,2499],{"class":676},"0",[231,2501,2502],{"class":255},"]",[231,2504,488],{"class":245},[231,2506,2507],{"class":286},"name",[231,2509,522],{"class":255},[231,2511,488],{"class":245},[231,2513,2514],{"class":323},"toBe",[231,2516,818],{"class":255},[231,2518,694],{"class":245},[231,2520,2347],{"class":690},[231,2522,694],{"class":245},[231,2524,522],{"class":255},[231,2526,265],{"class":245},[231,2528,2530,2533,2535],{"class":233,"line":2529},26,[231,2531,2532],{"class":245},"  }",[231,2534,522],{"class":255},[231,2536,265],{"class":245},[231,2538,2540,2542,2544],{"class":233,"line":2539},27,[231,2541,519],{"class":245},[231,2543,522],{"class":286},[231,2545,265],{"class":245},[1054,2547,2548],{},[204,2549,2550,2552],{},[228,2551,491],{}," doesn't require a complete implementation - just provide the methods you need for your test.",[208,2554,2556],{"id":2555},"container-reference","Container Reference",[204,2558,2559],{},"Access the container itself by injecting it:",[221,2561,2563],{"className":223,"code":2562,"language":225,"meta":226,"style":226},"import { Container } from '@vercube\u002Fdi';\n\nexport class MyService {\n  @Inject(Container)\n  private container!: Container;\n  \n  public doSomething() {\n    const otherService = this.container.get(OtherService);\n  }\n}\n",[228,2564,2565,2585,2589,2600,2608,2620,2624,2635,2661,2665],{"__ignoreMap":226},[231,2566,2567,2569,2571,2573,2575,2577,2579,2581,2583],{"class":233,"line":234},[231,2568,757],{"class":627},[231,2570,500],{"class":245},[231,2572,2043],{"class":286},[231,2574,768],{"class":245},[231,2576,771],{"class":627},[231,2578,687],{"class":245},[231,2580,1268],{"class":690},[231,2582,694],{"class":245},[231,2584,265],{"class":245},[231,2586,2587],{"class":233,"line":249},[231,2588,381],{"emptyLinePlaceholder":56},[231,2590,2591,2593,2595,2598],{"class":233,"line":268},[231,2592,628],{"class":627},[231,2594,631],{"class":237},[231,2596,2597],{"class":241}," MyService",[231,2599,246],{"class":245},[231,2601,2602,2604,2606],{"class":233,"line":283},[231,2603,386],{"class":245},[231,2605,389],{"class":323},[231,2607,2031],{"class":286},[231,2609,2610,2612,2614,2616,2618],{"class":233,"line":290},[231,2611,252],{"class":237},[231,2613,2038],{"class":255},[231,2615,986],{"class":245},[231,2617,2043],{"class":241},[231,2619,265],{"class":245},[231,2621,2622],{"class":233,"line":301},[231,2623,287],{"class":286},[231,2625,2626,2628,2631,2633],{"class":233,"line":308},[231,2627,640],{"class":237},[231,2629,2630],{"class":255}," doSomething",[231,2632,296],{"class":245},[231,2634,246],{"class":245},[231,2636,2637,2639,2642,2644,2646,2648,2650,2652,2654,2657,2659],{"class":233,"line":331},[231,2638,2079],{"class":237},[231,2640,2641],{"class":286}," otherService",[231,2643,317],{"class":245},[231,2645,1030],{"class":245},[231,2647,485],{"class":286},[231,2649,488],{"class":245},[231,2651,2421],{"class":323},[231,2653,818],{"class":255},[231,2655,2656],{"class":286},"OtherService",[231,2658,522],{"class":255},[231,2660,265],{"class":245},[231,2662,2663],{"class":233,"line":350},[231,2664,353],{"class":245},[231,2666,2667],{"class":233,"line":356},[231,2668,359],{"class":245},[2670,2671,2672],"warning",{},[204,2673,2674],{},"Injecting the container directly is an advanced pattern. In most cases, you should inject specific services instead. This keeps your dependencies explicit and your code easier to test.",[208,2676,2678],{"id":2677},"common-patterns","Common Patterns",[216,2680,2682],{"id":2681},"factory-pattern","Factory Pattern",[204,2684,2685],{},"Create instances dynamically based on runtime conditions:",[221,2687,2689],{"className":223,"code":2688,"language":225,"meta":226,"style":226},"export class NotificationFactory {\n  @Inject(Container)\n  private container!: Container;\n  \n  public create(type: 'email' | 'sms'): NotificationService {\n    if (type === 'email') {\n      return this.container.resolve(EmailNotificationService);\n    }\n    return this.container.resolve(SmsNotificationService);\n  }\n}\n",[228,2690,2691,2702,2710,2722,2726,2762,2783,2805,2809,2830,2834],{"__ignoreMap":226},[231,2692,2693,2695,2697,2700],{"class":233,"line":234},[231,2694,628],{"class":627},[231,2696,631],{"class":237},[231,2698,2699],{"class":241}," NotificationFactory",[231,2701,246],{"class":245},[231,2703,2704,2706,2708],{"class":233,"line":249},[231,2705,386],{"class":245},[231,2707,389],{"class":323},[231,2709,2031],{"class":286},[231,2711,2712,2714,2716,2718,2720],{"class":233,"line":268},[231,2713,252],{"class":237},[231,2715,2038],{"class":255},[231,2717,986],{"class":245},[231,2719,2043],{"class":241},[231,2721,265],{"class":245},[231,2723,2724],{"class":233,"line":283},[231,2725,287],{"class":286},[231,2727,2728,2730,2733,2735,2737,2739,2741,2744,2746,2748,2750,2753,2755,2757,2760],{"class":233,"line":290},[231,2729,640],{"class":237},[231,2731,2732],{"class":255}," create",[231,2734,818],{"class":245},[231,2736,2061],{"class":821},[231,2738,259],{"class":245},[231,2740,687],{"class":245},[231,2742,2743],{"class":690},"email",[231,2745,694],{"class":245},[231,2747,1877],{"class":245},[231,2749,687],{"class":245},[231,2751,2752],{"class":690},"sms",[231,2754,694],{"class":245},[231,2756,829],{"class":245},[231,2758,2759],{"class":241}," NotificationService",[231,2761,246],{"class":245},[231,2763,2764,2766,2768,2770,2773,2775,2777,2779,2781],{"class":233,"line":301},[231,2765,1920],{"class":627},[231,2767,1923],{"class":255},[231,2769,2061],{"class":286},[231,2771,2772],{"class":245}," ===",[231,2774,687],{"class":245},[231,2776,2743],{"class":690},[231,2778,694],{"class":245},[231,2780,1932],{"class":255},[231,2782,655],{"class":245},[231,2784,2785,2788,2790,2792,2794,2796,2798,2801,2803],{"class":233,"line":308},[231,2786,2787],{"class":627},"      return",[231,2789,1030],{"class":245},[231,2791,485],{"class":286},[231,2793,488],{"class":245},[231,2795,2093],{"class":323},[231,2797,818],{"class":255},[231,2799,2800],{"class":286},"EmailNotificationService",[231,2802,522],{"class":255},[231,2804,265],{"class":245},[231,2806,2807],{"class":233,"line":331},[231,2808,1969],{"class":245},[231,2810,2811,2813,2815,2817,2819,2821,2823,2826,2828],{"class":233,"line":350},[231,2812,660],{"class":627},[231,2814,1030],{"class":245},[231,2816,485],{"class":286},[231,2818,488],{"class":245},[231,2820,2093],{"class":323},[231,2822,818],{"class":255},[231,2824,2825],{"class":286},"SmsNotificationService",[231,2827,522],{"class":255},[231,2829,265],{"class":245},[231,2831,2832],{"class":233,"line":356},[231,2833,353],{"class":245},[231,2835,2836],{"class":233,"line":445},[231,2837,359],{"class":245},[208,2839,2841],{"id":2840},"best-practices","Best Practices",[204,2843,2844,2847],{},[467,2845,2846],{},"Keep constructors clean"," - Let the container inject dependencies, don't do heavy work in constructors",[221,2849,2851],{"className":223,"code":2850,"language":225,"meta":226,"style":226},"\u002F\u002F ✅ Good\nexport class UserService {\n  @Inject(Database)\n  private db!: Database;\n}\n\n\u002F\u002F ❌ Bad\nexport class UserService {\n  private db: Database;\n  \n  constructor() {\n    this.db = new Database();\n    this.db.connect(); \u002F\u002F Heavy work in constructor\n  }\n}\n",[228,2852,2853,2858,2868,2876,2889,2893,2897,2902,2912,2924,2928,2936,2953,2972,2976],{"__ignoreMap":226},[231,2854,2855],{"class":233,"line":234},[231,2856,2857],{"class":304},"\u002F\u002F ✅ Good\n",[231,2859,2860,2862,2864,2866],{"class":233,"line":249},[231,2861,628],{"class":627},[231,2863,631],{"class":237},[231,2865,242],{"class":241},[231,2867,246],{"class":245},[231,2869,2870,2872,2874],{"class":233,"line":268},[231,2871,386],{"class":245},[231,2873,389],{"class":323},[231,2875,392],{"class":286},[231,2877,2878,2880,2883,2885,2887],{"class":233,"line":283},[231,2879,252],{"class":237},[231,2881,2882],{"class":255}," db",[231,2884,986],{"class":245},[231,2886,262],{"class":241},[231,2888,265],{"class":245},[231,2890,2891],{"class":233,"line":290},[231,2892,359],{"class":245},[231,2894,2895],{"class":233,"line":301},[231,2896,381],{"emptyLinePlaceholder":56},[231,2898,2899],{"class":233,"line":308},[231,2900,2901],{"class":304},"\u002F\u002F ❌ Bad\n",[231,2903,2904,2906,2908,2910],{"class":233,"line":331},[231,2905,628],{"class":627},[231,2907,631],{"class":237},[231,2909,242],{"class":241},[231,2911,246],{"class":245},[231,2913,2914,2916,2918,2920,2922],{"class":233,"line":350},[231,2915,252],{"class":237},[231,2917,2882],{"class":255},[231,2919,259],{"class":245},[231,2921,262],{"class":241},[231,2923,265],{"class":245},[231,2925,2926],{"class":233,"line":356},[231,2927,287],{"class":286},[231,2929,2930,2932,2934],{"class":233,"line":445},[231,2931,293],{"class":237},[231,2933,296],{"class":245},[231,2935,246],{"class":245},[231,2937,2938,2940,2943,2945,2947,2949,2951],{"class":233,"line":1025},[231,2939,311],{"class":245},[231,2941,2942],{"class":286},"db",[231,2944,317],{"class":245},[231,2946,320],{"class":245},[231,2948,262],{"class":323},[231,2950,296],{"class":255},[231,2952,265],{"class":245},[231,2954,2955,2957,2959,2961,2964,2966,2969],{"class":233,"line":1045},[231,2956,311],{"class":245},[231,2958,2942],{"class":286},[231,2960,488],{"class":245},[231,2962,2963],{"class":323},"connect",[231,2965,296],{"class":255},[231,2967,2968],{"class":245},";",[231,2970,2971],{"class":304}," \u002F\u002F Heavy work in constructor\n",[231,2973,2974],{"class":233,"line":1050},[231,2975,353],{"class":245},[231,2977,2978],{"class":233,"line":2359},[231,2979,359],{"class":245},[204,2981,2982,2985],{},[467,2983,2984],{},"Use interfaces for flexibility"," - Program to interfaces, not implementations",[221,2987,2989],{"className":223,"code":2988,"language":225,"meta":226,"style":226},"\u002F\u002F ✅ Good\n@Inject(ILogger)\nprivate logger!: Logger;\n\n\u002F\u002F ❌ Less flexible\n@Inject(FileLogger)\nprivate logger!: FileLogger;\n",[228,2990,2991,2995,3004,3016,3020,3025,3034],{"__ignoreMap":226},[231,2992,2993],{"class":233,"line":234},[231,2994,2857],{"class":304},[231,2996,2997,2999,3001],{"class":233,"line":249},[231,2998,937],{"class":245},[231,3000,389],{"class":323},[231,3002,3003],{"class":286},"(ILogger)\n",[231,3005,3006,3009,3011,3014],{"class":233,"line":268},[231,3007,3008],{"class":286},"private logger",[231,3010,1061],{"class":245},[231,3012,3013],{"class":286},": Logger",[231,3015,265],{"class":245},[231,3017,3018],{"class":233,"line":283},[231,3019,381],{"emptyLinePlaceholder":56},[231,3021,3022],{"class":233,"line":290},[231,3023,3024],{"class":304},"\u002F\u002F ❌ Less flexible\n",[231,3026,3027,3029,3031],{"class":233,"line":301},[231,3028,937],{"class":245},[231,3030,389],{"class":323},[231,3032,3033],{"class":286},"(FileLogger)\n",[231,3035,3036,3038,3040,3043],{"class":233,"line":308},[231,3037,3008],{"class":286},[231,3039,1061],{"class":245},[231,3041,3042],{"class":286},": FileLogger",[231,3044,265],{"class":245},[204,3046,3047,3050],{},[467,3048,3049],{},"One responsibility per service"," - Keep services focused",[221,3052,3054],{"className":223,"code":3053,"language":225,"meta":226,"style":226},"\u002F\u002F ✅ Good\nexport class UserService { \u002F* user operations *\u002F }\nexport class AuthService { \u002F* auth operations *\u002F }\n\n\u002F\u002F ❌ Bad\nexport class UserAuthService { \u002F* users AND auth *\u002F }\n",[228,3055,3056,3060,3075,3091,3095,3099],{"__ignoreMap":226},[231,3057,3058],{"class":233,"line":234},[231,3059,2857],{"class":304},[231,3061,3062,3064,3066,3068,3070,3073],{"class":233,"line":249},[231,3063,628],{"class":627},[231,3065,631],{"class":237},[231,3067,242],{"class":241},[231,3069,500],{"class":245},[231,3071,3072],{"class":304}," \u002F* user operations *\u002F",[231,3074,724],{"class":245},[231,3076,3077,3079,3081,3084,3086,3089],{"class":233,"line":268},[231,3078,628],{"class":627},[231,3080,631],{"class":237},[231,3082,3083],{"class":241}," AuthService",[231,3085,500],{"class":245},[231,3087,3088],{"class":304}," \u002F* auth operations *\u002F",[231,3090,724],{"class":245},[231,3092,3093],{"class":233,"line":283},[231,3094,381],{"emptyLinePlaceholder":56},[231,3096,3097],{"class":233,"line":290},[231,3098,2901],{"class":304},[231,3100,3101,3103,3105,3108,3110,3113],{"class":233,"line":301},[231,3102,628],{"class":627},[231,3104,631],{"class":237},[231,3106,3107],{"class":241}," UserAuthService",[231,3109,500],{"class":245},[231,3111,3112],{"class":304}," \u002F* users AND auth *\u002F",[231,3114,724],{"class":245},[204,3116,3117,3120],{},[467,3118,3119],{},"Avoid circular dependencies"," - If Service A needs Service B and Service B needs Service A, rethink your design",[221,3122,3124],{"className":223,"code":3123,"language":225,"meta":226,"style":226},"\u002F\u002F ❌ Bad - circular dependency\nclass A {\n  @Inject(B) b!: B;\n}\n\nclass B {\n  @Inject(A) a!: A;\n}\n\n\u002F\u002F ✅ Good - extract shared logic\nclass SharedLogic { }\nclass A {\n  @Inject(SharedLogic) logic!: SharedLogic;\n}\nclass B {\n  @Inject(SharedLogic) logic!: SharedLogic;\n}\n",[228,3125,3126,3131,3140,3159,3163,3167,3175,3193,3197,3201,3206,3217,3225,3243,3247,3255,3271],{"__ignoreMap":226},[231,3127,3128],{"class":233,"line":234},[231,3129,3130],{"class":304},"\u002F\u002F ❌ Bad - circular dependency\n",[231,3132,3133,3135,3138],{"class":233,"line":249},[231,3134,238],{"class":237},[231,3136,3137],{"class":241}," A",[231,3139,246],{"class":245},[231,3141,3142,3144,3146,3149,3152,3154,3157],{"class":233,"line":268},[231,3143,386],{"class":245},[231,3145,389],{"class":323},[231,3147,3148],{"class":286},"(B) ",[231,3150,3151],{"class":255},"b",[231,3153,986],{"class":245},[231,3155,3156],{"class":241}," B",[231,3158,265],{"class":245},[231,3160,3161],{"class":233,"line":283},[231,3162,359],{"class":245},[231,3164,3165],{"class":233,"line":290},[231,3166,381],{"emptyLinePlaceholder":56},[231,3168,3169,3171,3173],{"class":233,"line":301},[231,3170,238],{"class":237},[231,3172,3156],{"class":241},[231,3174,246],{"class":245},[231,3176,3177,3179,3181,3184,3187,3189,3191],{"class":233,"line":308},[231,3178,386],{"class":245},[231,3180,389],{"class":323},[231,3182,3183],{"class":286},"(A) ",[231,3185,3186],{"class":255},"a",[231,3188,986],{"class":245},[231,3190,3137],{"class":241},[231,3192,265],{"class":245},[231,3194,3195],{"class":233,"line":331},[231,3196,359],{"class":245},[231,3198,3199],{"class":233,"line":350},[231,3200,381],{"emptyLinePlaceholder":56},[231,3202,3203],{"class":233,"line":356},[231,3204,3205],{"class":304},"\u002F\u002F ✅ Good - extract shared logic\n",[231,3207,3208,3210,3213,3215],{"class":233,"line":445},[231,3209,238],{"class":237},[231,3211,3212],{"class":241}," SharedLogic",[231,3214,500],{"class":245},[231,3216,724],{"class":245},[231,3218,3219,3221,3223],{"class":233,"line":1025},[231,3220,238],{"class":237},[231,3222,3137],{"class":241},[231,3224,246],{"class":245},[231,3226,3227,3229,3231,3234,3237,3239,3241],{"class":233,"line":1045},[231,3228,386],{"class":245},[231,3230,389],{"class":323},[231,3232,3233],{"class":286},"(SharedLogic) ",[231,3235,3236],{"class":255},"logic",[231,3238,986],{"class":245},[231,3240,3212],{"class":241},[231,3242,265],{"class":245},[231,3244,3245],{"class":233,"line":1050},[231,3246,359],{"class":245},[231,3248,3249,3251,3253],{"class":233,"line":2359},[231,3250,238],{"class":237},[231,3252,3156],{"class":241},[231,3254,246],{"class":245},[231,3256,3257,3259,3261,3263,3265,3267,3269],{"class":233,"line":2369},[231,3258,386],{"class":245},[231,3260,389],{"class":323},[231,3262,3233],{"class":286},[231,3264,3236],{"class":255},[231,3266,986],{"class":245},[231,3268,3212],{"class":241},[231,3270,265],{"class":245},[231,3272,3273],{"class":233,"line":2374},[231,3274,359],{"class":245},[208,3276,3278],{"id":3277},"troubleshooting","Troubleshooting",[216,3280,3282],{"id":3281},"unresolved-dependency-error","\"Unresolved dependency\" Error",[204,3284,3285],{},"This means you tried to inject a service that wasn't registered in the container.",[221,3287,3289],{"className":223,"code":3288,"language":225,"meta":226,"style":226},"\u002F\u002F Error: Unresolved dependency for [UserService]\n@Inject(UserService)\nprivate userService!: UserService;\n",[228,3290,3291,3296,3304],{"__ignoreMap":226},[231,3292,3293],{"class":233,"line":234},[231,3294,3295],{"class":304},"\u002F\u002F Error: Unresolved dependency for [UserService]\n",[231,3297,3298,3300,3302],{"class":233,"line":249},[231,3299,937],{"class":245},[231,3301,389],{"class":323},[231,3303,976],{"class":286},[231,3305,3306,3309,3311,3314],{"class":233,"line":268},[231,3307,3308],{"class":286},"private userService",[231,3310,1061],{"class":245},[231,3312,3313],{"class":286},": UserService",[231,3315,265],{"class":245},[204,3317,3318,3321],{},[467,3319,3320],{},"Solution:"," Register the service in your setup:",[221,3323,3325],{"className":223,"code":3324,"language":225,"meta":226,"style":226},"app.container.bind(UserService);\n",[228,3326,3327],{"__ignoreMap":226},[231,3328,3329,3331,3333,3335,3337,3339,3342],{"class":233,"line":234},[231,3330,822],{"class":286},[231,3332,488],{"class":245},[231,3334,485],{"class":286},[231,3336,488],{"class":245},[231,3338,549],{"class":323},[231,3340,3341],{"class":286},"(UserService)",[231,3343,265],{"class":245},[216,3345,3347],{"id":3346},"typescript-error-property-has-no-initializer","TypeScript Error: Property has no initializer",[221,3349,3351],{"className":223,"code":3350,"language":225,"meta":226,"style":226},"\u002F\u002F Error: Property 'userService' has no initializer\n@Inject(UserService)\nprivate userService: UserService;\n",[228,3352,3353,3358,3366],{"__ignoreMap":226},[231,3354,3355],{"class":233,"line":234},[231,3356,3357],{"class":304},"\u002F\u002F Error: Property 'userService' has no initializer\n",[231,3359,3360,3362,3364],{"class":233,"line":249},[231,3361,937],{"class":245},[231,3363,389],{"class":323},[231,3365,976],{"class":286},[231,3367,3368,3371,3373,3375,3377],{"class":233,"line":268},[231,3369,3370],{"class":286},"private ",[231,3372,1033],{"class":241},[231,3374,259],{"class":245},[231,3376,242],{"class":286},[231,3378,265],{"class":245},[204,3380,3381,3383,3384,3386],{},[467,3382,3320],{}," Add the ",[228,3385,1061],{}," definite assignment assertion:",[221,3388,3390],{"className":223,"code":3389,"language":225,"meta":226,"style":226},"@Inject(UserService)\nprivate userService!: UserService;\n",[228,3391,3392,3400],{"__ignoreMap":226},[231,3393,3394,3396,3398],{"class":233,"line":234},[231,3395,937],{"class":245},[231,3397,389],{"class":323},[231,3399,976],{"class":286},[231,3401,3402,3404,3406,3408],{"class":233,"line":249},[231,3403,3308],{"class":286},[231,3405,1061],{"class":245},[231,3407,3313],{"class":286},[231,3409,265],{"class":245},[216,3411,3413],{"id":3412},"service-is-undefined-when-accessed","Service is undefined when accessed",[204,3415,3416],{},"Make sure you're accessing the service after the container has initialized:",[221,3418,3420],{"className":223,"code":3419,"language":225,"meta":226,"style":226},"\u002F\u002F ❌ Bad - accessing in constructor\nconstructor() {\n  console.log(this.userService); \u002F\u002F undefined!\n}\n\n\u002F\u002F ✅ Good - accessing in methods\npublic getUsers() {\n  console.log(this.userService); \u002F\u002F works!\n}\n",[228,3421,3422,3427,3435,3458,3462,3466,3471,3482,3503],{"__ignoreMap":226},[231,3423,3424],{"class":233,"line":234},[231,3425,3426],{"class":304},"\u002F\u002F ❌ Bad - accessing in constructor\n",[231,3428,3429,3431,3433],{"class":233,"line":249},[231,3430,579],{"class":323},[231,3432,516],{"class":286},[231,3434,655],{"class":245},[231,3436,3437,3440,3442,3445,3447,3449,3451,3453,3455],{"class":233,"line":268},[231,3438,3439],{"class":286},"  console",[231,3441,488],{"class":245},[231,3443,3444],{"class":323},"log",[231,3446,818],{"class":255},[231,3448,1926],{"class":245},[231,3450,1033],{"class":286},[231,3452,522],{"class":255},[231,3454,2968],{"class":245},[231,3456,3457],{"class":304}," \u002F\u002F undefined!\n",[231,3459,3460],{"class":233,"line":283},[231,3461,359],{"class":245},[231,3463,3464],{"class":233,"line":290},[231,3465,381],{"emptyLinePlaceholder":56},[231,3467,3468],{"class":233,"line":301},[231,3469,3470],{"class":304},"\u002F\u002F ✅ Good - accessing in methods\n",[231,3472,3473,3476,3478,3480],{"class":233,"line":308},[231,3474,3475],{"class":286},"public ",[231,3477,1038],{"class":323},[231,3479,516],{"class":286},[231,3481,655],{"class":245},[231,3483,3484,3486,3488,3490,3492,3494,3496,3498,3500],{"class":233,"line":331},[231,3485,3439],{"class":286},[231,3487,488],{"class":245},[231,3489,3444],{"class":323},[231,3491,818],{"class":255},[231,3493,1926],{"class":245},[231,3495,1033],{"class":286},[231,3497,522],{"class":255},[231,3499,2968],{"class":245},[231,3501,3502],{"class":304}," \u002F\u002F works!\n",[231,3504,3505],{"class":233,"line":350},[231,3506,359],{"class":245},[3508,3509,3510],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":226,"searchDepth":234,"depth":249,"links":3512},[3513,3517,3520,3525,3530,3534,3535,3536,3537,3538,3539,3542,3543],{"id":210,"depth":249,"text":211,"children":3514},[3515,3516],{"id":218,"depth":268,"text":219},{"id":362,"depth":268,"text":363},{"id":450,"depth":249,"text":451,"children":3518},[3519],{"id":462,"depth":268,"text":463},{"id":608,"depth":249,"text":609,"children":3521},[3522,3523,3524],{"id":612,"depth":268,"text":613},{"id":742,"depth":268,"text":743},{"id":863,"depth":268,"text":864},{"id":1065,"depth":249,"text":1066,"children":3526},[3527,3528,3529],{"id":1072,"depth":268,"text":1073},{"id":1137,"depth":268,"text":1138},{"id":1176,"depth":268,"text":1177},{"id":1236,"depth":249,"text":1237,"children":3531},[3532,3533],{"id":1243,"depth":268,"text":1244},{"id":1486,"depth":268,"text":1487},{"id":1670,"depth":249,"text":1671},{"id":1801,"depth":249,"text":1802},{"id":1985,"depth":249,"text":1986},{"id":2128,"depth":249,"text":2129},{"id":2555,"depth":249,"text":2556},{"id":2677,"depth":249,"text":2678,"children":3540},[3541],{"id":2681,"depth":268,"text":2682},{"id":2840,"depth":249,"text":2841},{"id":3277,"depth":249,"text":3278,"children":3544},[3545,3546,3547],{"id":3281,"depth":268,"text":3282},{"id":3346,"depth":268,"text":3347},{"id":3412,"depth":268,"text":3413},"Understanding and using the Dependency Injection container in Vercube","md",null,{},{"title":37,"description":3548},"jjao_s0s6Ia3pir_HMKuxFVf2mr2ItCZrZaoSh5J5cU",[3555,3557],{"title":33,"path":34,"stem":35,"description":3556,"children":-1},"Configure your Vercube application",{"title":41,"path":42,"stem":43,"description":3558,"children":-1},"Building APIs with Controllers in Vercube",1775552780365]