demystifying dependency injection: angular vs nest · injection: angular vs nest. kammysliwiec...
TRANSCRIPT
KAMMYSLIWIEC
DEMYSTIFYING DEPENDENCY INJECTION: ANGULAR VS NEST
KAMMYSLIWIEC
KAMIL MYSLIWIEC CREATOR OF NESTJS | CO-FOUNDER OF TRILON.IO
GOOGLE DEVELOPER EXPERT @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