Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fundamentals docs pages #234

Merged
merged 5 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
sidebar_position: 2
title: DI Hierarchy
---
import diHierarchySource from '@inversifyjs/code-examples/generated/examples/diHierarchy.ts.txt';
import CodeBlock from '@theme/CodeBlock';

# DI Hierarchy
Some applications use a hierarchical dependency injection (DI) system.
For example, Angular applications use its own [hierarchical DI system](https://angular.dev/guide/di/hierarchical-dependency-injection).

In a hierarchical DI system, a container can have a parent container and multiple containers can be used in one application. The containers form a hierarchical structure.

When a container at the bottom of the hierarchical structure requests a dependency,
the container tries to satisfy that dependency with it's own bindings. If the container
lacks bindings, it passes the request up to its parent container. If that container can't
satisfy the request, it passes it along to its parent container. The requests keep
bubbling up until we find an container that can handle the request or run out of container
ancestors.

<CodeBlock language="ts">{diHierarchySource}</CodeBlock>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
sidebar_position: 4
title: Inheritance
---
# Inheritance

Inheritance can be accomplished as long as constructor parameters are properly decorated. There're two ways to have constructor parameters properly decorated:

- The number of decorated constructor arguments in a derived class is greater or equal than the number of constructor arguments in its base class.
- [skipBaseClassChecks](/docs/api/container#skipbaseclasschecks) option is enabled

## Example of wrong inheritance injection

```ts
@injectable()
class Warrior {
public rank: string;
constructor(rank: string) { // args count = 1
this.rank = rank;
}
}

@injectable()
class SamuraiMaster extends Warrior {
constructor() { // args count = 0
super("master");
}
}
```

When trying to get a `SamuraiMaster`, the container throws an Error alerting the constructor parameters are not properly decorated.

## Using @unmanaged decorator

The [unmanaged](/docs/api/decorator#unmanaged) decorator is a good way to tell inversify a base type constructor param is should not be managed. This is often the case when dealing with inheritance hierarchies in which only leaf types are injected.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"label": "Lifecycle",
"position": 2
"position": 3
}
4 changes: 2 additions & 2 deletions packages/docs/services/inversify-site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
},
"license": "MIT",
"name": "@inversifyjs/inversify-docs-site",
"private": true,
"publishConfig": {
"access": "public"
},
Expand All @@ -61,6 +62,5 @@
"lint": "eslint ./src ./docusaurus.config.ts ./sidebars.ts",
"serve": "docusaurus serve",
"typecheck": "tsc"
},
"version": "1.0.0"
}
}
4 changes: 2 additions & 2 deletions packages/docs/tools/inversify-code-examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
},
"license": "MIT",
"name": "@inversifyjs/code-examples",
"private": true,
"publishConfig": {
"access": "public"
},
Expand All @@ -61,6 +62,5 @@
"test:js:coverage": "pnpm run test:unit:js --coverage",
"test:uncommitted": "pnpm run test --changedSince=HEAD",
"test:unit:js": "pnpm run test:js --selectProjects Unit"
},
"version": "1.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { describe, expect, it } from '@jest/globals';

import { Katana, katana } from './diHierarchy';

describe('DI Hierachy', () => {
it('should provide a Katana', () => {
expect(katana).toBeInstanceOf(Katana);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Container } from 'inversify';

const weaponIdentifier: symbol = Symbol.for('Weapon');

// Begin-example
class Katana {}

const parentContainer: Container = new Container();
parentContainer.bind(weaponIdentifier).to(Katana);

const childContainer: Container = parentContainer.createChild();

const katana: Katana = childContainer.get(weaponIdentifier);
// End-example

export { Katana, katana };
Loading