Хтось вже використовував 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'); }
34 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів