A well-known but not very popular method of dependency injection. An attempt to implement this method in popular DI npm packages. Another DI.
A few words about OOP and DI
. . ES js .
. 2006 , β PERL. . OO , , PERL , 1, 2, .
2 , , , . , . . , .
JavaScript, , . , , .
TypeScript , , - ( ). .
, JS , . JQuery UI Widget Factory. , - , . ES6 classes ES5 . ES6 DI.
(dependency injection) . , , . , DI, .
DI . , β . , (/ , , , , ...). / . , ββ, - . β ! DI.
DI β .
β , . Javascript . . , .
.
App ,
Storage β ( singleton/service),
Date, ( ).
- . (transient) βnewβ.
- (singleton) βoneβ.
class App {
/** @type { function( int ):IDate } */
newDate;
/** @type { function(): IStorage } */
oneStorage;
construct( newDate, oneStorage ) {
this.newDate = newDate;
this.oneStorage = oneStorage;
}
main() {
const oDate1 = this.newDate( 0 );
const oDate2 = this.newDate( 1000 );
const oStorage = this.oneStorage();
oStorage.insert( oDate1.format() + ' - ' + oDate2.format() );
}
}
, . (lazy). , ( inversify: to, toSelf, toConstantValue, toDynamicValue, toConstructor, toFactory, toFunction, toAutoFactory, toProvider, toService), DI . , .
DI . DI , , . DI .
dependency injection
, , , . dependency injection. :
- , . .
- , / . , , .
- , . , , , , / IDE.
DI. , DI , .
DI . , . , , DI .
, , , , , . , - , - , . . β β-β )
dependency injection javascript/typescript
, βdiβ npm. ~1400. . npm dependents.
repo | npm dependents | npm weekly downloads | github stars | , | , | lang | ES classes | interfaces | inject property | bundle size, KB | open github issues | github forks |
inversify/Inversifyjs
|
1798
|
408k | 6.6k | 6 | 1 | TS | + | + | + | 63.3 | 204 | 458 |
typestack/typedi | 353 | 62k | 1.9k | 5 | 3 | TS | + | + | + | 30.3 | 17 | 98 |
thlorenz/proxyquire | 344 | 426k | 2.6k | 8 | 8 | ES5 | ? | ? | ? | ? | 9 | 116 |
jeffijoe/awilix | 244 | 42k | 1.7k | 5 | 1 | TS | + | - | - | 31.7 | 2 | 92 |
aurelia/dependency-injection
|
153
|
13k | 156 | 6 | 2 | TS | + | - | ? | ? | 2 | 68 |
stampit-org/stampit | 170
|
22k | 3k | 8 | 1 | ES5 | ? | ? | ? | ? | 6 | 107 |
microsoft/tsyringe
|
149
|
80k | 1.5k | 3 | 1 | TS | + | + | - | 30.4 | 27 | 69 |
boblauer/mock-require
|
136 | 160k | 441 | 6 | 1 | ES5 | ? | ? | ? | ? | 4 | 29 |
mgechev/injection-js | 105 | 236k | 928 | 4 | 1 | TS | + | -? | ? | 41.7 | 0 | 48 |
young-steveo/bottlejs
|
101
|
16k | 1.2k | 6 | 1 | ES5 + D.TS | -? | - | - | 13.3 | 2 | 63 |
jaredhanson/electrolyte
|
33 | 1k | 569 | 7 | 1 | ES5 | - | - | - | ? | 25 | 65 |
zhang740/power-di
|
10
|
0.2k | 65 | 4 | 1 | TS | + | + | + | 45.0 | 2 | 69 |
jpex-js/vue-inject
|
9 | 0.8k | 174 | 4 | 12 | ES5 | - | - | ? | ? | 3 | 14 |
zazoomauro/node-dependency-injection
|
5
|
1k | 123 | 4 | 2 | ES6 + D.TS | + | -? | + | 291.0 | 3 | 17 |
justmoon/constitute | 4 | 8k | 132 | 5 | 60 | ES6 | + | -? | - | 56.2 | 4 | 6 |
owja/ioc | 1
|
2k | 158 | 1 | 3 | TS | + | + | + | 11.3 | 4 | 5 |
kraut-dps/di-box
|
1 | 0k | 0 | 0 | 1 | ES6 + D.TS | + | + | + | 11.1 | 0 | 0 |
https://github.com/inversify/InversifyJS
, , , . )). , . )
https://github.com/typestack/typedi
, , . , , App Date, . , ?
https://github.com/thlorenz/proxyquire
, . . DI, .
https://github.com/jeffijoe/awilix
, βSymbol(Symbol.toPrimitive)β, , - Proxy, Date . .
https://github.com/aurelia/dependency-injection
https://github.com/stampit-org/stampit
. . - .
https://github.com/microsoft/tsyringe
Microsoft, . , .
https://github.com/boblauer/mock-require
https://github.com/mgechev/injection-js
Angular 4. , , useFactory .
https://github.com/young-steveo/bottlejs
. .instanceFactory, .
https://github.com/jaredhanson/electrolyte
. ES6 .
https://github.com/zhang740/power-di
. React. . - . , .
https://github.com/jpex-js/vue-inject
vue ES6 . . ES6 classes, provide inject DI. .
https://github.com/zazoomauro/node-dependency-injection
YAML/JS/JSON . . php symfony , setParameter, , .
https://github.com/justmoon/constitute
, , DI .
https://github.com/owja/ioc
inversify, . , : , , . , .
https://github.com/kraut-dps/di-box
, .
, , DI , , .
ββ, :
class Service {
work () {
console.log('work');
}
}
class App {
oneService;
main () {
this.oneService().work();
}
}
// es6 , DI
class AppBox {
Service;
App;
_oService;
newApp () {
const oApp = new this.App();
//
oApp.oneService = this.oneService.bind(this);
return oApp;
}
oneService () {
if (!this._oService) {
this._oService = new this.Service();
}
return this._oService;
}
}
const oBox = new AppBox();
oBox.Service = Service;
oBox.App = App;
const oApp = oBox.newApp();
oApp.main();
Box , , .
(.one()), bind(this), . :
import {Box} from "di-box";
class Service {
work() {
console.log( 'work' );
}
}
class App {
oneService;
main() {
this.oneService().work();
}
}
class AppBox extends Box {
App;
Service;
newService() {
return new this.Service();
}
oneService() {
return this.one( this.newService );
}
newApp() {
const oApp = new this.App();
oApp.oneService = this.oneService;
return oApp;
}
}
const oBox = new AppBox();
oBox.Service = Service;
oBox.App = App;
const oApp = oBox.newApp();
oApp.main();
:
const oBox = new AppBox();
// oBox.Service = Service;
oBox.App = App;
const oApp = oBox.newApp(); // : Service is undefined
oApp.main();
...
DI . , , . , .
:
constructor( arg1, arg2, arg3 ) {}
//
constructor( { arg1key: arg1, arg2key: arg2, arg3key: arg3 } ) {}
, . ?
- - .
- .
. undefined. . .
:
class A {
_arg1;
_arg2;
constructor( arg1, arg2 = null ) {
this._arg1 = arg1;
this._arg2 = arg2;
}
}
const instance = new A( 1, 2 );
//
class A {
arg1; // ,
arg2 = null; // null !== undefined
}
const instance = new A();
instance.arg1 = 1;
instance.arg2 = 2;
dependency injection , . di-box.
typescript constructor( public arg1: type, public arg2: type ) Box:
new AppBox( { bNeedSelfCheck: false, sNeedCheckPrefix: null } );
So with di-box we get the opportunity to write in OOP style, with minimal, but sufficient additional code that implements DI. On the one hand, there is prototypal "magic" in the implementation, but on the other hand, it is only at the meta level, and the components themselves can be pure and know nothing about the environment.
I would be glad to discuss it, maybe I missed some other libraries. Or maybe you know how best to implement my example in some of the DI implementations. Write in the comments.