Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injection versus global static class with Angular 2

I'm creating a project where I need a "constants" class to contain some configuration values. Here is an extract of this class :

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';
    };
}

When I'm in a component with Angular 2, I can use that class by importing it :

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

And then, just reference it :

this.cookieName = Constants.Configuration.CookieName;

It works pretty well but I have the feeling that I should use the dependency injection engine of Angular 2 to inject a reference to that class in the constructor but it seems a bit overkill. However, I have the feeling that I'm violating the "Angular way" of doing things, so I don't know if I can stick with my solution or if I have to use DI.

Any advice ?

like image 357
ssougnez Avatar asked Dec 21 '15 21:12

ssougnez


1 Answers

What I might suggest doing instead is change your Constants classes to have read-only properties and create a Providers[] from them like so

@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})
];

Then you can bootstrap these providers into the top-level injector for your application making them available wherever you might need them.

import {CONSTANTS_PROVIDERS} from './constants';

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

Here's a plunk to demonstrate: http://plnkr.co/edit/RPjDxoIZ8wLY3DDIdhJF

Edit 2: Plunker is back now and I've updated the example

Edit: Plunkr is dead right now so I can't update it but in my comment I meant something like this (I haven't tested this but it should work):

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

Again this is more code than your suggestion of the inner classes so it's probably up to which you prefer.

like image 162
Zyzle Avatar answered Nov 16 '22 10:11

Zyzle