deepkit / deepkit-framework

A new full-featured and high-performance TypeScript framework
https://deepkit.io/
MIT License
3.18k stars 121 forks source link

DI: Undefined dependency "context: InjectorContext" #597

Open Murzbul opened 1 month ago

Murzbul commented 1 month ago

Hi!

I have some tests with the InjectorContext and InjectorModule.

I've tested the docs example to inject the InjectorContext but it doesn't work.

class Database
{

}

class MyService
{
      constructor(protected context: InjectorContext)
     {
         console.log('MyService');
     }

     getDatabase(): Database
     {
          return this.context.get(Database);
     }
}

const rootModule = new InjectorModule([
      { provide: Database, useClass: Database },
      { provide: MyService, useClass: MyService }
]);

const injector = new InjectorContext(rootModule);

console.log('injector.get(MyService)');
console.log(injector.get(MyService));

This is the error.

 /home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/injector.js:616
            throw new DependenciesUnmetError(`Undefined dependency "${options.name}: ${type}" of ${of}. Type has no provider${fromScope ? ' in scope ' + fromScope : ''}.`);
                  ^

DependenciesUnmetError: Undefined dependency "context: InjectorContext" of MyService(?). Type has no provider.
    at Injector.createFactoryProperty (/home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/injector.js:616:19)
    at Injector.createFactory (/home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/injector.js:461:32)
    at Injector.buildProvider (/home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/injector.js:368:28)
    at Injector.build (/home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/injector.js:311:37)
    at new Injector (/home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/injector.js:210:14)
    at InjectorModule.getOrCreateInjector (/home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/module.js:444:25)
    at InjectorContext.getInjector (/home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/injector.js:834:23)
    at InjectorContext.get (/home/node/node_modules/.pnpm/@deepkit+injector@1.0.1-alpha.153_@deepkit+core@1.0.1-alpha.147_@deepkit+type@1.0.1-alpha.153/node_modules/@deepkit/injector/dist/cjs/src/injector.js:818:31)
    at /home/node/dist/src/index.js:47:30
    at Object.<anonymous> (/home/node/dist/src/index.js:108:3)

Node.js v21.7.0

I don't know if there is a bug or if I have a mistake understanding here with the docs.

marcj commented 1 month ago

InjectorContext is not available in the low level API. It is only available in the App abstraction of @deepkit/app.

As a side note: if your MyService needs Database, you should just reference Database in the constructor instead of using the InjectorContext. InjectorContext is only necesary to either delay intantiation or load services dynamically. You should try to stay away from it to not tightly couple your code too much to the DI container or use the DI container as metasystem

Murzbul commented 1 month ago

Thank you very much for the message.

In reality, it is a mere example.

What I would like to build is a SimpleCQRS.

So I need some way to get the context to add the handlers.

The idea is to create a simple module.

For example

export const CqrsModule = new InjectorModule([
    {provide: CommandBus, useClass: SimpleCommandBus},
    { provide: QueryBus, useClass: SimpleQueryBus }
]).forRoot();

As a first module.

Then add another module and get the SimpleCommandBus to add the corresponding handlers.