diff --git a/cms/articles/1474380939/_article-1474380939.component.js b/cms/articles/1474380939/_article-1474380939.component.js
new file mode 100644
index 0000000..ae337b7
--- /dev/null
+++ b/cms/articles/1474380939/_article-1474380939.component.js
@@ -0,0 +1,448 @@
+import { Component } from '@angular/core';
+import { DomSanitizer } from '@angular/platform-browser';
+import highlight from 'highlight.js';
+
+import { xblogTableContentService } from 'xblog-cores/modules';
+import { resourceUtils } from 'xblog-cores/utils';
+
+
+export var article1474380939Component = Component({
+ selector: 'article',
+ templateUrl: './templates/article-1474380939.html',
+ host: {
+ '[class.xblog-article-1474380939]': 'true'
+ }
+})
+.Class({
+ constructor: [
+ DomSanitizer,
+ xblogTableContentService,
+
+ function (sanitizer, tableContentService){
+ this.id = 1474380939;
+ this.sanitizer = sanitizer;
+ this.tableContentService = tableContentService;
+ }
+ ],
+
+ ngOnInit: function() {
+ this.tableContents = this.tableContentService
+ .getBuilder()
+ .addHeadings([
+ { id: 'injector-providers', name: 'Injector providers' },
+ { id: 'class-provider', name: 'Class provider' },
+ { id: 'value-provider', name: 'Value provider' },
+ { id: 'factory-provider', name: 'Factory provider' },
+ { id: 'optional-dependencies', name: 'Optional dependencies' },
+ { id: 'dependency-visibility', name: 'Dependency visibility' },
+ { id: 'restricting-dependency-lookup', name: 'Restricting dependency lookup' },
+ ])
+ .build();
+
+ this.simpleDI = {
+ sourceCode: {
+ name: 'Simple DI',
+ link: resourceUtils.getGithubArticleFileLink(this.id, 'simple-di')
+ },
+ codeBlocks: {
+ 1: this.getCodeBlock(getSimpleDI)
+ },
+ screenCaptures: {
+ 1: resourceUtils.getImg('simpleDI-example-1474380939.png')
+ }
+ };
+
+ this.classProvider = {
+ sourceCode: {
+ name: 'Class provider',
+ link: resourceUtils.getGithubArticleFileLink(this.id, 'class-provider')
+ },
+ codeBlocks: {
+ 1: this.getCodeBlock(getClassProvider01),
+ 2: this.getCodeBlock(getClassProvider02),
+ 3: this.getCodeBlock(getClassProvider03)
+ },
+ screenCaptures: {
+ 1: resourceUtils.getImg('classProvider-example-1474380939.png')
+ }
+ };
+
+ this.valueProvider = {
+ sourceCode: {
+ name: 'Value provider',
+ link: resourceUtils.getGithubArticleFileLink(this.id, 'value-provider')
+ },
+ codeBlocks: {
+ 1: this.getCodeBlock(getValueProvider01),
+ 2: this.getCodeBlock(getValueProvider02)
+ }
+ };
+
+ this.factoryProvider = {
+ sourceCode: {
+ name: 'Factory provider',
+ link: resourceUtils.getGithubArticleFileLink(this.id, 'factory-provider')
+ },
+ codeBlocks: {
+ 1: this.getCodeBlock(getFactoryProvider)
+ }
+ };
+
+ this.optionalDependency = {
+ sourceCode: {
+ name: 'Optional dependency',
+ link: resourceUtils.getGithubArticleFileLink(this.id, 'optional-dependency')
+ },
+ codeBlocks: {
+ 1: this.getCodeBlock(getOptionalDependency)
+ }
+ };
+
+ this.hostDependency = {
+ sourceCode: {
+ name: 'Host dependency',
+ link: resourceUtils.getGithubArticleFileLink(this.id, 'host-dependency')
+ },
+ codeBlocks: {
+ 1: this.getCodeBlock(getHostDependency)
+ }
+ };
+
+ this.dependencyVisibility = {
+ sourceCode: {
+ name: 'Dependency visibility',
+ link: resourceUtils.getGithubArticleFileLink(this.id, 'dependency-visibility')
+ },
+ codeBlocks: {
+ 1: this.getCodeBlock(getDependencyVisibility)
+ },
+ screenCaptures: {
+ 1: resourceUtils.getImg('dependencyVisibility-example-1474380939.png')
+ }
+ };
+ },
+
+ getCodeBlock: function(getter, lang) {
+ var _langs = lang ? [ lang ] : ['javascript', 'html', 'css'];
+
+ var _codeBlock = highlight.highlightAuto(getter().replace('\n', '').replace(/^ /gm, ''), _langs).value;
+
+ return this.sanitizer.bypassSecurityTrustHtml(_codeBlock);
+ }
+});
+
+function getSimpleDI(){
+ return `
+ import * as ngCore from '@angular/core';
+
+ export var logService = ngCore.Class({
+ constructor: function(){
+ this.name = 'logService';
+ },
+
+ setName: function(name){
+ this.name = name;
+ }
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todoItemComponent = ngCore.Component({
+ .....
+ providers: [ logService ]
+ })
+ .Class({
+ constructor: [logService, function(logService){
+ console.log('todoItemComponent', logService.name);
+ }]
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todoListComponent = ngCore.Component({
+ .....
+ directives: [ todoItemComponent ]
+ })
+ .Class({
+ constructor: [logService, function(logService){
+ console.log('todoListComponent', logService.name);
+ }]
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todosComponent = ngCore.Component({
+ .....
+ providers: [ logService ],
+ directives: [ todoListComponent, todoItemComponent ]
+ })
+ .Class({
+ constructor: [logService, function(logService){
+ logService.setName('logService is hosted by todosComponent');
+ }]
+ });`;
+}
+
+function getClassProvider01(){
+ return `
+ ngCore.Component({
+ .....
+ providers: [{ provide: logSerivce, useClass: logSerivce }]
+ })
+ .Class(.....);`;
+}
+
+function getClassProvider02(){
+ return `
+ export var todoListComponent = ngCore.Component({
+ .....
+ providers: [
+ { provide: logService, useClass: supperLogService }
+ ]
+ })
+ .Class(.....);`;
+}
+
+function getClassProvider03(){
+ return `
+ import * as ngCore from '@angular/core';
+
+ export var rootLogService = ngCore.Class({
+ constructor: function(){}
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var supperLogService = ngCore.Class({
+ constructor: function(){
+ this.name = 'supperLogService';
+ }
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todoItemComponent = ngCore.Component({
+ .....
+ })
+ .Class({
+ constructor: [rootLogService, function(logService){
+ console.log('todoItemComponent', logService.name);
+ }]
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todoListComponent = ngCore.Component({
+ .....
+ directives: [ todoItemComponent ],
+ providers: [
+ { provide: logService, useClass: supperLogService }
+ ]
+ })
+ .Class({
+ constructor: [logService, function(logService){
+ console.log('todoListComponent', logService.name + ' is hosted by todoListComponent');
+ }]
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todosComponent = ngCore.Component({
+ .....
+ directives: [ todoListComponent, todoItemComponent ],
+ providers: [
+ logService,
+ { provide: rootLogService, useExisting: logService }
+ ]
+ })
+ .Class({
+ constructor: [logService, function(logService){
+ logService.setName('logService is hosted by todosComponent');
+ }]
+ });`;
+}
+
+function getValueProvider01(){
+ return `
+ export var supperLogService = {
+ name: 'supperLogService'
+ };
+
+ /*---------------------------------------------------------*/
+
+ export var todoListComponent = ngCore.Component({
+ .....
+ providers: [
+ { provide: logService, useValue: supperLogService }
+ ]
+ })
+ .Class(.....);`;
+}
+
+function getValueProvider02(){
+ return `
+ import { OpaqueToken } from '@angular/core';
+
+ export var WINDOW = new OpaqueToken('window');
+
+ export var WINDOW_PROVIDERS = [
+ { provide: WINDOW, useValue: window }
+ ];
+
+ /*---------------------------------------------------------*/
+
+ import { WINDOW } from './window.model';
+
+ export var logService = ngCore.Class({
+ constructor: [
+ ngCore.Inject(WINDOW),
+
+ function(window){
+ this.window = window;
+ }
+ ],
+
+ log: function(text){
+ this.window.console.log(text);
+ }
+ });
+
+ /*---------------------------------------------------------*/
+
+ import { WINDOW_PROVIDERS } from './window.model';
+
+ export var todosComponent = ngCore.Component({
+ .....
+ providers: [
+ logService,
+ WINDOW_PROVIDERS
+ ]
+ })
+ .Class({
+ constructor: [logService, function(logService){
+ logService.log('This message is logged by using window.console via DI');
+ }]
+ });`;
+}
+
+function getFactoryProvider(){
+ return `
+ export var userService = ngCore.Class({
+ .....
+ setAuth: function(isAuth){
+ this.isAuth = isAuth;
+ }
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todoListComponent = ngCore.Component({
+ .....
+ providers: [
+ {
+ provide: logService,
+ useFactory: function(userService){
+ return userService.isAuth ? new supperLogService() : new logService();
+ },
+ deps: [userService]
+ }
+ ]
+ })
+ .Class({
+ constructor: [logService, function(logService){
+ console.log('todoListComponent', logService.name);
+ }]
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todosComponent = ngCore.Component({
+ .....
+ providers: [ userService ]
+ })
+ .Class({
+ constructor: [userService, function(userService){
+ this.userService.setAuth(true);
+ }]
+ });`;
+}
+
+function getOptionalDependency(){
+ return `
+ export var todoListComponent = ngCore.Component({.....})
+ .Class({
+ constructor: [
+ [ new ngCore.Optional(), ngCore.Inject(logService) ],
+
+ function(logService){
+ if(!logService) {
+ console.log('todoListComponent', 'logService is null');
+ }
+ }
+ ]
+ });`;
+}
+
+function getHostDependency(){
+ return `
+ export var todoItemComponent = ngCore.Component({.....})
+ .Class({
+ constructor: [
+ [ new ngCore.Host(), ngCore.Inject(logService) ],
+
+ function(logService){
+ console.log('todoItemComponent', logService.name);
+ }
+ ]
+ });`;
+}
+
+function getDependencyVisibility(){
+ return `
+ export var todoTitleComponent = ngCore.Component({.....})
+ .Class({
+ constructor: [logService, function(logService){
+ console.log('todoTitleComponent', logService.name);
+ }]
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todoItemComponent = ngCore.Component({.....})
+ .Class({
+ constructor: [logService, function(logService){
+ console.log('todoItemComponent', logService.name);
+ }]
+ });
+
+ /*---------------------------------------------------------*/
+
+ export var todoListComponent = ngCore.Component({
+ .....
+ template: [
+ 'Table of Contents
Angular ships with its own dependency injection framework and we really can't build an Angular application without it.
An Angular application is a tree of components. Each component instance has its own injector. The tree of components parallels the tree of injectors.
We can re-configure the injectors at any level of that component tree with interesting and useful results.
Consider a simple example about TodosComponent.
Each component instance gets its own injector and an injector at one level is a child injector of the injector above it in the tree.
When a component at the bottom requests a dependency, Angular tries to satisfy that dependency with a provider registered in that component's own injector.
If the component's injector lacks the provider, it passes the request up to its parent component's injector. If that injector can't satisfy the request, it passes it along to its parent component's injector.
The requests keep bubbling up until we find an injector that can handle the request or run out of component ancestors. If we run out of ancestors, Angular throws an error.
Dependencies are singletons within the scope of an injector.
In our example, logSerivce are shared among todosComponent, todoListComponent, todoItemComponent. Because it is hosted by todosComponent which is parents of todoListComponent & todoItemComponent.
todoListComponent can inject logSerivce from todosComponent via its constructor. However, nested injectors at todoItemComponent create their own service instances by using providers to host logService itself.
A provider provides the concrete of a dependency value.
The injector relies on providers to create instances of the services that the injector injects into components and other services.
As you know, we can register service provider or directive provider by using providers & directives in component's declaration.
Look back our example, you can see the way we registered logSerivce in TodosComponent.
But there are many ways that we can configure the injector with alternative providers that can deliver an object that behaves like logSerivce. We'll expore them now.
We wrote the providers array like this: providers: [ logSerivce ]
This is actually a short-hand expression for a provider registration.
The first is the token that serves as the key for both locating a dependency value and registering the provider.
The second is a provider definition object, which we can think of as a recipe for creating the dependency value.
With this expression, it's easy for us specify another class to provide the service.
For example we have another service is superLogService, We can register it for todoListComponent with logSerivce token instead of logSerivce class.
However, lets look back the example that you registered logService in todosComponent then you used useClass to register superLogService in todoListComponent.
So how can todoItemComponent inject logService from todoComponent instead of superLogService from todoListComponent ?
The solution for this case is you should use useExisting with rootLogService token for register in todosComponent.
Sometimes it's easier to provide a object rather than ask the injector to create it from a class.
We can re-write superLogService as an object then registering it by using useValue like this.
Now, you have seen I used a class as the token such as logService, rootLogService for register, acttualy, there's another way for you to get the same result.
The way I'm mentioning is using OpaqueToken & ngCore.Inject.
OpaqueToken is a good solution for us to inject global variables such as window, localstorage into our component.
Sometimes we need to create the dependent value dynamically, based on information we won't have until the last possible moment. This situation calls for a factory provider.
Let's illustrate, we want to implement a logic like that if user is authenticated, superLogService should be injected into our components, otherwise, logSerivce should be used.
Assume that we have userService which provide information about authentication. We re-write declaration for providers as below.
The deps property is an array of provider tokens which our factory requires for injection.
As you know, if Angular can't resolve injection for component, it'll throw an exception.
In fact, there're situations, we allow the constructor's arguments to be null. We can tell Angular that the dependency is optional by annotating the constructor argument with Optional.
Of course, your code must be prepared to handle a null value.
Well, as we learned, we can use the providers property to define providers for its injector.
However, it turns out that there’s another property viewProviders that basically allows us to do the same thing. What’s the difference between those two them ?
viewProviders allows us to define injector providers that are only available for a component’s view.
Let’s take a closer look at what that means by using our TodosComponent example.
As you can see, todoTitleComponent is contentChild of TodoListComponent, todoItemComponent is viewChild of TodoListComponent.
Both todoTitleComponent & todoItemComponent require an instance of the class which is provided via logSerivce token.
How should we do if we expect that todoTitleComponent require logSerivce's instance, todoItemComponent require superLogService's instance ?
With viewProviders we can tell the DI system very specifically, which providers are available to which child injectors.
To make our code work as expected, all we have to do is to make the supperLogService provider of todoListComponent explicitly available only for its viewChild by using viewProviders instead of providers.
Now, whenever a component of todoListComponent's view asks for something of type logSerivce, it’ll get an instance of superLogService as expected.
Other child components from the outside world(contentChild) that ask for the same type, however, they won’t see this provider and will continue with the lookup in the injector tree.
Which means todoTitleComponent now gets an expected instance from another parent injector without even knowing that todoListComponent actually introduces its own provider.
Note that, viewProviders are also only available in components, not in directives. That’s simply because a directive doesn’t have its own view.
We'll go on with the example in Dependency visibility subject.
Now, look back again, in the example, todoItemComponent requires logSerivce, follow DI rules, it will receice superLogService which is provided by todoListComponent.
This's so cool, however this can be problematic. Just imagine someone uses our todoItemComponent with their customTodoListComponent which doesn't provide superLogService.
What will happen ? our todoItemComponent will receice logSerivce's instance from another parent injector instead. It's unexpected.
If we need to ensure that superLogService instance is always instatiated by our component’s host or an exception should be thrown. Host dependency is a solution for us.
Angular ships with its own dependency injection framework and we really can't build an Angular application without it.
+An Angular application is a tree of components. Each component instance has its own injector. The tree of components parallels the tree of injectors.
+We can re-configure the injectors at any level of that component tree with interesting and useful results.
+Consider a simple example about TodosComponent.
+Each component instance gets its own injector and an injector at one level is a child injector of the injector above it in the tree.
+When a component at the bottom requests a dependency, Angular tries to satisfy that dependency with a provider registered in that component's own injector.
+If the component's injector lacks the provider, it passes the request up to its parent component's injector. If that injector can't satisfy the request, it passes it along to its parent component's injector.
+The requests keep bubbling up until we find an injector that can handle the request or run out of component ancestors. If we run out of ancestors, Angular throws an error.
+Dependencies are singletons within the scope of an injector.
+In our example, logSerivce are shared among todosComponent, todoListComponent, todoItemComponent. Because it is hosted by todosComponent which is parents of todoListComponent & todoItemComponent.
+todoListComponent can inject logSerivce from todosComponent via its constructor. However, nested injectors at todoItemComponent create their own service instances by using providers to host logService itself.
+A provider provides the concrete of a dependency value.
+The injector relies on providers to create instances of the services that the injector injects into components and other services.
+As you know, we can register service provider or directive provider by using providers & directives in component's declaration.
+Look back our example, you can see the way we registered logSerivce in TodosComponent.
+But there are many ways that we can configure the injector with alternative providers that can deliver an object that behaves like logSerivce. We'll expore them now.
+We wrote the providers array like this: providers: [ logSerivce ]
+This is actually a short-hand expression for a provider registration.
+The first is the token that serves as the key for both locating a dependency value and registering the provider.
+The second is a provider definition object, which we can think of as a recipe for creating the dependency value.
+With this expression, it's easy for us specify another class to provide the service.
+For example we have another service is superLogService, We can register it for todoListComponent with logSerivce token instead of logSerivce class.
+However, lets look back the example that you registered logService in todosComponent then you used useClass to register superLogService in todoListComponent.
+So how can todoItemComponent inject logService from todoComponent instead of superLogService from todoListComponent ?
+The solution for this case is you should use useExisting with rootLogService token for register in todosComponent.
+Sometimes it's easier to provide a object rather than ask the injector to create it from a class.
+We can re-write superLogService as an object then registering it by using useValue like this.
+Now, you have seen I used a class as the token such as logService, rootLogService for register, acttualy, there's another way for you to get the same result.
+The way I'm mentioning is using OpaqueToken & ngCore.Inject.
+OpaqueToken is a good solution for us to inject global variables such as window, localstorage into our component.
+Sometimes we need to create the dependent value dynamically, based on information we won't have until the last possible moment. This situation calls for a factory provider.
+Let's illustrate, we want to implement a logic like that if user is authenticated, superLogService should be injected into our components, otherwise, logSerivce should be used.
+Assume that we have userService which provide information about authentication. We re-write declaration for providers as below.
+The deps property is an array of provider tokens which our factory requires for injection.
+As you know, if Angular can't resolve injection for component, it'll throw an exception.
+In fact, there're situations, we allow the constructor's arguments to be null. We can tell Angular that the dependency is optional by annotating the constructor argument with Optional.
+Of course, your code must be prepared to handle a null value.
+Well, as we learned, we can use the providers property to define providers for its injector.
+However, it turns out that there’s another property viewProviders that basically allows us to do the same thing. What’s the difference between those two them ?
+viewProviders allows us to define injector providers that are only available for a component’s view.
+Let’s take a closer look at what that means by using our TodosComponent example.
+As you can see, todoTitleComponent is contentChild of TodoListComponent, todoItemComponent is viewChild of TodoListComponent.
+Both todoTitleComponent & todoItemComponent require an instance of the class which is provided via logSerivce token.
+How should we do if we expect that todoTitleComponent require logSerivce's instance, todoItemComponent require superLogService's instance ?
+With viewProviders we can tell the DI system very specifically, which providers are available to which child injectors.
+To make our code work as expected, all we have to do is to make the supperLogService provider of todoListComponent explicitly available only for its viewChild by using viewProviders instead of providers.
+Now, whenever a component of todoListComponent's view asks for something of type logSerivce, it’ll get an instance of superLogService as expected.
+Other child components from the outside world(contentChild) that ask for the same type, however, they won’t see this provider and will continue with the lookup in the injector tree.
+Which means todoTitleComponent now gets an expected instance from another parent injector without even knowing that todoListComponent actually introduces its own provider.
+Note that, viewProviders are also only available in components, not in directives. That’s simply because a directive doesn’t have its own view.
+We'll go on with the example in Dependency visibility subject.
+Now, look back again, in the example, todoItemComponent requires logSerivce, follow DI rules, it will receice superLogService which is provided by todoListComponent.
+This's so cool, however this can be problematic. Just imagine someone uses our todoItemComponent with their customTodoListComponent which doesn't provide superLogService.
+What will happen ? our todoItemComponent will receice logSerivce's instance from another parent injector instead. It's unexpected.
+If we need to ensure that superLogService instance is always instatiated by our component’s host or an exception should be thrown. Host dependency is a solution for us.
+