@lppedd/di-wise-neo 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -476,7 +476,7 @@ In this example, `ExtensionContext` will be registered with **Resolution** scope
476
476
  Enables automatic registration of the decorated class if it has not been registered explicitly.
477
477
 
478
478
  ```ts
479
- @AutoRegister()
479
+ @AutoRegister
480
480
  export class ExtensionContext {
481
481
  /* ... */
482
482
  }
@@ -485,6 +485,24 @@ export class ExtensionContext {
485
485
  container.resolve(ExtensionContext);
486
486
  ```
487
487
 
488
+ ### `@EagerInstantiate`
489
+
490
+ Marks a class for eager instantiation when registered with **Container** scope.
491
+
492
+ This causes the container to immediately create and cache the instance of the class
493
+ at registration time, instead of deferring instantiation until the first resolution.
494
+
495
+ ```ts
496
+ @EagerInstantiate
497
+ @Scoped(Scope.Container)
498
+ export class ExtensionContext {
499
+ /* ... */
500
+ }
501
+
502
+ // The container immediately creates and caches the instance
503
+ container.register(ExtensionContext);
504
+ ```
505
+
488
506
  ## Testing support
489
507
 
490
508
  Testing is an important part of software development, and dependency injection is meant to make it easier.
@@ -422,7 +422,7 @@ declare function createContainer(options?: Partial<ContainerOptions>): Container
422
422
  *
423
423
  * @example
424
424
  * ```ts
425
- * @AutoRegister()
425
+ * @AutoRegister
426
426
  * class Wizard {}
427
427
  *
428
428
  * const wizard = container.resolve(Wizard);
@@ -431,7 +431,28 @@ declare function createContainer(options?: Partial<ContainerOptions>): Container
431
431
  *
432
432
  * @__NO_SIDE_EFFECTS__
433
433
  */
434
- declare function AutoRegister(enable?: boolean): ClassDecorator;
434
+ declare function AutoRegister<Ctor extends Constructor<any>>(Class: Ctor): void;
435
+
436
+ /**
437
+ * Class decorator that enables eager instantiation of a class when it is registered
438
+ * in the container with `Scope.Container`.
439
+ *
440
+ * This causes the container to immediately create and cache the instance of the class,
441
+ * instead of deferring instantiation until the first resolution.
442
+ *
443
+ * @example
444
+ * ```ts
445
+ * @EagerInstantiate
446
+ * @Scoped(Scope.Container)
447
+ * class Wizard {}
448
+ *
449
+ * // A Wizard instance is immediately created and cached by the container
450
+ * const wizard = container.register(Wizard);
451
+ * ```
452
+ *
453
+ * @__NO_SIDE_EFFECTS__
454
+ */
455
+ declare function EagerInstantiate<Ctor extends Constructor<any>>(Class: Ctor): void;
435
456
 
436
457
  interface TokensRef<Value = any> {
437
458
  readonly getRefTokens: () => Set<Token<Value>>;
@@ -826,5 +847,5 @@ interface Middleware {
826
847
  */
827
848
  declare function applyMiddleware(container: Container, middlewares: Middleware[]): Container;
828
849
 
829
- export { AutoRegister, Inject, InjectAll, Injectable, Injector, Optional, OptionalAll, Scope, Scoped, applyMiddleware, build, createContainer, createType, forwardRef, inject, injectAll, injectBy };
850
+ export { AutoRegister, EagerInstantiate, Inject, InjectAll, Injectable, Injector, Optional, OptionalAll, Scope, Scoped, applyMiddleware, build, createContainer, createType, forwardRef, inject, injectAll, injectBy };
830
851
  export type { ClassProvider, Constructor, Container, ContainerOptions, ExistingProvider, FactoryProvider, Middleware, MiddlewareComposer, Provider, RegistrationOptions, Token, TokenRef, Tokens, TokensRef, Type, ValueProvider };
package/dist/cjs/index.js CHANGED
@@ -496,15 +496,16 @@ function isDisposable(value) {
496
496
  if (args.length == 1) {
497
497
  const Class = args[0];
498
498
  const metadata = getMetadata(Class);
499
- // Register the class itself
500
- this.myTokenRegistry.set(Class, {
499
+ const registration = {
501
500
  // The provider is of type ClassProvider, initialized by getMetadata
502
501
  provider: metadata.provider,
503
502
  options: {
504
- scope: metadata.scope
503
+ scope: metadata.scope ?? this.myOptions.defaultScope
505
504
  },
506
505
  dependencies: metadata.dependencies
507
- });
506
+ };
507
+ // Register the class itself
508
+ this.myTokenRegistry.set(Class, registration);
508
509
  // Register the additional tokens specified via class decorators.
509
510
  // These tokens will point to the original Class token and will have the same scope.
510
511
  for (const token of metadata.tokensRef.getRefTokens()){
@@ -514,21 +515,29 @@ function isDisposable(value) {
514
515
  }
515
516
  });
516
517
  }
518
+ // Eager-instantiate only if the class is container-scoped
519
+ if (metadata.eagerInstantiate && registration.options?.scope === Scope.Container) {
520
+ this.resolve(Class);
521
+ }
517
522
  } else {
518
523
  const [token, provider, options] = args;
519
524
  if (isClassProvider(provider)) {
520
- const Class = provider.useClass;
521
- const metadata = getMetadata(Class);
522
- this.myTokenRegistry.set(token, {
525
+ const metadata = getMetadata(provider.useClass);
526
+ const registration = {
523
527
  provider: metadata.provider,
524
528
  options: {
525
529
  // The explicit registration options override what is specified
526
530
  // via class decorators (e.g., @Scoped)
527
- scope: metadata.scope,
531
+ scope: metadata.scope ?? this.myOptions.defaultScope,
528
532
  ...options
529
533
  },
530
534
  dependencies: metadata.dependencies
531
- });
535
+ };
536
+ this.myTokenRegistry.set(token, registration);
537
+ // Eager-instantiate only if the provided class is container-scoped
538
+ if (metadata.eagerInstantiate && registration.options?.scope === Scope.Container) {
539
+ this.resolve(token);
540
+ }
532
541
  } else {
533
542
  if (isExistingProvider(provider)) {
534
543
  assert(token !== provider.useExisting, `the useExisting token ${token.name} cannot be the same as the token being registered`);
@@ -825,7 +834,7 @@ function isDisposable(value) {
825
834
  *
826
835
  * @example
827
836
  * ```ts
