Dependency Injection with Generic class

Hello Aurelia community. I havn’t been here in a while, I used to be joined in on the live chat, but apparantly discourse for aurelia has moved into a forum-like form now, verry nice!

I have a question regarding dependency injection and typescript generic classes. Obviously, I am using Aurelia with Typescript (and webpack, started an Aurelia project via au new).

I have a class:

     export class DeviceManager<TPosition>
    {
         private devices: Device<TPosition>[];
     
         constructor()
         {
             this.devices = [];
         }
     
         public addDevice(name: string, id: string,position: TPosition)
         {
             if (this._devices.some(x=> x.id === id))
                 throw Error("Device with the provided id already exists, id must be unique");
     
             this._devices.push(<Device<TPosition>>{
                 name: name,
                 id: id,
                position: position
            });
       }
    }

Now TPosition can become either a GpsPosition or a CarthesianPosition. I have 2 ViewModels which depend on my DeviceManager. ViewModel1 that has a DeviceManager<GpsPosition> in its constructor and ViewModel2 with a DeviceManager<CarthesianPosition> in its constructor.

Now with Dependency Injection, I want ViewModel1 to get the 1 singleton DeviceManager<GpsPosition>and ViewModel2 to get the 1 singleton (but different from DeviceManager<GpsPosition>) DeviceManager<CarthesianPosition>.

When trying to register singletons myself:

aurelia.container.registerSingleton(DeviceManager<CarthesianPosition>, DeviceManager<CarthesianPosition>); This does not work because the <> are not allowed.

How would i go about achieving my goal here?

1 Like

.registerSingleton does not care about generic, it’s just TS contract. You can just do

aurelia.container.registerSingleton(DeviceManager, DeviceManager);

If you want to register different types of DeviceManager, you can make non-generic versions of them like this:

class DMGpsPosition extends DeviceManager<GpsPosition> {
}

class DMCarthesianPosition extends DeviceManager<CarthesianPosition> {
}

aurelia.container.registerSingleton(DMGpsPosition, DMGpsPosition);
2 Likes

Yes, this is also what I had in mind myself. I don’t really like this since I would have to make classes for every possible type of Position, but i think there is no other option then.

1 Like