IOC für Typoskript

stimmen
8

Mit Typoskript jetzt haben wir statische Analyse und viele OOP-Funktionen in JavaScript. So ist es auch Zeit besser Unit-Tests in Client-Seite Logik zu haben, und auch wir brauchen IOC-Container für Abhängigkeitsinjektionen vorzunehmen, um Code mehr prüfbar ...

So haben schon jemand erlebt es zu diesem Thema oder vielleicht wissen Bibliotheken für Typoskript oder JavaScript-Frameworks, die Typoskript werden Portierung kann?

Veröffentlicht am 09/10/2012 um 09:15
quelle vom benutzer
In anderen Sprachen...                            


6 antworten

stimmen
15

Ich habe einen IoC-Container genannt InversifyJS mit erweiterten Dependency Injection-Features wie Kontext Bindungen entwickelt.

Sie müssen folgen drei grundlegenden Schritten , es zu benutzen:

1. Hinzufügen von Anmerkungen

Die Anmerkung API basiert auf Angular 2.0:

import { injectable, inject } from "inversify";

@injectable()
class Katana implements IKatana {
    public hit() {
        return "cut!";
    }
}

@injectable()
class Shuriken implements IShuriken {
    public throw() {
        return "hit!";
    }
}

@injectable()
class Ninja implements INinja {

    private _katana: IKatana;
    private _shuriken: IShuriken;

    public constructor(
        @inject("IKatana") katana: IKatana,
        @inject("IShuriken") shuriken: IShuriken
    ) {
        this._katana = katana;
        this._shuriken = shuriken;
    }

    public fight() { return this._katana.hit(); };
    public sneak() { return this._shuriken.throw(); };

}

2. Deklarieren Bindungen

Die Bindung API basiert auf Ninject:

import { Kernel } from "inversify";

import { Ninja } from "./entities/ninja";
import { Katana } from "./entities/katana";
import { Shuriken} from "./entities/shuriken";

var kernel = new Kernel();
kernel.bind<INinja>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken);

export default kernel;

3. Resolve Abhängigkeiten

Die Auflösung API basiert auf Ninject:

import kernel = from "./inversify.config";

var ninja = kernel.get<INinja>("INinja");

expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true

Die neueste Version (2.0.0) unterstützt viele Anwendungsfälle:

  • Kernel-Module
  • Kernel-Middleware
  • Verwenden Sie Klassen, Stringliterale oder Symbole als Abhängigkeitskennungen
  • Injektion von konstanten Werten
  • Die Injektion von Klassenkonstruktoren
  • Die Injektion von Fabriken
  • Auto Fabrik
  • Die Injektion von Anbietern (Asynchron-Fabrik)
  • Aktivierungsbehandlungsroutinen (Proxies verwendet einzuspritzen)
  • Multi-Injektionen
  • Stichwort Bindings
  • Benutzerdefinierte Tag Dekorateure
  • benannt Bindungen
  • Kontext-bezogene Bindings
  • Freundliche Ausnahmen (zB Rund Abhängigkeiten)

Sie können mehr über sie erfahren https://github.com/inversify/InversifyJS

Beantwortet am 07/05/2015 um 22:33
quelle vom benutzer

stimmen
3

Ich habe für Typoskript DI Bibliothek erstellt - huject

https://github.com/asvetliakov/huject

Beispiel:

import {Container, FactoryMethod, ConstructorInject, Inject} from 'huject';
class FirstService {
   public constructor(param: number) {}
}
class SecondService {
}

@ConstructorInject
class MyController {
    @Inject
    public service: FirstService;

    public second: SecondService;
    public constructor(service: SecondService) {
        this.second = service;
    }
    ...
}
container.setAllowUnregisteredResolving(true);
container.register(FirstService, [10]); // Register constructor arguments

// FirstService and SecondService will be resolved for container instance
let controller = container.resolve(MyController);

Es gibt ein Problem mit Typoskript Schnittstellen zwar, aber ich habe 2 Abhilfen (verwendet abstrakt oder einfache Klasse als Schnittstelle)

Beantwortet am 31/08/2015 um 00:13
quelle vom benutzer

stimmen
3

Denn jetzt können Sie Dependency Injection in JavaScript ohne das IOC Teil verwenden. Es liegt an Ihnen, ob Sie eine „manuelle“ Resolver schreiben oder Fabriken, oder was auch immer DI Muster, das Sie bevorzugen.

Wenn die ECMAScript-6-Norm angenommen wird, kann es das Konzept des IOC möglich in JavaScript machen.

Beantwortet am 09/10/2012 um 11:28
quelle vom benutzer

stimmen
2

Wir haben eine einfache Dependency Injection Container wurden verwendet, die verwendet AMD definieren / erfordern - wie Syntax. Die ursprüngliche Implementierung ist in Typoskript, obwohl die Blog-Post darunter in plain old JavaScript präsentiert.

http://blog.coolmuse.com/2012/11/11/a-simple-javascript-dependency-injection-container/

Es ist ziemlich einfach Abhängigkeitsbeziehungen zu definieren, ohne eine Reihe von Konfigurations zu erfordern, und unterstützt zirkuläre Abhängigkeit Auflösung ähnlich wie requirejs.

Hier ist ein einfaches Beispiel:

// create the kernel
var kernel = new ServiceKernel();

// define service1
kernel.define("service1", function() {

    // service1 has a function named foo
    return {
        foo: function () { return "foo"; }
    }

});

// define service2, which depends on service1
kernel.define("service2", ["service1"], function(service1) {

    // service2 has a function named foobar
    return {
        foobar : function() { return service1.foo() + "bar"; }
    }

});

// get service2 instance 
var service2 = kernel.require("service2");
service2.foobar();  // returns "foobar"

// get both service1 and service2 instances
kernel.require(["service1", "service2"], function(service1, service2) {

    alert(service1.foo() + service2.foobar()); // displays foofoobar

});
Beantwortet am 12/11/2012 um 07:41
quelle vom benutzer

stimmen
1

Alternativ können Sie auch einfach keinen Rahmen verwenden und mit dem Objekt Fabriken als Eigenschaften Klasse als Container verwenden. Anschließend können Sie diese Klasse in Tests und ändern Fabriken erben. Dieser Ansatz ist typsicher und benötigt keine Dekorateure, nur die Registrierung von Klassen.

class B {
    echo() {
        alert('test');
    }   
}

class A {
    constructor(private b: B) {
        b.echo();
    }
}

class Container {
    A = () => new A(this.B());
    B = singleton(() => new B()); 
}

var c = new Container();
var a = c.A();

// singleton helper:

function memoize<T>(factory: () => T): () => T  {
    var memo: T = null;
    return function () {
        if(!memo) {
            memo = factory();
        }
        return memo;
    };
}

var singleton = memoize;
Beantwortet am 15/10/2015 um 08:35
quelle vom benutzer

stimmen
0

Kasse https://github.com/typestack/typedi

so etwas wie dies möglich ist:

import "reflect-metadata";
import {Service, Container} from "typedi";

@Service()
class SomeClass {

    someMethod() {
    }

}

let someClass = Container.get(SomeClass);
someClass.someMethod();
Beantwortet am 03/12/2018 um 12:15
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more