Алексей Плуталов, Злые марсиане
Чем сложнее класс или компонент, тем меньше должно быть внешних связей.
Важный принцип используемый для уменьшения связанности кода
Паттерн скрывающий процессы связанные с получением модуля с сильным уровнем абстракции
Реализуется в виде центрального реестра ресурсов, возвращающего нужную информацию по запросу
var Connection = function () {this.logger = require("logger")();/* реализация логики */}
Процесс предоставления внешней зависимости программному компоненту
// adapter - клиент хранилища (например, REST)// serializator - сериализатор данныхvar Resource = function (adapter, serializator) {this.adapter = adapter;this.serializator = serializator;};
var Resource = function ( ) { };Resource.prototype.setAdapter = function (adapter) {this.adapter = adapter;};Resource.prototype.setSerializator = function (srl) {this.serializator = srl;};
var Injectable = function ( ) { };Injectable.prototype.inject = function (name, dep) { };var Resource = function ( ) { Injectable.apply(this); };Resource.prototype.inject = function (name, dep) {this[name] = dep;};
Object.prototype.inject = function (name, dep) {this[name] = dep;};var resource = new Resource();resource.inject(adapter, serializer);
jQuery.fn.pluginName = function ( ) {this; // jQuery объект с выборкой элементов};
app.use(function * ( ) {this; // Koa Contextthis.request; // Koa Requestthis.response; // Koa Response});
Программный каркас реализующий DI, и упрощающий его использование
Многие фреймворки являются реализацией IoC-container
Ember.js предоставляет IoC-container, и две реализации DI:
App.SessionController = Ember.Controller.extend({isSignedIn: false});App.IndexController = Ember.Controller.extend({needs: [ "session" ],isSignedIn: function ( ) {return this.get("controllers.session.isSignedIn");}.property("controllers.session.isSignedIn");});
App.SignInController = Ember.Controller.extend({needs: [ "session" ],isSignedIn: Ember.computed.alias("controllers.session.isSignedIn"),actions: {signIn: function ( ) {this.set("isSignedIn", true);}}});
Использование DI в Ember.js сводится к двум методам:
register — регистрация провайдераinject — внедрение зависимостиvar Logger = Ember.Object.extend({write: function (msg) {console.log(msg);}});application.register("logger:console", Logger);
var Logger = Ember.Object.extend({write: function (msg) {console.log(msg);}});application.register("logger:console", Logger, { singleton: false });
App.register("logger:console", function (msg) {console.log(msg);}, {instantiate: false});
Ember.Application.initializer({name: "logger",initialize: function (container, application) {application.register("logger:console", function (msg) {console.log(msg);}, { instantiate: false });application.inject("route", "logger", "logger:console");}});App.create();
App = Ember.Application.create({Resolver: Ember.DefaultResolver.extend({resolveTemplate: function (parsedName) {var resolvedTemplate = this._super(parsedName);if (resolvedTemplate) {return resolvedTemplate;}return JST[parsedName] || Ember.TEMPLATES["not_found"];}});});
resolve[Type] — разрешение типа зависимостиresolveOther — разрешение всех остальных зависимостейКастомизацию разрешения зависимостей используют