thiagobustamante / typescript-ioc

A Lightweight annotation-based dependency injection container for typescript.
MIT License
526 stars 64 forks source link

Constructor injection with inheritance not working as expected #75

Open XaeroDegreaz opened 4 years ago

XaeroDegreaz commented 4 years ago

"typescript-ioc": "^3.2.2"

export abstract class BaseRepository<T extends BaseModel> {
  protected readonly collection: Collection<T>

  constructor( @Inject private readonly connectionManager: ConnectionManager )
  {
    //# Weird -- Why can't I inject this in this constructor, instead?
    //const connectionManager = Container.get( ConnectionManager );

    //TypeError: Cannot read property 'db' of undefined
    this.collection = this.connectionManager.db.collection( this.getCollectionName() )
  }

  abstract getCollectionName(): string;
}

@Singleton
export class TileRepository extends BaseRepository<Tile> {
  getCollectionName()
  {
    return 'tiles';
  }

  test()
  {

    console.log( this.collection.collectionName );
  }
}

I've tried several variations of the constructor including a simple @Inject connectionManager: ConnectionManager to no avail. I've also tried field injection, and that didn't work, but I suspect that information wouldn't be available in the constructor anyhow.

If I add a constructor in TileRepository and @Inject the ConnectionManager, then pass it to super() it will work, but I don't want to lead that implementation detail.

jlurbe commented 3 years ago

Almost the same here. Same version of typescript-ioc.

import { Get, Route } from "tsoa";
import { Inject, Singleton } from "typescript-ioc";

@Singleton
class Katana {
    public hit() {
        return "cut!";
    }
}

@Singleton
class Shuriken {
    public throw() {
        return "hit!";
    }
}

@Singleton
@Route('/ninja')
export class NinjaController {

    private _katana: Katana;
    private _shuriken: Shuriken;

    constructor(@Inject katana: Katana, @Inject shuriken: Shuriken) {
        this._katana = katana;
        this._shuriken = shuriken;
    }

    @Get('/fight')
    public fight() { return this._katana.hit(); };
    @Get('/sneak')
    public sneak() { return this._shuriken.throw(); };

}