Eine bekannte, aber nicht sehr beliebte Methode zur Abhängigkeitsinjektion. Ein Versuch, diese Methode in gängigen DI npm-Paketen zu implementieren. Ein weiterer DI.
Ein paar Worte zu OOP und 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 } );
Mit di-box haben wir also die Möglichkeit, im OOP-Stil mit minimalem, aber ausreichendem zusätzlichem Code zu schreiben, der DI implementiert. Einerseits gibt es prototypische "Magie" in der Implementierung, andererseits nur auf Metaebene, und die Komponenten selbst können rein sein und nichts über die Umgebung wissen.
Ich würde gerne darüber diskutieren, vielleicht habe ich einige andere Bibliotheken verpasst. Oder vielleicht wissen Sie, wie Sie mein Beispiel am besten in einer der DI-Implementierungen implementieren können. Schreiben Sie in die Kommentare.