2016-05-09 4 views
6

У меня есть реальный сценарий в реальном проекте, где мне нужны 2 службы для доступа к свойствам и/или методам друг друга. Я не эксперт по углам, так это возможно?Возможно ли внедрить услугу внутри другой службы и наоборот?

Я пробовал, и он терпит неудачу. Вот моя попытка:

app.component.ts

import { Component } from '@angular/core'; 
import { FirstService } from './first.service'; 
import { SecondService } from './second.service'; 

@Component({ 
    selector: 'my-app', 
    template: '<h1>Hello world!</h1>', 
    providers: [FirstService, SecondService] 
}) 
export class AppComponent { 

    constructor(public firstService: FirstService, public secondService: SecondService) { 
    console.log(firstService.foo); 
    console.log(secondService.bar); 
    } 

} 

first.service.ts

import { Injectable } from '@angular/core'; 
import { SecondService } from './second.service'; 

@Injectable() 
export class FirstService { 

    foo: string = 'abc'; 

    constructor(public secondService: SecondService) { 
    this.foo = this.foo + this.secondService.bar; 
    } 

} 

second.service.ts

import { Injectable } from '@angular/core'; 
import { FirstService } from './first.service'; 

@Injectable() 
export class SecondService { 

    bar: string = 'xyz'; 

    constructor(public firstService: FirstService) { 
    this.bar = this.bar + this.firstService.foo; 
    } 

} 

Plunker: http://plnkr.co/edit/PQ7Uw1WHpvzPRf6yyLFd?p=preview

Просто ввод второй службы в первую услугу работает нормально, но как только я ввожу первую услугу во вторую службу, она терпит неудачу и выдает ошибки на консоль.

Итак, что не так?

Рабочий раствор должен напечатать следующее в лог консоли:

abcxyz 
xyzabc 

Заранее спасибо!

ответ

3

AngularJS не позволяет инъекции круговых зависимостей.

Miško Hevery, один из авторов AngularJS, рекомендует найти общие элементы:

+---------+  +---------+ 
| A |<-----| B  | 
|   |  | | +-+ | 
|   |  | +->|C| | 
|   |------+---->| | | 
|   |  |  +-+ | 
+---------+  +---------+ 

И извлекая его третьей службы:

      +---------+ 
+---------+    | B | 
| A |<-------------|   | 
|   |    |   | 
|   | +---+  |   | 
|   |--->| C |<----|   | 
|   | +---+  +---------+ 
+---------+ 

Для получения дополнительной информации см Circular Dependency in constructors and Dependency Injection по Miško Hevery.

3

Я не Угловая эксперт, так это возможно

No. Круговые зависимости не разрешены угловыми в DI.

Также даже системы, которые его поддерживают, довольно часто являются несогласованными, например. commonjs https://nodejs.org/docs/latest/api/modules.html#modules_cycles покажет вам пустой объект.

Решение

Рассмотрим объединение двух служб в один. Вы можете перемещать определенные вещи (например, простые функции и т. Д.) Из комбинированной службы, если это становится слишком много.

2

Я согласен с решением, предложенным basarat. Другое решение было бы инициализировать экземпляры вне DI и обеспечить их значение как

Одна услуга должна быть изменена, чтобы иметь возможность создать экземпляр без предоставления других услуг в зависимости:

@Injectable() 
export class FirstService { 

    foo: string = 'abc'; 
    secondService: SecondService 

    constructor() { 
    //this.foo = this.foo + this.secondService.bar; 
    } 

    init(secondService:SecondService) { 
    this.foo = this.foo + secondService.bar; 
    } 
} 

Затем создать экземпляры императивно и предоставить им в качестве значения

let firstService = new FirstService(); 
let secondService = new SecondService(firstService); 

@Component({ 
    selector: 'my-app', 
    template: '<h1>Hello world!</h1>', 
    providers: [ 
    provide(FirstService, {useFactory:() => { 
     firstService.init(secondService); 
     return firstService; 
    }}), provide(SecondService, {useValue: secondService})] 
}) 
... 

Plunker example

+0

есть 'круговые зависимости' существуют в угловом2? –

+2

Не уверен, что вы имеете в виду. «Круговые зависимости» работают с классами, но DI не может создавать экземпляры классов с круговыми зависимостями. –

Смежные вопросы