Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StaticInjector vs ReflectiveInjector in Angular

Angular 5.x will include new StaticInjector as mentioned in this tweet. I have two questions:

  • How is it different from existing ReflectiveInjector?
  • Will it break any of my existing code?
like image 596
Max Koretskyi Avatar asked Aug 09 '17 08:08

Max Koretskyi


People also ask

What is ReflectiveInjector?

Relies on reflection capabilities provided by Reflect library to extract the implicit dependencies for a provider, hence the name Reflective : class B {} class A { constructor(@Inject(B) b) { } <----- `B` is implicit dependency } const i = ReflectiveInjector.

What is static provider?

A static provider provides tokens to an injector for various types of dependencies. type StaticProvider = ValueProvider | ExistingProvider | StaticClassProvider | ConstructorProvider | FactoryProvider | any[];

What is angular injector?

Injectors are data structures that store instructions detailing where and how services form. They act as intermediaries within the Angular DI system. Module, directive, and component classes contain metadata specific to injectors. A new injector instance accompanies every one of these classes.


1 Answers

First, there's a great article Angular introduces StaticInjector. Should you care? that explains the difference in details.

How is it different from existing ReflectiveInjector?

ReflectiveInjector

Relies on reflection capabilities provided by Reflect library to extract the implicit dependencies for a provider, hence the name Reflective:

class B {}
class A {
  constructor(@Inject(B) b) { } <----- `B` is implicit dependency
}

const i = ReflectiveInjector.resolveAndCreate([A, B]);

The @Inject decorator defines the metadata specifying implicit dependencies and ReflectiveInjector uses this metadata.

StaticInjector

Doesn't use reflective capabilities and requires to specify the dependencies explicitly:

class B {}
class A { constructor(b) {} }
const i = Injector.create([{provide: A, useClass: A, deps: [B]]};
const a = i.get(A);

Will it break any of my existing code? The change will only affect providers supplied to platform and compiler providers. So if you provided them like this:

class B1 {}
class A1 { constructor(@Inject(B1) b) {} }

class B2 {}
class A2 { constructor(@Inject(B2) b) {} }
bootstrapModule(AppModule, {providers: [A1, B1]}).platformBrowserDynamic([A2, B2])

You should now change that to:

class B1 {}
class A1 { constructor(b) {} }

class B2 {}
class A2 { constructor(b) {} }

platformBrowserDynamic([{ provide: A1, useClass: A1, deps: [B1] }, B1])
.bootstrapModule(AppModule, { providers: [ {provide: A2, useClass: A2, deps: [B2]}, B2 ] })

The ReflectiveInjector is still marked as stable so you can probably continue using it. But there's a great probability that it will be removed in the future. I suggest you start using StaticInjector as soon as it's available.

like image 102
Max Koretskyi Avatar answered Oct 24 '22 20:10

Max Koretskyi