Хтось вже використовував Dependency Injection від Angular 2 як окремий модуль DI?

В документації Angular 2 сказано, що їхній фреймворк DI можна використовувати як окремий модуль в інших фреймворках

Angular ships with its own dependency injection framework. This framework can also be used as a standalone module by other applications and frameworks.

На Github є angular/di.js, там є приклади як можна використовувати DI, але схоже що цей проект вже не підтримується (останній коміт був більше, ніж рік назад). Спосіб використання відрізняється від описаного зараз в документації Angular 2.

В той же час, в ядрі Angular 2 є частина, яка відповідає за DI: @angular/core/src/di, є свіжі коміти в неї, але ще ніде не зустрічав прикладів використання, як про це говориться в документації.

Ніхто не експериментував із цим? Цікавить використання на бекенді з Node.js.

Оновлення від 04.07.2016 00:39:
Краще розібрався з обидвома варіантами використання DI, причому в контексті використання TypeScript. Однозначно зручніший і кращий — свіжіший варіант, зацініть:

1. Скачуємо та зберігаємо DI та reflect-metadata, яка теж буде потрібна:

npm i -S @angular/core reflect-metadata

2. Якщо у нас є сервіс, який ми будемо включати в інші класи, ми просто дописуємо @Injectable() попереду класа сервіса, сам клас позначаємо що він буде експортуватись, а у конструкторі прописуємо усі залежності, якщо вони існують:

// Це файл ./classes/services/mysql-connect-service.ts
import mysql = require('mysql');
import {Injectable} from '@angular/core/src/di';

@Injectable()
export class MysqlConnectService
{
  getConnection()
  {
    let connection = mysql.createConnection({
      host     : 'localhost',
      user     : 'користувач',
      password : 'пароль',
      database : 'базаданих'
    });

    connection.connect();
    
    return connection;
  }
}

3. Те ж саме правило застосовуємо до усіх класів, які ми хочемо включати в інші класи в якості залежностей, наприклад нехай це буде клас контролера UsersCtrl:

// Це файл ./classes/controllers/users.ts
import restify = require('restify');
import errors = require('restify-errors');
import {MysqlConnectService} from '../services/mysql-connect-service';
import {Injectable} from '@angular/core/src/di';

@Injectable()
export class UsersCtrl
{
  constructor(private connect:MysqlConnectService){}

  // ...
}

4. Тепер у головному файлі, який буде першим запускатись з node.js, імпортуємо усі класи, які треба буде включати як залежності в інші класи, і запускаємо процес вирішення усіх залежностей:

import 'reflect-metadata';
import {MysqlConnectService} from './classes/services/mysql-connect-service';
import {UsersCtrl} from './classes/controllers/users';
import {ReflectiveInjector} from '@angular/core/src/di';

let injector = ReflectiveInjector.resolveAndCreate([MysqlConnectService, UsersCtrl]);
let instanceCtrl = injector.get( UsersCtrl );

Все! Тепер всі залежності вирішені, нам залишається лише брати і користуватись instanceCtrl.

Єдине, що трохи хакнуте — це додавання import ’reflect-metadata’; у головному файлі, бо без нього node.js чомусь лається.

Заліковно! =)

Оновлення від 05.07.2016 14:04:

З декоратором @Injectable DI, що знаходиться в ядрі angular 2, звісно чистіший код, менше писанини в самих класах, але некудишні справи у головному файлі, бо ми повинні знати «які саме залежності є у потрібного нам класа» (вище у прикладі я просто передаю усі класи, але це точно не правильний підхід...).

Переглядав як можна цього уникнути, але поки що не знайшов як. Тому таки практичнішим є використання саме окремого модуля angular 2 di.js

npm install --save [email protected]
// in engine.js
var Engine = function() {
  this.state = 'stopped';
};

Engine.prototype = {
  start: function() {
    console.log('Starting engine...');
    this.state = 'running';
  }
};

module.exports = Engine;
// in car.js
var di = require('di');
var Engine = require('./engine');

var Car = function(engine) {
  this.engine = engine;
};

Car.prototype = {
  run: function() {
    this.engine.start();
  },
  isRunning: function() {
    return this.engine.state === 'running';
  }
};

di.annotate(Car, new di.Inject(Engine));

module.exports = Car;
// in main.js
var di = require('di');
var Car = require('./car');


var injector = new di.Injector([]);

console.log('Getting in the car...');
var car = injector.get(Car);

car.run();

if (car.isRunning()) {
  console.log('The car is running');
} else {
  console.log('The car is stopped');
}

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Еще хотел бы поделиться ссылкой на IoC с множеством возможностей — inversify.io

