Browse Source

fix: prioritize inherited constructor

e22m4u 1 month ago
parent
commit
12aaac2c8c
3 changed files with 52 additions and 10 deletions
  1. 1 1
      dist/cjs/index.cjs
  2. 5 7
      src/service-container.js
  3. 46 2
      src/service-container.spec.js

+ 1 - 1
dist/cjs/index.cjs

@@ -112,7 +112,7 @@ var _ServiceContainer = class _ServiceContainer {
     if (!service && !isCtorRegistered && !inheritedCtor && this._parent && this._parent.has(ctor)) {
     if (!service && !isCtorRegistered && !inheritedCtor && this._parent && this._parent.has(ctor)) {
       return this._parent.get(ctor, ...args);
       return this._parent.get(ctor, ...args);
     }
     }
-    if (!service && !isCtorRegistered && inheritedCtor) {
+    if (!isCtorRegistered && inheritedCtor) {
       ctor = inheritedCtor;
       ctor = inheritedCtor;
     }
     }
     if (!service || args.length) {
     if (!service || args.length) {

+ 5 - 7
src/service-container.js

@@ -112,13 +112,11 @@ export class ServiceContainer {
     ) {
     ) {
       return this._parent.get(ctor, ...args);
       return this._parent.get(ctor, ...args);
     }
     }
-    // если
-    //   ни экземпляр сервиса (или экземпляр наследника),
-    //   ни указанный конструктор
-    // не зарегистрированы, но найден конструктор наследника,
-    // то для создания экземпляра будет использован найденный
-    // конструктор наследника
-    if (!service && !isCtorRegistered && inheritedCtor) {
+    // если указанный конструктор не зарегистрирован,
+    // но найден конструктор наследника, то для создания
+    // экземпляра будет использован данный конструктор
+    // наследника
+    if (!isCtorRegistered && inheritedCtor) {
       ctor = inheritedCtor;
       ctor = inheritedCtor;
     }
     }
     // если экземпляр сервиса не найден или переданы
     // если экземпляр сервиса не найден или переданы

+ 46 - 2
src/service-container.spec.js

@@ -174,7 +174,7 @@ describe('ServiceContainer', function () {
         expect(executed).to.be.eq(1);
         expect(executed).to.be.eq(1);
       });
       });
 
 
-      it('overrides the cached instance', function () {
+      it('overrides the cached instance when arguments provided', function () {
         let executed = 0;
         let executed = 0;
         const givenArgs = [];
         const givenArgs = [];
         class MyService extends Service {
         class MyService extends Service {
@@ -254,6 +254,28 @@ describe('ServiceContainer', function () {
           expect(res1).to.be.not.eq(res2);
           expect(res1).to.be.not.eq(res2);
         });
         });
 
 
+        it('should create an instance from a registered class that inherits the given not registered class', function () {
+          class ParentService extends Service {}
+          class ChildService extends ParentService {}
+          const container = new ServiceContainer();
+          container.add(ChildService);
+          const res1 = container.get(ParentService);
+          const res2 = container.get(ChildService);
+          expect(res1).to.be.instanceOf(ParentService);
+          expect(res2).to.be.instanceOf(ChildService);
+          expect(res1).to.be.eq(res2);
+        });
+
+        it('should create an instance from a given not registered class even its parent class is registered', function () {
+          class ParentService extends Service {}
+          class ChildService extends ParentService {}
+          const container = new ServiceContainer();
+          container.add(ParentService);
+          const res = container.get(ChildService);
+          expect(res).to.be.instanceOf(ParentService);
+          expect(res).to.be.instanceOf(ChildService);
+        });
+
         describe('when a container has a parent', function () {
         describe('when a container has a parent', function () {
           describe('when a parent container has a registered constructor', function () {
           describe('when a parent container has a registered constructor', function () {
             it('should prioritize its own existing instance when available', function () {
             it('should prioritize its own existing instance when available', function () {
@@ -470,7 +492,7 @@ describe('ServiceContainer', function () {
         expect(executed).to.be.eq(1);
         expect(executed).to.be.eq(1);
       });
       });
 
 
-      it('overrides the cached instance', function () {
+      it('overrides the cached instance when arguments provided', function () {
         let executed = 0;
         let executed = 0;
         const givenArgs = [];
         const givenArgs = [];
         class MyService {
         class MyService {
@@ -549,6 +571,28 @@ describe('ServiceContainer', function () {
           expect(res1).to.be.not.eq(res2);
           expect(res1).to.be.not.eq(res2);
         });
         });
 
 
+        it('should create an instance from a registered class that inherits the given not registered class', function () {
+          class ParentService {}
+          class ChildService extends ParentService {}
+          const container = new ServiceContainer();
+          container.add(ChildService);
+          const res1 = container.get(ParentService);
+          const res2 = container.get(ChildService);
+          expect(res1).to.be.instanceOf(ParentService);
+          expect(res2).to.be.instanceOf(ChildService);
+          expect(res1).to.be.eq(res2);
+        });
+
+        it('should create an instance from a given not registered class even its parent class is registered', function () {
+          class ParentService {}
+          class ChildService extends ParentService {}
+          const container = new ServiceContainer();
+          container.add(ParentService);
+          const res = container.get(ChildService);
+          expect(res).to.be.instanceOf(ParentService);
+          expect(res).to.be.instanceOf(ChildService);
+        });
+
         describe('when a container has a parent', function () {
         describe('when a container has a parent', function () {
           describe('when a parent container has a registered constructor', function () {
           describe('when a parent container has a registered constructor', function () {
             it('should prioritize its own existing instance when available', function () {
             it('should prioritize its own existing instance when available', function () {