两个服务如何以双向方式相互通信?

时间:2022-02-09 12:47:58

In one way by events, in other by calling methods. I trying to realize aggregate pattern in my app.

以某种方式通过事件,在其他方面通过调用方法。我试图在我的应用程序中实现聚合模式。

I have AuthService, here i handle auth results and emit the event.

我有AuthService,这里我处理auth结果并发出事件。

if (auth) { this.eAuth.emit(true) } else { this.eAuth.emit(false) }

I can subscribe in AuthComponent

我可以订阅AuthComponent

_authService.eAuth.subscribe( (isAuth) => this.handleAuthResult(isAuth) )

And it works perfect. But AggregateService also need to know about this and broadcast this information to UserService, LoadDataService and so on.

它完美无缺。但是AggregateService还需要了解这一点并将此信息广播到UserService,LoadDataService等。

How to do it?

怎么做?

upd: my AggregateService doesn't have component and I already inject AuthService into it.

upd:我的AggregateService没有组件,我已经将AuthService注入其中。

1 个解决方案

#1


4  

If ServiceA is injected into ServiceB, ServiceB can call methods on ServiceA (hence ServiceB → ServiceA communication) and it can subscribe() to any Obervable that ServiceA might expose (hence ServiceA → to ServiceB communication).

如果将ServiceA注入ServiceB,ServiceB可以调用ServiceA上的方法(因此ServiceB→ServiceA通信),它可以订阅()ServiceA可能暴露的任何Obervable(因此ServiceA→ServiceB通信)。

What's missing is ServiceA's ability to directly call methods on ServiceB. This is often not recommended, as it creates coupling between the services. ServiceA should emit events using next() on the Observable that ServiceB can subscribe() to, then ServiceB can call the appropriate method(s) on itself.

缺少的是ServiceA能够直接调用ServiceB上的方法。通常不建议这样做,因为它会在服务之间创建耦合。 ServiceA应该使用ServiceB可以订阅()的Observable上的next()发出事件,然后ServiceB可以自己调用适当的方法。

However, if you really need this to work, here is one way to do it: have ServiceB call some kind of registerService(this) method on ServiceA. The type of the argument should be an interface rather than a concrete type, to limit coupling. Then ServiceA will have a reference to ServiceB and it can call methods on it.

但是,如果你真的需要这个工作,这里有一种方法:让ServiceB在ServiceA上调用某种registerService(this)方法。参数的类型应该是接口而不是具体类型,以限制耦合。然后,ServiceA将引用ServiceB,并且可以在其上调用方法。

interface SomeInterface {
  public methodOne();
  public methodTwo();
}

import {SomeInterface} from './some-interface';
export class ServiceA {
    registerService(someService:SomeInterface) {
       someService.methodOne(this);
       // you'll probably want to store someService in this object
    }
}

ServiceB should implement that interface -- i.e., implement the set of methods that ServiceA can call.

ServiceB应该实现该接口 - 即,实现ServiceA可以调用的方法集。

import {SomeInterface} from './some-interface';
export class ServiceB implements SomeInterface {
    constructor(private _serviceA: ServiceA) {
       _serviceA.registerService(this);
    }
    methodOne(who) {
       console.log('hello from ServiceB.methodOne(), called by', who);
    }        
    methodTwo() { ... }
}

Plunker

Plunker

#1


4  

If ServiceA is injected into ServiceB, ServiceB can call methods on ServiceA (hence ServiceB → ServiceA communication) and it can subscribe() to any Obervable that ServiceA might expose (hence ServiceA → to ServiceB communication).

如果将ServiceA注入ServiceB,ServiceB可以调用ServiceA上的方法(因此ServiceB→ServiceA通信),它可以订阅()ServiceA可能暴露的任何Obervable(因此ServiceA→ServiceB通信)。

What's missing is ServiceA's ability to directly call methods on ServiceB. This is often not recommended, as it creates coupling between the services. ServiceA should emit events using next() on the Observable that ServiceB can subscribe() to, then ServiceB can call the appropriate method(s) on itself.

缺少的是ServiceA能够直接调用ServiceB上的方法。通常不建议这样做,因为它会在服务之间创建耦合。 ServiceA应该使用ServiceB可以订阅()的Observable上的next()发出事件,然后ServiceB可以自己调用适当的方法。

However, if you really need this to work, here is one way to do it: have ServiceB call some kind of registerService(this) method on ServiceA. The type of the argument should be an interface rather than a concrete type, to limit coupling. Then ServiceA will have a reference to ServiceB and it can call methods on it.

但是,如果你真的需要这个工作,这里有一种方法:让ServiceB在ServiceA上调用某种registerService(this)方法。参数的类型应该是接口而不是具体类型,以限制耦合。然后,ServiceA将引用ServiceB,并且可以在其上调用方法。

interface SomeInterface {
  public methodOne();
  public methodTwo();
}

import {SomeInterface} from './some-interface';
export class ServiceA {
    registerService(someService:SomeInterface) {
       someService.methodOne(this);
       // you'll probably want to store someService in this object
    }
}

ServiceB should implement that interface -- i.e., implement the set of methods that ServiceA can call.

ServiceB应该实现该接口 - 即,实现ServiceA可以调用的方法集。

import {SomeInterface} from './some-interface';
export class ServiceB implements SomeInterface {
    constructor(private _serviceA: ServiceA) {
       _serviceA.registerService(this);
    }
    methodOne(who) {
       console.log('hello from ServiceB.methodOne(), called by', who);
    }        
    methodTwo() { ... }
}

Plunker

Plunker