2017-02-11 10 views
3

Мне нужно, чтобы некоторые угловые службы настраивались динамически, в зависимости от коммутатора времени выполнения. В дни перед АОТ, я получил его на работу, используя следующий код:Конфигурация динамического модуля/обслуживания и AOT

@NgModule({ 
    imports: [HttpModule], 
    providers: [] 
}) 
export class MyModule { 
    static forRoot(config: MyConfiguration): ModuleWithProviders { 
    return { 
     ngModule: MyModule, 
     providers: [ 
     SomeService, 
     { 
      provide: SomeOtherService, 
      useFactory: (some: SomeService, http: Http) => { 
      switch (config.type) { 
       case 'cloud': 
       return new SomeOtherService(new SomethingSpecificForCloud()); 
       case 'server': 
       return new SomeOtherService(new SomethingSpecificForServer()); 
      } 
      }, 
      deps: [SomeService, Http] 
     }, 

     ] 
    }; 
    } 
} 

Тогда в моем AppModule я бы импортировать это как MyModule.forRoot(myConfig).

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

Я злоупотреблял этим методом forRoot() в первую очередь? Как вы пишете модули, чтобы в зависимости от переключателя времени выполнения они создавали разные службы?

ответ

3

Я нашел один из способов его достижения: выставлять конфигурацию через поставщика, а затем вводить «статическую» заводскую функцию. Приведенный выше код будет выглядеть следующим образом:

// Necessary if MyConfiguration is an interface 
export const MY_CONFIG = new OpaqueToken('my.config'); 

// Static factory function 
export function someOtherServiceFactory(config: MyConfiguration,some: SomeService, http: Http) { 
    switch (config.type) { 
    case 'cloud': 
     return new SomeOtherService(new SomethingSpecificForCloud()); 
    case 'server': 
     return new SomeOtherService(new SomethingSpecificForServer()); 
    } 
} 

@NgModule({ 
    imports: [HttpModule], 
    providers: [] 
}) 
export class MyModule { 
    static forRoot(config: MyConfiguration): ModuleWithProviders { 
    return { 
     ngModule: MyModule, 
     providers: [ 
     SomeService, 
     { provide: MY_CONFIG, useValue: config }, 
     { 
      provide: SomeOtherService, 
      useFactory: someOtherServiceFactory, 
      deps: [MY_CONFIG, SomeService, Http] 
     }, 

     ] 
    }; 
    } 
} 

Он работает и все, но я все еще был бы очень интересно узнать, является ли это на самом деле хорошая идея, или, если я делаю что-то ужасно неправильно, и следует принимать совершенно иной подход к решению этой проблемы.


Я нашел другое решение:

  1. Использование Угловая CLI сред.
  2. Создайте абстрактные классы/интерфейсы для служб с различными реализациями или зависимостями для разных сред.
  3. Экспортируйте правильный тип из каждого файла enviromnent (кто сказал, что он должен быть только простым JS-объектом?).
  4. В определении поставщика модуля импортируйте из среды.
  5. Во время компиляции среды CLI будут правильно связаны.

Дополнительная информация и образец проекта: my blog.

+0

Я думаю, что это единственный вариант. 1 замечание: из v4 вы должны использовать 'InjectionToken' вместо' OpaqueToken'. – mat3e

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

  • Нет связанных вопросов^_^