#javascript #node.js #dependency-injection #dependency-management
#javascript #node.js #внедрение зависимостей #управление зависимостями
Вопрос:
Настройка
Я создаю базовую библиотеку для распределенного приложения. Вот структура:
core_project/
lib/
index.js
module1.js
module2.js
...
package.json
Многие другие части моего приложения будут использовать эту библиотеку следующим образом:
consumer_project/
node_modules/
core_project/
...
app.js
package.json
Проблема
Я хочу, чтобы некоторые общие зависимости, такие как обработчик DB, предоставлялись потребительским приложением. После инициализации я хочу, чтобы все мои основные модули приложения могли использовать эти зависимости.
Попытка решения
Я попытался создать функцию инициализации модуля в каждом модуле основного приложения: core_project/lib/module1.js
var cfg = {db: null};
module.exports = {
// ...
'initModule': function (db) {
cfg.db = db;
}
}
И это мой индексный файл основного модуля:
core_project/lib/index.js
var modules = {
'module1': require('./module1'),
'module1': require('./module2'),
// ...
};
function create(db) {
var app = {};
init(app, modules, db);
return app;
}
function init(app, mods, db) {
var m;
for (m in mods) {
if (mods.hasOwnProperty(m)) {
if (mods[m].hasOwnProperty('initModule')) {
mods[m].initModule(db);
}
app[m] = mods[m];
}
}
}
module.exports = create;
Теперь мое потребительское приложение может передавать зависимости следующим образом:
consumer_project/app.js
var core = require('core_project');
var db = // initialize db
var app = core(db);
// Start using
app.module1.run();
Проблемы с попыткой решения
- Я должен добавлять
cfg = {db: null}
и экспортироватьinitModule
функцию в каждый модуль, для которого требуются зависимости. - Я должен прикрепить каждый модуль к основному объекту приложения в core_project/lib/index.js
Вопрос
Есть ли лучший способ предоставить потребительские зависимости, такие как db, logger, для базовой библиотеки и всех ее модулей?
Комментарии:
1. если вы не хотите / have_чтобы изобрести собственное решение, проверьте component framework github.com/component/component или новая модульная система ES6, некоторые преимущества, упомянутые в addyosmani.com/writing-modular-js
Ответ №1:
Передача зависимостей в качестве аргументов (т. Е. Внедрение зависимостей) является вполне допустимым способом достижения этой цели, хотя вы можете упростить инициализацию с помощью замыкания:
core_project/lib/module1.js:
module.exports = function(db) {
return function() {
// closure scoped with dependencies
// can use db object
};
}
Тогда ваша функция инициализации создаст закрытие:
app[m] = mods[m](db);
Передача dep, подобная этой, Обычно желательна для клиентов базы данных, поэтому одно и то же соединение используется во всех ваших модулях, однако другие типы dep, такие как регистраторы, могут быть лучше импортировать с использованием стандартного require()
метода модульной системы, например require('winston')
Комментарии:
1. Это то, что я в итоге использовал. Что касается регистраторов, я бы определенно использовал require (‘winston’), Но я бы хотел настроить регистратор (файлы / сокеты для использования) на клиенте и передать настроенный регистратор в качестве dep в ядро.