Angular 6 Проблема внедрения зависимостей - PullRequest
0 голосов
/ 29 октября 2018

У меня есть кроссплатформенное приложение Angular, мне нужно проверить платформу, на которой работает приложение, а затем принять решение о внедрении сервисов на основе этой информации. Вот моя структура:

@NgModule({
  providers: [
    ConfigService,
     {
       provide: APP_INITIALIZER,
       useFactory: configFactory,
       deps: [ConfigService],
       multi: true
    },
    {
      provide: UserService,
      useFactory: userServiceFactory,
      deps: [
        ConfigService
      ],
      multi: true
    },

  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Фабрика Config возвращает Обещание:

export function configFactory(configService: ConfigService): () => Promise<any> {
  return (): Promise<any> => {
    return new Promise(resolve => {
       Device.getInfo().then(info => {
          configService.platform = info.platform; // it either ios or web
       });
    });
  }
}

Платформа configService.platform необходима для принятия решения о поставщике UserService, и поэтому у меня есть фабричный метод для этого:

const userServiceFactory = (configService: ConfigService): any => {
    if(configService.platform === 'ios') {
        return new UserServiceDevice()
    } else {
        return new UserWebServiceWeb();
    }
  }

Служба конфигурации инициализируется правильно, но перед завершением запуска growerServiceFactory получает неопределенное значение config.platform, поэтому она по существу не ожидает разрешения configFactory даже после установки ConfigService в качестве зависимости. Как мне этого добиться? Есть ли лучший подход для этого сценария?

1 Ответ

0 голосов
/ 29 октября 2018

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

Модифицированный UserService:

class PlatformAgnosticUserService implements IUserService {
   private service: IUserService;

   constructor(
      private _PLAT : Platform,
      private mobileUserService: MobileUserService,
      private webUserService: WebUserService
   ) {
      if (this._PLAT.is('ios') || this._PLAT.is('android'))
      {
         this.service = mobileUserService;
      }
      else
      {
         this.service = webUserService;
      }
   }

   userCreate(param: any) {
      this.service.userCreate(param);
   }

}

Я знаю, что это не так хорошо, но это лучшее, что я могу придумать, ура.

Старый ответ ниже

Я думаю, вы можете усложнять ситуацию. Почему бы не упростить это:

@NgModule({
  providers: [
    {
      provide: UserService,
      useFactory: userServiceFactory,
      deps: [],
      multi: true
    },

  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

А это:

    const growerServiceFactory = (configService: ConfigService): () => Promise<any> => {
return (): Promise<any> => {
    return new Promise(
       resolve => {
         Device.getInfo().then(info => {
            return new UserServiceDevice();
       },
       () => {
         return new UserWebServiceWeb()
       });
    });
  }

Не уверен, что вы используете службу конфигурации для чего-то еще, но, по крайней мере, в этом случае его можно «пропустить».

...