Инъекция против глобального статического класса с Angular 2

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

export class Constants
{
    static Configuration = class
    {
        static CookieName:string = 'etl_language';
    };

    ...

    static View = class
    {
        static Militaries:string = 'militaries';
        static Mutants:string = 'mutants';
        static Objects:string = 'objects';
        static Scientists:string = 'scientists';
    };
}

Когда я нахожусь в компоненте с Angular 2, я могу использовать этот класс, импортировав его:

import {Constants} from "../../misc/constants";

И тогда просто укажите его:

this.cookieName = Constants.Configuration.CookieName;

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

Любые советы?

Ответ 1

Вместо этого я могу предложить вместо этого изменить ваши классы Constants, чтобы иметь свойства только для чтения и создать из них Providers[] так

@Injectable()
public class ConfigurationConstants() {
  private _cookieName:string = 'etl_language';
  ...
  get cookieName():string {
    return this._cookieName;
  }
  ...
}

export var CONSTANTS_PROVIDERS:Provider[] = [
  provide(ConfigurationConstants, {useClass: ConfigurationConstants}),
  provide(ViewConstants, {useClass: ViewConstatns})
];

Затем вы можете загрузить эти поставщики в инжектор верхнего уровня для вашего приложения, сделав их доступными там, где они вам могут понадобиться.

import {CONSTANTS_PROVIDERS} from './constants';

bootstrap(App, [CONSTANTS_PROVIDERS])
  .catch(err => console.error(err));

Здесь представлен фрагмент, демонстрирующий: http://plnkr.co/edit/RPjDxoIZ8wLY3DDIdhJF

Изменить 2: Теперь Plunker вернулся, и я обновил пример

Изменить: Plunkr уже мертв, поэтому я не могу его обновить, но в своем комментарии я имел в виду нечто подобное (я не тестировал это, но он должен работать):

public class SubConstants() {
  private _someString:string = 'Some String';
  ...
  get someString():string {
    return this._someString;
  }
  ...
}

@Injectable()
public class ConfigurationConstants() {
  private _cookieName:string = 'etl_language';
  private _subConstants:SubConstants = new SubConstants();
  ...
  get cookieName():string {
    return this._cookieName;
  }

  get subConstants():SubConstants {
    return this._subConstants;
  }
  ...
}

// ... this would allow you to then do:
confConstants.subConstants.someString
// assuming you injected ConfigurationConstants as confConstants

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

Ответ 2

DI является необязательным, но он хорош для случаев, когда вы хотите работать с экземпляром объекта. Импорт во многих случаях одобрен, но DI отделяет ваш код от экземпляра экземпляра. Это полезно, если вы выполняете автоматическое тестирование или хотите, чтобы ваш компонент был гибким и принимал любой объект с заданной подписью.

У меня есть дополнительная информация о DI здесь, если вы заинтересованы: http://www.syntaxsuccess.com/viewarticle/dependency-injection-in-angular-2.0

Ответ 3

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

Использование DI там, где это не требуется, или, что еще хуже, системное использование DI во всем приложении, чтобы удовлетворить некоторую чрезмерную структуру, приведет к непонятному коду. (Возможно, это относится к любому шаблону проектирования).

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