How do I register Transients in Aurelia v2?

Since the Aurelia 2 beta is out, I started to check if I can manage to port my Aurelia 1 applications to the beta. I am struggling to say the least. For now I am already stuck on registering transients for DI.

In Aurelia 1, I registered my clients like this.

const clients = [
    Client1,
    Client2,
    // etc
];

for (const t of clients) {
    aurelia.container.registerTransient(t, () => {
        const type = new t(
            {
                accessToken: () => 'accessToken'
                // rest of config
            },
            'client-endpoint'
        );
        return type;
    });
}

For Aurelia 2, I am trying to register it like this:

const container = DI.createContainer();
const clients = [
    Client1,
    Client2,
    // etc
];


for (const t of clients) {
    container.register(
        Registration.transient(t, () => 
           new t(
                {
                   accessToken: () => 'accessToken'
                   // rest of config
                },
                'client-endpoint'
            );
        })
    );
}

Which gives me the error:

TS2345: Argument of type '() => Client1 | Client2 | etc.' is not assignable to parameter of type 'Constructable<{}>'.
  Type '() => Client1, Client2 | etc. provides no match for the signature 'new (...args: any[]): {}'.

I tried using the Registration.callback instead, which gives me no compile errors. But when calling an instance from DI doesn’t seem to provide an instance with the provided config in the constructor when registering it.

@inject(Client1)
export class MyApp {
    constructor(
        private readonly clientApi: Client1 //
    ) {}

    public async attached(): Promise<void> {
        const client = await this.clientApi.getAuthenticated();
        console.log(client);
    }
}

When I try to use Client1 it should have to config configured (which the clientApi.getAuthenticated() uses) but it gives the error:

 Cannot read properties of undefined (reading 'accessToken')

which means the config is not provided when constructing the Client one.

Callback is indeed what you want to use here as transient will construct the class for you injecting things appropriately.

For your error can you provide more details? Maybe a small repo on stackblitz?

Hi @dtaalbers!

If you want to register transient, then all you need to do is to use the @transient decorator. You can explicitly register a transient resolver using Registration.transient(Client1, Client1). An example will look something like the following

new Aurelia()  // or use the static API, if that's preferred to you.
  .register(Registration.transient(Client1, Client1))

For more details, please refer to the documentations:

In case these don’t help to resolve your issues, please share a reproduction. You can easily do so by forking this StackBlitz project.

1 Like

Hi @brandonseydel & @Sayan751,

Thank you for your responses. I would love to provide you with a reproduction but I am using (compiled) libraries (the Client1 and Client2 etc) which are private and that is why I can’t use them in reproductions. And that is why I also can’t use decorators I’m afraid. So I guess Registration.transient is out of the question since I need to construct the client on the fly.

I guess that is why you’d use Registration.callback. But like I said, I don’t have compile errors which is good. I also get a Client instance when injecting into a constructor, but it doesn’t seem to construct the client with the config.

@brandonseydel @Sayan751 I managed to get a slimmed down reproduction for you after all. I’ve send it to both of you via DM.

Thank you for any help in advance!

Hi @dtaalbers! Responded you on DM. Just for completeness, I am also posting the solution here.

The issue was that you were creating a separate container which has nothing to do with the aurelia instance. Ideally, you need to use the same container from the aurelia instance. To this end, you can use the friendly Aurelia#register API, as shown in my previous comment.

1 Like

Hi @Sayan751 ,

Thank you for looking into this for me! I will try it out as soon I have time to look into the Aurelia 2 upgrade and I’ll come back to you!