injector create angular dependency-injection angular-di

create - injector get angular 5



¿Puedo usar estrategias personalizadas de ReflectiveInjector para obtener proveedores de componentes? (1)

Como todos ustedes saben, tenemos diferentes estrategias para proveedores: useClass , useExisting , useFactory , useValue . Pero, ¿y si quisiera agregar mi propia estrategia? Algo como:

providers: [ { MyService: MyService, useAsyncFactory: MyAsyncFactory} ]

¿Cuál es la mejor manera de extender ReflectiveInjector y hacer que Angular use su variante extendida? Encontré el lugar donde está definido, pero sigo buscando una forma de sobrescribir el mecanismo de DI angular existente.

PD: No preguntes por qué lo necesito y por qué no utilizar las estrategias existentes. Estoy investigando sobre DI angular y la respuesta me ayudará a entenderlo mejor.


Bajo el capó, Angular no usa ReflectiveInjector para recuperar proveedores de componentes, por lo que incluso si logra extender el ReflectiveInjector, no tendrá ningún efecto sobre los proveedores de los componentes. Puedes verlo aquí :

function resolveDep(...) { ... default: const providerDef = (allowPrivateServices ? elDef.element !.allProviders : elDef.element !.publicProviders) ![tokenKey]; if (providerDef) { const providerData = asProviderData(view, providerDef.index); ^^^^^^^^^^^^^^^ if (providerData.instance === NOT_CREATED) { providerData.instance = _createProviderInstance(view, providerDef); } return providerData.instance; }

El método se llama cuando el componente solicita una dependencia, por ejemplo ViewContainerRef :

class MyComponent { constructor(vc: ViewContainerRef)

Y esta línea:

const providerData = asProviderData(view, providerDef.index);

muestra que la dependencia se recupera del nodo de vista, no de un inyector reflectivo. Entonces cuando te gusta esto:

constructor(i: Injector) { console.log(i instanceOf ReflectiveInjector); // false }

Verás que no es real. Es solo una envoltura alrededor de la función resolveDep que encierra la vista y el nodo de vista relevante.

El inyector reflectante todavía se usa para los inyectores de la vista de host. Este es el inyector que pasa cuando crea una instancia de un componente de forma dinámica:

componentFactory.create(hostViewInjector)

Aquí está el código relevante:

const value = startView.root.injector.get(depDef.token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);

Y también se consulta el inyector del módulo si la dependencia no se puede resolver en el componente o en el inyector de la vista de host.
Aquí está el código relevante:

return startView.root.ngModule.injector.get(depDef.token, notFoundValue);