一种众所周知但不太流行的依赖项注入方法。尝试在流行的DI npm软件包中实现此方法。另一个DI。
关于OOP和DI的几句话
我想抛弃将OOP反对其他范式的话题。在我看来,不同的范式很可能在一个应用程序中组合在一起。我认为ES类朝着使用OOP的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 } );
因此,使用di-box,我们有机会以最少,但足够的实现DI的附加代码以OOP风格进行编写。一方面,在实现中存在原型“魔术”,但另一方面,它仅在元级别,并且组件本身可以是纯净的,对环境一无所知。
我很乐意讨论它,也许我错过了其他一些图书馆。或者,也许您知道如何在某些DI实现中最好地实现我的示例。在评论中写。