Created
September 5, 2017 12:20
Using Abstract Classes As Dependency-Injection Tokens For Swappable Behaviors In Angular 4.2.3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Import the core angular services. | |
import { Component } from "@angular/core"; | |
import { Inject } from "@angular/core"; | |
import { InjectionToken } from "@angular/core"; | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
// This injection token can be used to configure the Providers as well as the @Inject() | |
// meta-data that will tell the dependency-injection container how to locate the desired | |
// class instance. | |
var GreeterToken = new InjectionToken<GreeterInterface>( "Greeter behavior" ); | |
interface GreeterInterface { | |
greeting() : string; | |
} | |
class NiceGreeter implements GreeterInterface { | |
public greeting() : string { | |
return( "Hello, what a pleasure to meet you." ); | |
} | |
} | |
class MeanGreeter implements GreeterInterface { | |
public greeting() : string { | |
return( "Hello, you are a doofus!" ); | |
} | |
} | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
@Component({ | |
selector: "my-app", | |
providers: [ | |
// For this application, let's provide the MeanGreeter instance when the | |
// GreeterToken needs to be injected into the App component. | |
{ | |
provide: GreeterToken, | |
useClass: MeanGreeter // <--- Defining the swappable implementation. | |
} | |
], | |
styleUrls: [ "./app.component.css" ], | |
template: | |
` | |
<p> | |
<strong>Greeting:</strong> {{ greeting }} | |
</p> | |
` | |
}) | |
export class AppComponent { | |
public greeting: string; | |
// I initialize the app component. | |
constructor( @Inject( GreeterToken ) greeter: GreeterInterface ) { | |
this.greeting = greeter.greeting(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Import the core angular services. | |
import { Component } from "@angular/core"; | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
interface GreeterInterface { | |
greeting() : string; | |
} | |
class NiceGreeter implements GreeterInterface { | |
public greeting() : string { | |
return( "Hello, what a pleasure to meet you." ); | |
} | |
} | |
// CAUTION: Here, I am saying that the "MeanGreeter" IMPLEMENTS the "NiceGreeter." | |
class MeanGreeter implements NiceGreeter { | |
public greeting() : string { | |
return( "Hello, you are a doofus!" ); | |
} | |
} | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
@Component({ | |
selector: "my-app", | |
providers: [ | |
// For this application, let's provide the MeanGreeter instance when the | |
// NiceGreeter needs to be injected into the App component. | |
{ | |
provide: NiceGreeter, | |
useClass: MeanGreeter // <--- Defining the swappable implementation. | |
} | |
], | |
styleUrls: [ "./app.component.css" ], | |
template: | |
` | |
<p> | |
<strong>Greeting:</strong> {{ greeting }} | |
</p> | |
` | |
}) | |
export class AppComponent { | |
public greeting: string; | |
// I initialize the app component. | |
constructor( greeter: NiceGreeter ) { | |
this.greeting = greeter.greeting(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Import the core angular services. | |
import { Component } from "@angular/core"; | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
// Because an Abstract class has a runtime representation, we can use it as a | |
// dependency-injection (DI) token in Angular's DI container. And, since each concrete | |
// class has to implement or extend this abstract base class, it means that the base | |
// class can act as the "interface" to the behavior as well. | |
abstract class Greeter { | |
abstract greeting() : string; | |
} | |
// NOTE: We could have also used "extends Greeter" if Greeter provided base | |
// functionality that needed to be shared with its concrete classes. | |
class NiceGreeter implements Greeter { | |
public greeting() : string { | |
return( "Hello, what a pleasure to meet you." ); | |
} | |
} | |
// NOTE: We could have also used "extends Greeter" if Greeter provided base | |
// functionality that needed to be shared with its concrete classes. | |
class MeanGreeter implements Greeter { | |
public greeting() : string { | |
return( "Hello, you are a doofus!" ); | |
} | |
} | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
@Component({ | |
selector: "my-app", | |
providers: [ | |
// For this application, let's provide the MeanGreeter instance when the | |
// Greeter needs to be injected into the App component. | |
{ | |
provide: Greeter, | |
useClass: MeanGreeter // <--- Defining the swappable implementation. | |
} | |
], | |
styleUrls: [ "./app.component.css" ], | |
template: | |
` | |
<p> | |
<strong>Greeting:</strong> {{ greeting }} | |
</p> | |
` | |
}) | |
export class AppComponent { | |
public greeting: string; | |
// I initialize the app component. | |
constructor( greeter: Greeter ) { | |
this.greeting = greeter.greeting(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class NiceGreeter implements GreeterInterface { | |
private value: string = "Hello, what a pleasure to meet you."; | |
public greeting() : string { | |
return( this.value ); | |
} | |
} | |
// CAUTION: Here, I am saying that the "MeanGreeter" IMPLEMENTS the "NiceGreeter." | |
class MeanGreeter implements NiceGreeter { | |
public greeting() : string { | |
return( "Hello, you are a doofus!" ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment