@autoinject and @optional

Is it allowed to use @autoinject and @optional together?If yes, is this the correct syntax?

@autoinject
export class MyService implements IMyService
{
	constructor(
		@optional()
		private dependency: IOptionalDependency)
	{
	}
}

This leads to the following error: key/value cannot be null or undefined. Are you trying to inject/register something that doesn’t exist with DI

1 Like

Are you trying to use an interface as type there? Since that resolves to nothing after compilation that might cause your troubles.

1 Like

No, it’s an abstract class!

public abstract class IOptionalDependency
{
    // ...
}
1 Like

@elitastic So I hope you don’t mind me asking a separate question, but related I think for my own knowledge purposes.

What does @optional provide over a default parameter value?
Wouldn’t this be equivalent and less boilerplate? (no import, etc…)

constructor(private dependency: IOptionalDependency = undefined)

1 Like

Optional makes sure that only an injection happens if the corresponding key is already in the container. So in your case the autoinject would eagerly resolve and the default param is useless

Edit: sry was meant as a reply to @airboss001

1 Like

So, just for my own clarity, and restating it to make sure I have it right.

The container is the Aurelia default DI container.
@optional will only use an existing DI container object, and would not instantiate a new one.
@autoinject would have replaced any default constructor parameter values and they would never be seen. So if you actually wanted some default values, you would not want to use @autoinject.

How does that work in Aurelia 2 with its constructor having DI without using @autoinject?

2 Likes

From the docs (v1) https://aurelia.io/docs/fundamentals/dependency-injection#resolvers

If using TypeScript, keep in mind that @autoinject won’t allow you to use Resolvers (that is optional, lazy and others)

2 Likes

Autoinject merely makes sure that metadata is present with the emitMetadata tsconfig for the given class. Actually any decorator will do so, see v2 docs
https://docs.aurelia.io/app-basics/dependency-injection

Note The secret of TypeScript’s metadata generation is that any decorator on the class will cause the compiler to include the metadata. You don’t have to use the inject decorator specifically.

In v2 it should behave similarly with same drawbacks of no resolvers in this case. There are new benefits of being able to use Interfaces as keys though, through use of declaration merges with Symbols, which in itself is really a killer feature

2 Likes

inoveryourhead-small
Right, right, for sure, ummm…totally agree.

1 Like

Thanks for all your great help!

1 Like