单例动态提供程序 - Angular 7

Dynamic provider for singleton - Angular 7

我有一个 angular 应用程序,它可以显示视频或文章列表以及视频的详细信息或文章的详细信息。

我得到了 ContentListPage 和 ContentDetailsPage,它们对于视频或文章是一样的。

唯一的区别在于服务层,它基本上从 youtube 或 worpress 获取数据。

我只想根据当前内容类型动态提供一项通用服务。 我能够拥有动态提供者,但因为我使用的是工厂提供者,所以每次创建组件时都会创建一个新的服务实例。

我的主要尝试是基于factory provider

所以我定义了useFactory应该提供什么样的服务。 这运行良好,但是当我从 ContentListPage 导航到 ContentDetailsPage 时,会创建一个新的服务实例。

我知道这是因为我提供服务的方式

@Component({
  . . .
  providers: [contentServiceProvider]
})

但我找不到如何在没有后遗症的情况下提供另一个级别。

content.service.provider.ts

const contentServiceFactory = (http: HttpService, metaMediaService: MetaMediaService) => {

  let contentService;
  if (metaMediaService.currentMetaMedia.type === MetaMediaType.WORDPRESS) {
    contentService = new MediasService(http, metaMediaService);
  } else {
    contentService = new YoutubeService(http, metaMediaService);
  }
  return contentService;
};

export let contentServiceProvider = {
  provide: ContentService,
  useFactory: contentServiceFactory,
  deps: [HttpService, MetaMediaService]
};

@Component({
  . . .
  providers: [contentServiceProvider]
})
export class ContentListPage implements OnInit {

  constructor(public mediasService: ContentService<IContent>) {

内容-details.page.ts

@Component({
  . . .
  providers: [contentServiceProvider]
})
export class ContentDetailsPage implements OnInit {

  constructor(public contentService: ContentService<IContent>) { }

content.service.ts

@Injectable({
  providedIn: 'root'
})
export abstract class ContentService<T extends IContent> {
  abstract getContentById(id: number): Observable<T>;
  abstract  getContents(): Observable<T[]>;
  abstract loadMore(): Observable<T[]>;
}

向朋友请教了一些建议,我们得出使用注射器的结论:

const contentServiceFactory = (metaMediaService: MetaMediaService, injector: Injector) => {
  if (metaMediaService.currentMetaMedia.type === MetaMediaType.WORDPRESS) {
    return injector.get(MediasService);
  } else {
    return injector.get(YoutubeService);
  }
};

export let contentServiceProvider = {
  provide: ContentService,
  useFactory: contentServiceFactory,
  deps: [MetaMediaService, Injector]
};