@@ -18,6 +18,29 @@ const serviceProvider = Symbol("serviceProvider");
1818
1919const globalServiceProvider = Symbol ( "globalInstance" ) ;
2020
21+ let newServiceTarget = null ;
22+
23+ const patched = Symbol ( "serviceConstructorPatched" ) ;
24+
25+ const patchClass = ( type ) => {
26+ if ( type [ patched ] ) {
27+ return ;
28+ }
29+ const parent = Object . getPrototypeOf ( type ) ;
30+ if ( parent === null || parent === Object || parent === Object . prototype ) {
31+ // eslint-disable-next-line @typescript-eslint/ban-types
32+ const old = type . constructor as Function ;
33+ type . constructor = function ( ...a ) {
34+ this [ serviceProvider ] = newServiceTarget ;
35+ return old . apply ( this , a ) ;
36+ } ;
37+ type [ patched ] = true ;
38+ return ;
39+ }
40+ patchClass ( parent ) ;
41+ type [ patched ] = true ;
42+ } ;
43+
2144export class ServiceProvider implements IDisposable {
2245
2346 public static from ( owner : any ) {
@@ -167,10 +190,14 @@ export class ServiceProvider implements IDisposable {
167190 }
168191
169192 private createFromType ( type , key = type ) : any {
193+ const old = newServiceTarget ;
194+ newServiceTarget = this ;
170195 const injectTypes = type [ injectServiceTypesSymbol ] as any [ ] ;
171196 const injectServices = injectTypes
172197 ? injectTypes . map ( ( x ) => this . resolve ( x ) )
173198 : [ ] ;
199+ patchClass ( type . prototype ) ;
200+ type = type . prototype ?. constructor ?? type ;
174201 const instance = new type ( ... injectServices ) ;
175202 this . map . set ( key , instance ) ;
176203 instance [ serviceProvider ] = this ;
@@ -180,6 +207,7 @@ export class ServiceProvider implements IDisposable {
180207 }
181208 // initialize properties...
182209 this . resolveProperties ( instance , type ) ;
210+ newServiceTarget = old ;
183211 return instance ;
184212 }
185213
@@ -264,9 +292,9 @@ export default function Inject(target, key, index?: number): any {
264292
265293 const pType = ( Reflect as any ) . getMetadata ( "design:type" , target , key ) ;
266294 ( target [ injectServiceKeysSymbol ] ??= { } ) [ key ] = pType ;
267- Object . defineProperty ( target , key , {
295+ const descriptor = {
268296 get ( ) {
269- const result = ServiceProvider . resolve ( this , pType ) ;
297+ const result = ServiceProvider . resolve ( newServiceTarget ?? this , pType ) ;
270298 // get is compatible with AtomWatcher
271299 // as it will ignore getter and it will
272300 // not try to set a binding refresher
@@ -276,9 +304,9 @@ export default function Inject(target, key, index?: number): any {
276304 return result ;
277305 } ,
278306 configurable : true
279- } ) ;
280-
281-
307+ } ;
308+ Object . defineProperty ( target , key , descriptor ) ;
309+ return descriptor ;
282310}
283311
284312export function Register ( kind : ServiceKind , factory ?: ( sp : ServiceProvider ) => any ) {
0 commit comments