Skip to content

Commit

Permalink
📝 docs: add life cycle and decorators examples
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor MENDELE committed May 21, 2020
1 parent 89b76b5 commit 17d1215
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
65 changes: 65 additions & 0 deletions DECORATORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Decorators / Reflection support

As mentions in [README](README.new.md#Decorators) this package
supports decorators and reflection.

This package use decorators in a passive way meaning
that the only role of a decorator in to attach metadata.
The active work such as registering or instantiating is done by
service loaders or container itself.

## Example

To illustrate the usage of decorators, we will use
the same example as in [README](README.new.md#Example)

````typescript
import { Inject, Service } from '@botflx/dependency-injection-container'

@Service('logger')
class Logger {}

@Service('db')
class DatabaseConnection {
private logger: Logger

// You don't need to call container.get
// You can directly use @Inject
constructor(
@Inject('logger') logger: Logger
) {
this.logger = logger
}
}

function getUsers (db: DatabaseConnection) {}
````

`IServiceContainer` implementations provide an fluent API for adders. `IServiceContainer` provides an
API to add class-style and function-style services.

````typescript
import {createServiceContainer, createReflectServiceLoader} from '@botflx/dependency-injection-container'

// Create a service container using factory function
const container: IServiceContainer = createServiceContainer({
useReflection: true,
// In order to load services you must use IServiceLoader
// that supports Reflection.
// Under the hood this service loader will read the decorators's metadata
// and call the `container.add()` method.
serviceLoader: createReflectServiceLoader([ Logger, DatabaseConnection ], [])
})

// Add function-style using factory functions
// Even with decorators supports factory functions still works the same as with
// non-reflection container. This way you still will be able to add function or
// classes you can't decorate.
container
.addFactory('getUsers', (container: IServiceContainer) => getUsers.bind(null, container.get('db')))

// Retrieve services
const getUsers = container.get<Function>('getUsers')
const db = container.get<DatabaseConnection>('db')
const logger = container.get<Logger>('logger')
````
16 changes: 13 additions & 3 deletions README.new.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@ This package is designed with retro-compatibility in mind.

### Decorators

Reflection and Decorators are supported. This package provide also an API without decorators.
Reflection and Decorators are [supported](DECORATORS.md). This package provide also an API without decorators.

### Example

As a DI container handles dependency I will first declare some services.
As a DI container handles instantiation I will first declare some services that will be instantiated.

````typescript
class Logger {}

class DatabaseConnection {
constructor(container: IServiceContainer) {}
private logger: Logger

constructor(container: IServiceContainer) {
this.logger = container.get<Logger>('logger')
}
}

function getUsers (db: DatabaseConnection) {}
Expand Down Expand Up @@ -52,6 +56,12 @@ const db = container.get<DatabaseConnection>('db')
const logger = container.get<Logger>('logger')
````

### Services life cycle

Services are instantiated when you call `container.get(serviceName)`.
The instance is deleted when you `container.delete(serviceName)`.
Deletion is performed with the `delete` keyword.

### Recommendation

I recommend when it comes to instantiation to use as much as possible factory functions and interfaces, this way package updates will be less difficult.
Expand Down

0 comments on commit 17d1215

Please sign in to comment.