828
- * @AutoRegister()
837
+ * @AutoRegister
829
838
  * class Wizard {}
830
839
  *
831
840
  * const wizard = container.resolve(Wizard);
@@ -833,11 +842,32 @@ function isDisposable(value) {
833
842
  * ```
834
843
  *
835
844
  * @__NO_SIDE_EFFECTS__
836
- */ function AutoRegister(enable = true) {
837
- return function(Class) {
838
- const metadata = getMetadata(Class);
839
- metadata.autoRegister = enable;
840
- };
845
+ */ function AutoRegister(Class) {
846
+ const metadata = getMetadata(Class);
847
+ metadata.autoRegister = true;
848
+ }
849
+
850
+ /**
851
+ * Class decorator that enables eager instantiation of a class when it is registered
852
+ * in the container with `Scope.Container`.
853
+ *
854
+ * This causes the container to immediately create and cache the instance of the class,
855
+ * instead of deferring instantiation until the first resolution.
856
+ *
857
+ * @example
858
+ * ```ts
859
+ * @EagerInstantiate
860
+ * @Scoped(Scope.Container)
861
+ * class Wizard {}
862
+ *
863
+ * // A Wizard instance is immediately created and cached by the container
864
+ * const wizard = container.register(Wizard);
865
+ * ```
866
+ *
867
+ * @__NO_SIDE_EFFECTS__
868
+ */ function EagerInstantiate(Class) {
869
+ const metadata = getMetadata(Class);
870
+ metadata.eagerInstantiate = true;
841
871
  }
842
872
 
843
873
  function forwardRef(token) {
@@ -1065,6 +1095,7 @@ function OptionalAll(token) {
1065
1095
  }
1066
1096
 
1067
1097
  exports.AutoRegister = AutoRegister;
1098
+ exports.EagerInstantiate = EagerInstantiate;
1068
1099
  exports.Inject = Inject;
1069
1100
  exports.InjectAll = InjectAll;
1070
1101
  exports.Injectable = Injectable;