import ’reflect-metadata’; у головному файлі, бо без нього node.js чомусь лається.
Декораторы .

Судя по применению — все это было зря (ноде экспорты синглтоны).

Ви вмієте висловлювати свою думку більше, ніж односкладно? Що ви маєте на увазі під “ноде експорты синглтоны — это зря”, в даному випадку? Ви очікували що DI сам заінклудить все необхідне, так? — Хз, можливо я зайве щось роблю, але не побачив поки що як це можна спростити. Для мене це вже й так дуже зручний працюючий механізм...

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

Додав Оновлення від 04.07.2016 00:39:

І що там ви можете знайти по даній темі, думаєте я там не шукав?

В мене не настільки хороша англійська, щоб задавати подібні розгорнуті питання. Ну і плюс, мабуть, за правилами Stackoverflow, воно буде «не у форматі».

Не бойтесь Stackoverflow. Ваш английский поправят. А информация полезная и очень даже "
«в формате»

А Вы не пробовали паттерн DI на практике?

Ну так просвятите, только без явастайл.

Хоча ось тут є специфіка суто Angular’івска, але вони наводять багато вагомих аргументів чому є сенс використовувати взагалі DI.

У Вас тоже куча реализаций ioc, aop с полусотней звезд что бы сувать линки в нос ? github.com/Pencroff

Вам не сподобалось, що я вам дав лінк, чи що? Типу «хто я такий, щоб давати вамі лінки» — так? :))

Скажем так — упрек, намек от Pencroff (Sergii Daniloff) мне более интересен.

Коментар порушує правила спільноти і видалений модераторами.

Коментар порушує правила спільноти і видалений модераторами.

Коментар порушує правила спільноти і видалений модераторами.

Не совсем понимаю Ваш саркастический тон по поводу языков сос статической типизацией (там он реализуется намного проще с помощью рефлексии), в JS (язык с динамической типизацией) же вся сложность что все просто объект или функция и сложно придумать красивый синтакс для декларации зависимостей.
Благо с декораторами красивый синтаксис стало легче изобретать ;)
По поводу патернов, они кстати от языка не зависят, посмотрите Мартина Фаулера — martinfowler.com/articles/injection.html
Ну и линк ниже дает ответ на вопрос «почему» :)

Никакого сарказма .. очередное сделаем java из js и поголовное ниасиляторство последнего. Но это про «вобщем», сама годиков так кхм была такая когда на жс перелазила окончательно с горячей любовью к шпрынгу и плюшкам..

Мне тоже нравиться гибкость JS и отсутствие типов (сейчас на проекте ES6), но практика показывает что, например применение TypeScript, облегчит жизнь джунам и согласование контрактов между разработчиками или командами.

Любопытно. В реальном применении (в Вашем случае) — какие части реально помогли и в чем из того, чего нет в es-next ? Даже если имелся в виду тандем с фреймверком (известно каким).

Не совсем понимаю что такое

es-next
.

Это из слэнга babel , сейчас просто «ES2015 and beyond» )

Если Вы имеете в виду части TypeScript в сравнении с ES6? То TS мы не используем, но его применение облегчало бы коммуникацию.

Я так понимаю речь идет о тулзах, неужели все изза uml ?
Ну не верю я что в Даблине жуны с рождения знают ts )))

А я и не говорил что его знают с рождения, ES6 еще не все на проектах используют, потому что миграция это очень трудный и не предсказуемый процесс с непонятными бенефитами для менеджеров.
Мы не используем, но вижу тренд, что гугл всех заганяет на TS.

Да вроде бы на dart загонял загонял. Скорее тогда M$, но там тоже vbscript и jscript были .Поверить не получается . Да и браузеры с нодой поддерживают много из es6. Кстати говоря TS во фреймверке (известно каком) — это всего лишь одна из опций. Странный культ честно говоря, при :

не предсказуемый процесс с непонятными бенефитами для менеджеров.

Пусть я ошибаюсь насчет тренда :)
А по поводу «браузеры с нодой поддерживают многое из ES6», так проблема здесь в том что не у всех новые браузеры и ES6 без бабеля использовать сложно.
А Вы пробовали без опции TS завести Angular 2? :)

Да, хотя против ts ничего не имею, но и придумать проблему которую он решает тоже не могу... как, собственно и Вы.

Так поэтому TS и нет на проекте, потому как не видно ОЧЕНЬ ЯВНЫХ преимуществ. Увидим — добавим :)

Это была такая синхронизация сознаний с материком )))))

А Вы пробовали без опции TS завести Angular 2? :)
Собственно, в чем проблема? На babel’е заводится легко.

Підписатись на коментарі