Injection using abstract classes

This commit is contained in:
2018-02-28 00:05:11 +01:00
parent 70ce7711a7
commit 507ab5d40f
9 changed files with 42 additions and 34 deletions

View File

@@ -1,7 +1,7 @@
import { Track } from "../../domain/models/Track";
import { IMusicRepository } from "../../domain/ports/IMusicRepository";
import { MusicRepository } from "../../domain/ports/MusicRepository";
export class VinylCatalog implements IMusicRepository {
export class VinylCatalog implements MusicRepository {
private vinylList: Track[] = new Array(
new Track(1, "DNA.", "Kendrick Lamar", 340),

View File

@@ -1,3 +0,0 @@
export interface IInjector {
inject<T>(name : string) : T;
}

View File

@@ -1,10 +0,0 @@
import { Track } from "../models/Track";
export interface IMusicRepository {
get() : Track[];
getById(id: number) : Track | null;
add(track: Track) : number;
edit(id: number, track: Track) : Track;
delete(id: number) : Track | null;
}

View File

@@ -0,0 +1,3 @@
export abstract class Injector {
abstract inject<T>(constructorFn: Function) : T;
}

View File

@@ -0,0 +1,10 @@
import { Track } from "../models/Track";
export abstract class MusicRepository {
abstract get() : Track[];
abstract getById(id: number) : Track | null;
abstract add(track: Track) : number;
abstract edit(id: number, track: Track) : Track;
abstract delete(id: number) : Track | null;
}

View File

@@ -1,18 +1,18 @@
import { IMusicRepository } from "../../domain/ports/IMusicRepository";
import { MusicRepository } from "../../domain/ports/MusicRepository";
import { Track } from "../../domain/models/Track";
import { IInjector } from "../../domain/ports/IInjector";
import { Injector } from "../../domain/ports/Injector";
export class MusicCatalogService {
private repository: IMusicRepository;
private repository: MusicRepository;
constructor(repository:IMusicRepository){
constructor(repository:MusicRepository){
this.repository = repository;
}
static new(injector : IInjector) : MusicCatalogService {
return new MusicCatalogService(injector.inject<IMusicRepository>("IMusicRepository"))
static new(injector : Injector) : MusicCatalogService {
return new MusicCatalogService(injector.inject(MusicRepository))
}
get(): Track[] {

View File

@@ -1,12 +1,13 @@
import { MusicCatalogService } from "../domain/services/MusicCatalogService"
import { IMusicRepository } from "../domain/ports/IMusicRepository";
import { MusicRepository } from "../domain/ports/MusicRepository";
import { Track } from "../domain/models/Track";
import { VinylCatalog } from "../adapters/music/VinylCatalog";
import { Wiring } from "../wiring/Wiring";
export class MusicComponent {
constructor() {
const injector = Wiring.getInjector();
let musicCatalogService = MusicCatalogService.new(injector);

View File

@@ -1,15 +1,22 @@
import { IInjector } from "../domain/ports/IInjector"
import { Injector } from "../domain/ports/Injector"
export class Container implements IInjector {
export class Container implements Injector {
private items : any = { };
public register(name : string, fn : Function) : void {
public registerName(name : string, fn : Function) : void {
console.log(`registering ${name}`);
this.items[name] = fn;
}
public inject<T>(name: string): T {
public register(nameFn : Function, fn : Function) : void {
let name = (nameFn as any).name || nameFn.prototype.name;
console.log(`registering ${name}`);
this.items[name] = fn;
}
public inject<T>(fn: Function) : T {
let name = (fn as any).name || fn.prototype.name;
if (this.items[name]) {
return this.items[name]();
}
throw new Error(`Failed to resolve ${name}`)
throw new Error(`Failed to resolve ${name} of ${JSON.stringify(Object.keys(this.items))}`);
}
}

View File

@@ -1,16 +1,16 @@
import { IInjector } from "../domain/ports/IInjector";
import { Injector } from "../domain/ports/Injector";
import { Container } from "./Container";
import { VinylCatalog } from "../adapters/music/VinylCatalog";
import { MusicRepository } from "../domain/ports/MusicRepository";
export class Wiring {
private static injector : IInjector;
private static injector : Injector;
public static apply() : void {
console.log('registering IMusicRepository');
const container = new Container();
container.register('IMusicRepository', () => new VinylCatalog());
Wiring.injector = container;
const container = new Container();
container.register(MusicRepository, () => new VinylCatalog());
Wiring.injector = container;
}
public static getInjector() : IInjector {
public static getInjector() : Injector {
if (!Wiring.injector) {
Wiring.apply();
}