demystifying dependency injection: angular vs nest · injection: angular vs nest. kammysliwiec...

Post on 11-Mar-2020

10 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

KAMMYSLIWIEC

DEMYSTIFYING DEPENDENCY INJECTION: ANGULAR VS NEST

KAMMYSLIWIEC

KAMIL MYSLIWIEC CREATOR OF NESTJS | CO-FOUNDER OF TRILON.IO

GOOGLE DEVELOPER EXPERT @KAMMYSLIWIEC

KAMIL MYŚLIWIEC SOFTWARE ENGINEER

@KAMMYSLIWIEC

KAMMYSLIWIEC

Adonis Express Koa Nest Fastify

NESTJS WWW.NESTJS.COM

@NESTFRAMEWORK

KAMMYSLIWIEC

DEPENDENCY INJECTION

KAMMYSLIWIEC

@Injectable()

class CatsService {

private httpService = new HttpService();

private logger = new Logger();

}

KAMMYSLIWIEC

@Injectable()

class CatsService {

private httpService = new HttpService();

private logger = new Logger();

}

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

@Injectable()

class CatsService {

private httpService = new HttpService();

private logger = new Logger();

}

KAMMYSLIWIEC

const Injectable: ClassDecorator = (target: Object) => {};

KAMMYSLIWIEC

COMPILER METADATA

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

CatsService = __decorate(

[__metadata('design:paramtypes', [HttpService, Logger])],

CatsService,

);

KAMMYSLIWIEC

CatsService = __decorate(

[__metadata('design:paramtypes', [HttpService, Logger])],

CatsService,

);

KAMMYSLIWIEC

CatsService = __decorate(

[__metadata('design:paramtypes', [HttpService, Logger])],

CatsService,

);

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

REFLECTION API

KAMMYSLIWIEC

Reflect.getMetadata('design:paramtypes', CatsService);

KAMMYSLIWIEC

Reflect.getMetadata('design:paramtypes', CatsService);

KAMMYSLIWIEC

Reflect.getMetadata('design:paramtypes', CatsService);

KAMMYSLIWIEC

const metadata = Reflect.getMetadata(

‘design:paramtypes',

CatsService,

);

// metadata = [HttpService, Logger]

KAMMYSLIWIEC

ENQUIRER INJECTOR

CONTAINERKEY

VALUE

KAMMYSLIWIEC

BEHIND FRAMEWORKS

KAMMYSLIWIEC

CatsService = __decorate(

[__metadata('design:paramtypes', [HttpService, Logger])],

CatsService,

);

KAMMYSLIWIEC

CatsService = tslib_1.__decorate(

[tslib_1.__metadata(

'design:paramtypes',

[HttpService, Logger],

)],

CatsService,

);

KAMMYSLIWIEC

i1.ɵdid(

1,

4308992,

null,

0,

i13.HomepageComponent,

[i1.ChangeDetectorRef, i7.Router],

null,

null,

);

KAMMYSLIWIEC

i1.ɵdid(

1,

4308992,

null,

0,

i13.HomepageComponent,

[i1.ChangeDetectorRef, i7.Router],

null,

null,

);

KAMMYSLIWIEC

factory: function AppComponent_Factory(t) {

return new (t || AppComponent)(

ɵɵdirectiveInject(ChangeDetectorRef),

ɵɵdirectiveInject(Router),

);

}

KAMMYSLIWIEC

factory: function AppComponent_Factory(t) {

return new (t || AppComponent)(

ɵɵdirectiveInject(ChangeDetectorRef),

ɵɵdirectiveInject(Router),

);

}

KAMMYSLIWIEC

REFLECTION API CHALLENGES

KAMMYSLIWIEC

INTERFACES

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: IHttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

const metadata = Reflect.getMetadata(

‘design:paramtypes',

CatsService,

);

// metadata = [Object, Logger]

// IHttpService === Object

KAMMYSLIWIEC

POTENTIAL SOLUTION

KAMMYSLIWIEC

GENERICS

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private httpService: HttpService,

private catsRepository: Repository<Cat>,

) {}

}

KAMMYSLIWIEC

const metadata = Reflect.getMetadata(

‘design:paramtypes',

CatsService,

);

// metadata = [HttpService, Repository]

// what about Cat class?

KAMMYSLIWIEC

POTENTIAL SOLUTION

KAMMYSLIWIEC

CIRCULARDEPENDENCIES

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

private dogsService: DogsService,

) {}

}

KAMMYSLIWIEC

@Injectable()

class DogsService {

constructor(

private catsService: CatsService,

) {}

}

KAMMYSLIWIEC

const metadata = Reflect.getMetadata(

‘design:paramtypes',

CatsService,

);

// metadata = [undefined]

// DogsService === undefined

KAMMYSLIWIEC

POTENTIAL SOLUTION

KAMMYSLIWIEC

@Injectable()

class CatsService {

constructor(

@Inject(forwardRef(() => DogsService))

private dogsService: DogsService,

) {}

}

KAMMYSLIWIEC

function forwardRef(forwardRefFn: ForwardRefFn): Type<any> {

(<any>forwardRefFn).__forward_ref__ = forwardRef;

...

}

KAMMYSLIWIEC

function forwardRef(forwardRefFn: ForwardRefFn): Type<any> {

(<any>forwardRefFn).__forward_ref__ = forwardRef;

...

}

KAMMYSLIWIEC

INJECTOR TREES

KAMMYSLIWIEC

ROOTA B C

COMPONENT A

COMPONENT B

COMPONENT C

@Component({})

export class CmpC {

constructor(private c: C) {}

}

KAMMYSLIWIEC

ROOTA B C

COMPONENT A

COMPONENT B

COMPONENT C

@Component({})

export class CmpC {

constructor(private c: C) {}

}

KAMMYSLIWIEC

ROOTA B C

COMPONENT A

COMPONENT B

COMPONENT C

@Component({})

export class CmpC {

constructor(private c: C) {}

}

KAMMYSLIWIEC

ROOTA B C

COMPONENT A

COMPONENT B

COMPONENT C

@Component({})

export class CmpC {

constructor(private c: C) {}

}

INJECTORSIN NEST

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

KAMMYSLIWIEC

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

KAMMYSLIWIEC

GLOBALSCOPE

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

KAMMYSLIWIEC

CORE

USERS

SHARED

APPLICATION

AUTH BLOG

WHAT’S NEW

KAMMYSLIWIEC

SCOPES

KAMMYSLIWIEC

REQUEST

PROVIDER

REQUEST REQUEST

KAMMYSLIWIEC

REQUEST

PROVIDER

REQUEST REQUEST

PROVIDER PROVIDER

KAMMYSLIWIEC

@Injectable({ scope: Scope.REQUEST })

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

@Injectable({ scope: Scope.REQUEST })

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

PROVIDER C

PROVIDER A

PROVIDER B PROVIDER D

PROVIDER A PROVIDER A

KAMMYSLIWIEC

@Injectable({ scope: Scope.TRANSIENT })

class CatsService {

constructor(

private httpService: HttpService,

private logger: Logger,

) {}

}

KAMMYSLIWIEC

OPEN SOURCE

KAMMYSLIWIEC

KAMMYSLIWIECKAMMYSLIWIEC

WWW.TRILON.IO

KAMMYSLIWIECKAMMYSLIWIEC

THANKYOU

@KAMMYSLIWIEC

top related