Skip to content

Commit 7b6223f

Browse files
committed
docs(getting-started): CI/CD
1 parent b941083 commit 7b6223f

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

src/content/002-getting-started-with-a-boilerplate.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
layout: post
3-
title: 'Getting started with the FuryStack Boilerplate'
3+
title: 'Getting started with the Boilerplate 🏁'
44
author: [gallayl]
5-
tags: ['getting-started']
5+
tags: ['getting-started', 'boilerplate']
66
image: img/002-getting-started-with-a-boilerplate-cover.jpg
77
date: '2021-06-23T08:48:20.257Z'
88
draft: false
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
layout: post
3+
title: 'DI / IOC with @furystack/inject 💉'
4+
author: [gallayl]
5+
tags: ['getting-started', 'inject']
6+
image: img/003-getting-started-with-inject-cover.jpg
7+
date: '2021-06-23T08:58:20.257Z'
8+
draft: false
9+
excerpt: Dependency injection and Inversion of control is a common practice that tries to protect you from insanity that would happen when you realize that you can't refactor and test a giant global static app structure. @furystack/inject is a simple but powerful tool that you can use in NodeJs and in the browser.
10+
---
11+
12+
## Injectable services
13+
An _injectable service_ is basically a class, decorated with the `@Injectable()` decorator. If you decorate a class, its injectable options (e.g. lifetime) and constructor argument types will be stored and the injector will be able to instantiate a new instance any time. Constructor arguments should be also _injectable services_ and they will be resolved recursively. Take a look at the following example and you'll get the idea:
14+
15+
```ts
16+
const injector = new Injector()
17+
@Injectable()
18+
class Service1 {
19+
constructor(public service2: Service2, public service3: Service3) {}
20+
}
21+
@Injectable()
22+
class Service2 {
23+
public value = 'foo'
24+
}
25+
@Injectable()
26+
class Service3 {
27+
public value = 'bar'
28+
}
29+
expect(injector.getInstance(Service1).service2.value).toBe('foo')
30+
expect(injector.getInstance(Service1).service2.value).toBe('bar')
31+
```
32+
33+
All of the 3 classes are decorated as an injectable service. If you request an instance of 'Service1', the framework will also provide an instance of the two dependencies as well.
34+
35+
36+
## Injector
37+
An `Injector` is basically an _extendable container_ that instantiates services with dependencies and handles their lifecycles. The most used and most important method is the `injector.getInstance(MyServiceClass)` that returns with an instance from a requested service. Injectors are smart enough to handle lifecycles (e.g. "singleton" services will be constructed once per injector).
38+
39+
You can create multiple injectors in your project, they can act as multiple separated "global" containers.
40+
41+
You can also organize injectos in a tree structure in the following way:
42+
43+
```ts
44+
const childInjector = injector.createChild({ owner: 'myCustomContext' })
45+
```
46+
47+
Creating _child injectors_ can be useful if you want to store contextual data (e.g. a per-http-request context that should be initialized once)
48+
49+
## Lifecycles
50+
The package defines four types of lifecycle:
51+
- **Transient** injectables are not cached - if you request an instance, you will get a new one every time.
52+
- **Scoped** injectables are cached, but only on the current level. If a service has been created in a current injector, the existing instance will be returned.
53+
- **Singleton** injectables are hoisted to the root injector. If you request a singleton, the injector will check create the instance in it's highest parent - and also returns it from there, if already exists.
54+
- **Explicit** values are not really injectables - you can call `injector.setExplicitInstance(myServiceInstance)` to set up an instance manually. Just like scoped services, explicit instances will be returned from the current scope only.
55+
56+
## Extension methods
57+
A simple injector can be easily extended by 3rd party packages with extension methods, just like the FuryStack packages. These extension methods usually provides a _shortcut_ of an instance or sets up a preconfigured explicit instance of a service. You can build clean and nice fluent API-s in that way - you can get the idea from one of the [FuryStack Injector Extensions](https://github.com/furystack/furystack/blob/develop/packages/rest-service/src/injector-extensions.ts)
93.8 KB
Loading

0 commit comments

Comments
 (0)