{"id":16726293,"url":"https://github.com/cmd-johnson/deno-dependency-injector","last_synced_at":"2025-04-10T10:24:17.088Z","repository":{"id":62421784,"uuid":"304019204","full_name":"cmd-johnson/deno-dependency-injector","owner":"cmd-johnson","description":"Simple dependency injection for Deno TypeScript projects.","archived":false,"fork":false,"pushed_at":"2021-10-10T11:18:53.000Z","size":24,"stargazers_count":13,"open_issues_count":4,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T09:11:38.321Z","etag":null,"topics":["deno","dependency-injection","hacktoberfest","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cmd-johnson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-10-14T13:11:44.000Z","updated_at":"2023-11-13T16:16:25.000Z","dependencies_parsed_at":"2022-11-01T17:31:48.462Z","dependency_job_id":null,"html_url":"https://github.com/cmd-johnson/deno-dependency-injector","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmd-johnson%2Fdeno-dependency-injector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmd-johnson%2Fdeno-dependency-injector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmd-johnson%2Fdeno-dependency-injector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmd-johnson%2Fdeno-dependency-injector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cmd-johnson","download_url":"https://codeload.github.com/cmd-johnson/deno-dependency-injector/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248199088,"owners_count":21063641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","dependency-injection","hacktoberfest","typescript"],"created_at":"2024-10-12T22:52:45.332Z","updated_at":"2025-04-10T10:24:17.053Z","avatar_url":"https://github.com/cmd-johnson.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Deno Dependency Injector\nSimple dependency injection for Deno TypeScript projects.\n\nThis module's aims to provide you with an extremely simple API, without any bells and whistles and the 100% test coverage that comes with such a minimal feature set.\n\nAs such, this module allows you to\n- inject classes into other classes through their constructor\n- inject classes as singletons *or* inject a new instance of the class every time it is used\n- override/replace certain injected classes (e.g. for replacing them with a mock for testing purposes)\n\nThat's it.\n\nNeed to inject a plain string? Wrap it in a class!\nNeed to inject a function? Wrap it in a class!\n\nThere's no need to make things more complicated than necessary.\n\n## Usage\n### 1. Create `@Injectable()` classes\n```ts\n// class_a.ts\nimport { Injectable } from \"https://deno.land/x/inject/mod.ts\";\n\n@Injectable()\nexport class ClassA {\n  hello() {\n    return \"Hello from ClassA!\";\n  }\n}\n```\n\n### 2. Inject Injectable classes through constructors\n```ts\n// class_b.ts\nimport { Injectable } from \"https://deno.land/x/inject/mod.ts\";\nimport { ClassA } from \"./class_a.ts\";\n\n@Injectable()\nexport class ClassB {\n  constructor(\n    private readonly classA: ClassA,\n  ) {}\n\n  hello() {\n    return `Hello from ClassB and ${this.classA.hello()}!`;\n  }\n}\n```\n\n### 3. Create a Bootstrapped class and let the injector take care of creation\n```ts\n// main.ts\nimport { Bootstrapped, bootstrap } from \"https://deno.land/x/inject/mod.ts\";\nimport { ClassB } from \"./class_b.ts\";\n\n@Bootstrapped()\nexport class Main {\n  constructor(\n    private readonly classB: ClassB,\n  ) {}\n\n  hello() {\n    return this.classB.hello();\n  }\n}\n\nconst main = bootstrap(Main);\n\nconsole.log(main.hello());\n```\n\n### 4. Run your App!\n```sh\ndeno run -c tsconfig.json main.ts\n# Hello from ClassB and Hello from ClassA!!\n```\n\nRemember to have a `tsconfig.json` with the following content in your project's root directory and always call `deno run` with the additional `-c tsconfig.json` parameter or Deno will complain about missing experimental support for decorators.\n\n```json\n{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n\n## Overriding dependencies\nDuring testing, it may be useful to override certain dependencies of the class under test with mocks.\nThis module allows you to do just that:\n\n```ts\nimport { Injectable, Bootstrappable, bootstrap } from \"https://deno.land/x/inject/mod.ts\";\nimport { assertEquals } from \"https://deno.land/std/test/mod.ts\";\n\n@Injectable()\nclass Dependency {\n  value = \"Original dependency\";\n}\n\n@Injectable()\nclass ClassUnderTest {\n  constructor(public dependency: Dependency) {}\n\n  getValue() {\n    return this.dependency.value;\n  }\n}\n\n@Injectable()\nclass OverrideDependency {\n  constructor(public original: Dependency) {}\n\n  value = \"Override dependency\";\n}\n\nDeno.test(\"ClassUnderTest dependency is overridden\", () =\u003e {\n  const instance = bootstrap(ClassUnderTest, new Map([[Dependency, OverrideDependency]]));\n\n  assertEquals(instance.getValue(), \"Override dependency\");\n  assertEquals((instance.dependency as unknown as OverrideDependency).original.value, \"Original dependency\");\n});\n```\n\nNote that when overriding class `A` with class `B`, an instance of `A` can still be injected into `B`, but all other classes depending on `A` will get an instance of `B` instead.\n\n## API\n### `@Injectable(options?: { isSingleton: boolean })`\nDecorator used to mark a class as injectable.\nYou can only inject classes that are declared with the `@Injectable()` decorator.\n\nYou can pass an optional options parameter to the `@Injectable()` decorator:\n- **`isSingleton`** (default: `true`): wether the class should be injected as a singleton or if a new instance should be created for every class that injects this type.\n\n    \u003e Checkout `examples/instanced_counter.ts` and `examples/singleton_counter.ts` for example usages of the `isSingleton` property.\n\n### `@Bootstrapped()`\nDecorator used to make a class bootstrappable.\n\nDoesn't do anything else but making the class known to the TypeScript's reflection system, which is required for the dependency injector to know the types you want to inject.\n\nYou can also bootstrap classes that are otherwise known to the reflection system, e.g. because they are `@Injectable` or bear any other decorator, but it is recommended to stick to using the `@Bootstrapped` decorator for consistency and making it easier to find your application's main entry point(s).\n\nDuring testing, it is perfectly fine to bootstrap `@Injectable` classes, of course.\n\n### `bootstrap\u003cT\u003e(Type: Constructor\u003cT\u003e, overrides?: Map\u003cConstructor, Constructor\u003e): T`\nThe one function call to rule them all.\n\nAutomatically creates an instance of the class you pass it, as long as all dependencies in the constructor (and their dependency's constructors) are `@Injectable`.\n\nOptionally takes a `Map` that you can use to override certain injected classes with some other `@Injectable` class, for example to mock dependencies during testing.\n\nThis function is shorthand for `new Injector(overrides).bootstrap(Type)`.\n\nUse the `Injector` class if you want to bootstrap more than one class using the same resolved dependencies and overrides.\n\n### `Injector`\nThe actual class responsible for discovering and creating all `@Injectable` classes required by your `@Bootstrapped` class.\n\n#### `new Injector(overrides?: Map\u003cConstructor, Constructor\u003e)`\nCreates a new `Injector` class with the optionally specified overrides for dependency resolution (see `bootstrap(Type, overrides?)` for more information).\n\n#### `bootstrap\u003cT\u003e(Type: Constructor\u003cT\u003e): T`\nResolves the dependency tree of the given class and creates instances of all required dependencies, taking into account the overrides passed during creation of the `Injector`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmd-johnson%2Fdeno-dependency-injector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcmd-johnson%2Fdeno-dependency-injector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmd-johnson%2Fdeno-dependency-injector/lists"}