МОК для машинописи

голоса
8

С машинопись теперь мы имеем статический анализ и много возможностей объектно-ориентированного программирования в JavaScript. Так что это также время, чтобы иметь лучшие юнит-тесты в стороне клиента логики и так же нам нужно контейнер МОК для инъекций зависимостей сделать код более проверяемым ...

Итак, у кого-то уже испытало это этот предмет или, может быть, знает, библиотеки для машинописи или фреймворк, которые могут быть портирование на машинопись?

Задан 09/10/2012 в 09:15
источник пользователем
На других языках...                            


6 ответов

голоса
15

Я разработал контейнер IoC под названием InversifyJS с расширенными возможностями для инъекций зависимостей, таких как контекстные привязки.

Вы должны следовать 3 основных шага , чтобы использовать его:

1. Добавить аннотации

Аннотацию API основан на угловых 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. Заявляют привязок

Связывание API основан на 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

Разрешение API базируется на Ninject:

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

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

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

В последней версии (2.0.0) поддерживает множество вариантов использования:

  • модули ядра
  • Ядро промежуточного слоя
  • Используйте классы, строковые литералы или символы в качестве идентификаторов зависимостей
  • Инъекция постоянных значений
  • Инъекция класса конструкторах
  • Инъекция заводов
  • Авто завод
  • Инъекции поставщиков (асинхронная завод)
  • Обработчики активации (используется для введения прокси)
  • Мульти инъекции
  • Tagged привязок
  • Пользовательские теги декораторов
  • Названные привязок
  • Контекстные привязок
  • Дружественные исключения (например, круговая зависимость)

Вы можете узнать больше об этом на https://github.com/inversify/InversifyJS

Ответил 07/05/2015 в 22:33
источник пользователем

голоса
3

Я создал библиотеку DI для машинописи - huject

https://github.com/asvetliakov/huject

Пример:

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);

Существует проблема с машинопись интерфейсов, хотя, но у меня есть 2 обходные пути (использовать абстрактный или простой класс как интерфейс)

Ответил 31/08/2015 в 00:13
источник пользователем

голоса
3

На данный момент, вы можете использовать инъекции зависимостей в JavaScript без части МОК. Это до вас, написать ли вы «ручной» распознаватель или фабрики, или любой другой DI шаблон, который вы предпочитаете.

Когда стандарт ECMAScript 6 принят, он может сделать понятие МОК возможно в JavaScript.

Ответил 09/10/2012 в 11:28
источник пользователем

голоса
2

Мы использовали простую зависимость инъекционного контейнера, который использует AMD определить / требуется - подобный синтаксис. Оригинальная реализация в машинописном, хотя сообщение в блоге ниже представляет его в обычном старом JavaScript.

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

Это довольно просто определить отношения зависимости, не требуя кучу конфигурации, и поддерживает разрешение круговой зависимости, аналогичную requirejs.

Вот простой пример:

// 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

});
Ответил 12/11/2012 в 07:41
источник пользователем

голоса
1

В качестве альтернативы вы можете просто использовать никаких заделов и использовать класс в качестве контейнера с объектными заводами как свойства. Вы можете наследовать этот класс в тестах и ​​изменения фабрик. Такой подход типобезопасна и не требуют каких-либо декораторов, только регистрацию классов.

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;
Ответил 15/10/2015 в 08:35
источник пользователем

голоса
0

выписка https://github.com/typestack/typedi

что-то, как это возможно:

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

@Service()
class SomeClass {

    someMethod() {
    }

}

let someClass = Container.get(SomeClass);
someClass.someMethod();
Ответил 03/12/2018 в 12:15
источник пользователем

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