angular angular2-services

angular - Usar mĂșltiples instancias del mismo servicio



angular2-services (3)

Angular DI mantiene una única instancia por proveedor. En su caso, si tiene dos parámetros de constructor con el mismo tipo, se resuelven en la misma instancia.

Lo que puede hacer es proporcionar una función de fábrica (diferente de un simple evento de proveedor useFactory , aunque también lo usa)

(Ejemplo copiado de https://stackoverflow.com/a/37517575/217408 )

{ provide: EditorService, useFactory: (dep1, dep2) => { return (x) => { new EditorService(x, dep1, dep2); } }, deps: [Dep1, Dep2] }) .... constructor(@Inject(EditorService) editorServiceFactory: any) { let editorService1 = editorServiceFactory(1); let editorService2 = editorServiceFactory(2); }

Si tiene un número fijo de instancias, esto debería funcionar:

{ provide: ''instance1'', useClass: EditorService }, { provide: ''instance2'', useClass: EditorService },

export class SomeComponent { constructor( @Inject(''instance1'') private _appleEditorService: EditorService, @Inject(''instance2'') private _pearEditorService: EditorService) {} }

Tengo un servicio como este:

@Injectable() export class EditorService { ... }

Y tengo un componente, como este:

@Component({ ... template: `<child-component></child-component>`, providers: [EditorService], ... }) export class SomeComponent { constructor( private _appleEditorService: EditorService, private _pearEditorService: EditorService) {} }

Como habrás notado, este componente tiene un componente hijo:

@Component({ ... selector: ''child-component'', ... }) export class ChildComponent { constructor( private _appleEditorService: EditorService, private _pearEditorService: EditorService) {} }

Como puede ver, quiero dos instancias de mi EditorService : una se usará para editar manzanas y otra para editar peras. Sin embargo, el código anterior no funcionará, ya que Angular no tiene forma de saber qué instancia de EditorService es cuál, ya que sus nombres de variables son privados. _pearEditorService en ChildComponent podría estar refiriéndose a la misma instancia que _appleEditorService en SomeComponent .

Pregunta: ¿De qué otra manera, puedo usar el mismo servicio Angular2 dos veces?

EDITAR: El punto de mi pregunta es si es posible usar la misma clase. Sé que existen soluciones al crear una clase separada para cada instancia del servicio, e incluso hacerlo con poco código por herencia. Solo quiero saber si se puede hacer sin él.


No es lo ideal, pero si crea un módulo para cada componente y luego importa su servicio en cada módulo, tendrá 2 instancias del mismo servicio (una para cada módulo).


quizás repensar su diseño

Creo que entonces deberías repensar tu diseño por completo. ¿Cuál es el punto de tener dos variables que apuntan exactamente al mismo EditorService? Si comparten la misma implementación.

Solución de herencia

Una solución a esto quizás sería utilizar la herencia . No he visto sus servicios, así que no estoy seguro de lo que hacen, pero a partir de este código, supongo que la funcionalidad "manzana" y la funcionalidad "pera" son realmente diferentes. Entonces esto indica que puede tener algunos problemas de diseño, y su EditorService podría estar haciendo demasiado. Quizás podría mover el código que es similar tanto para las manzanas como para las peras a un servicio llamado EditorService y luego hacer que dos clases extiendan esto. un AppleEditorService y un PearEditorService .

Utilice el servicio general de frutas

Solo para hablar un poco más sobre por qué creo que podría necesitar repensar su diseño. Supongamos que las apelaciones y las peras realmente tienen la misma funcionalidad. Entonces el EditorService hace lo mismo. Desea que se use una variable para ''Manzanas'' y otra para ''Peras''. Si veo ese código (supongo que otras personas trabajan en su equipo), y noto que ambas variables apuntan al mismo servicio. (Los servicios son únicos), estaría tentado a eliminar eso y hacer algo como fruitService : EditorService o algo similar.

De cualquier manera, su pregunta me hace pensar que el diseño debería cambiarse. No desea dos instancias del servicio, los servicios son únicos y, aunque podría encontrar formas de evitarlo, no creo que esa sea realmente la solución a su problema.

Pero como he mencionado antes. Piensa en tu diseño. ¿Realmente necesita dos servicios para niños, o puede resolverlo de manera diferente? ¿Puedes comer manzanas y peras solo subclase de frutas? ¿Puedes usar una variable ''fruitService'' en lugar de ambas manzanas / peras? ¿Qué sucede cuando quieres almacenar "Fresas" también en el futuro? Tener un montón de variables se refiere al mismo servicio (porque hacen lo mismo) pero con diferentes nombres de variables no es una buena idea. Imagina ver esto en código

appleService = EditorService; pearService = EditorService; starwberryService = EditorService; lemonService = EditorService; ... guavaService = EditorService;

¿Esto no indicaría que algo es extraño con el código? Me imagino (no proporcionó el código en este momento) que almacene una matriz de fruitInstances. Pero tal vez un fruitService podría funcionar y luego almacenar fruitService.store (Apple a) y ponerlo en una variedad de ''fruit''. Usar un ''filtro'' para obtener la fruta correcta de la matriz no debería ser demasiado difícil.

^ Esto se acaba de escribir sin tener más de su código para continuar. Si edita su pregunta, algunas cosas podrían no aguantar más.