Error injecting singletons in Aurelia 2

For testing purposes, I create a DI container like:

const container = DI.createContainer()

// This works
const numberValueConverter = container.get(NumberValueConverter)

But when I want to inject another value converter, which injects NumberValueConverter as well:

@inject(NumberValueConverter, IEventAggregator)
export class ByteFormatValueConverter extends AbstractLocaleValueConverter {
    constructor(
        private readonly _numberValueConverter:NumberValueConverter,
        eventAggregator:IEventAggregator
    ) {
        super(eventAggregator);
    }

It fails at this line

const bytesFormatValueConverter = container.get(ByteFormatValueConverter);

with an cryptic error message:

    AUR0003:NumberValueConverter

      16 | //container.makeGlobal();
      17 |
    > 18 | const numberValueConverter = container.get(NumberValueConverter);
         |                                        ^
      19 | numberValueConverter.getLocale()
      20 | // const bytesFormatValueConverter = numberValueConverter
      21 | const bytesFormatValueConverter = container.get(ByteFormatValueConverter);

      at createMappedError (node_modules/@aurelia/kernel/src/errors.ts:8:50)
      at Resolver.resolve (node_modules/@aurelia/kernel/src/di.ts:566:17)
      at Container.get (node_modules/@aurelia/kernel/src/di.container.ts:375:27)
      at Container.map (node_modules/@aurelia/kernel/src/di.container.ts:657:15)
          at Array.map (<anonymous>)
      at Factory.construct (node_modules/@aurelia/kernel/src/di.container.ts:626:55)
      at Resolver.resolve (node_modules/@aurelia/kernel/src/di.ts:569:96)
      at Container.get (node_modules/@aurelia/kernel/src/di.container.ts:371:29)
      at Object.<anonymous> (tests/value-converters/byte-format-value-converter.test.ts:18:40)
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
      at runJest (node_modules/@jest/core/build/runJest.js:404:19)
      at _run10000 (node_modules/@jest/core/build/cli/index.js:320:7)
      at runCLI (node_modules/@jest/core/build/cli/index.js:173:3)

You are getting AUR0003, which means Aurelia error code 0003, which means you have a cyclic dependency somewhere in NumberValueConverter. Maybe have a look at the class again?

For the crypticness error code, it can be solved by telling the test running to use the development build of Aurelia, similar to this section doc Errors | The Aurelia 2 Docs

Well, I have no circular references in NumberValueConverter.

ByteFormatValueConverter ā†’ AbstractLocaleValueConverter injects NumberValueConverter ā†’ AbstractLocaleValueConverter

This code works with @autoinject() of Aurelia 1.
See here: aurelia-components/tests/value-converters/byte-format-value-converter.test.ts at master Ā· telekom-mms/aurelia-components Ā· GitHub

ByteFormatValueConverter

NumberValueConverter

It works when I write:

@inject(IEventAggregator)
export class ByteFormatValueConverter extends AbstractLocaleValueConverter {
    private readonly _numberValueConverter = resolve(NumberValueConverter)
    constructor(eventAggregator:IEventAggregator) {
        super(eventAggregator);
    }

instead of (which is the most intuitive way, comming from Aurealia 1)

@inject(NumberValueConverter, IEventAggregator)
export class ByteFormatValueConverter extends AbstractLocaleValueConverter {
    constructor(
        private readonly _numberValueConverter:NumberValueConverter,
        eventAggregator:IEventAggregator
    ) {
        super(eventAggregator);
    }

That not very intuitive, what is the reason for that?

The following way does not work:

export class ByteFormatValueConverter extends AbstractLocaleValueConverter {
    constructor(
        private readonly _numberValueConverter = resolve(NumberValueConverter),
        eventAggregator:IEventAggregator = resolve(IEventAggregator)
    ) {
        super(eventAggregator);
    }

because both variables are type of EventAggregator then.

I donā€™t unterstand it at all.

This is no longer supported due to changes in decorators, see here (and here).

1 Like

That means, the documentation is outdated and wrong? Dependency injection (DI) | The Aurelia 2 Docs

@inject works, and is supported.
Can you try to create a repro based on this Aurelia app - conventions webpack - StackBlitz

Iā€™m trying here: Aurelia @inject test - StackBlitz but I get different errors now.

Would you mind to take a look @bigopon ? Iā€™m stuck, because this code works locally and I can only guess, if itā€™s typescript, ā€˜tsconfigā€™ or any other module.

  1. @mreiche I donā€™t see you import & register the value converter anywhere, so do this in your main.ts:
Aurelia.register(NumberValueConverter).app(...).start();
  1. And there seems to be missing abstract class type support for @inject decorator, so change to
@inject(IEventAggregator)
export class AbstractLocaleValueConverter {
  ...

for now.

  1. Also make sure you change target to es2022 in tsconfig.json

Both is present and I changed the target to ā€œes2022ā€. Still erroring. Do you see my changes?

Yes thatā€™s the 2nd point you need to change. Iā€™ve updated my post earlier to make it clearer

Now I unterstood. I canā€™t use @inject together with abstract class. Should we file a bug somewhere?