SET001
SET001

Reputation: 11718

inversify: not injectable contrustor arguments

I have a Game class and a Multiplayer class which handle all network players stuff for defined game:

export interface Multiplayer{
    game: Game
    start()
}
export class WebSocketMultiplayer implements Multiplayer{
    constructor(public game: Game){}
    start(){}
}

inversify configuration:

container.bind<Game>('Game').to(BasicGame)
container.bind<Multiplayer>('Multiplayer').to(WebSocketMultiplayer)

now I want to create, configure and run game and after that - run multiplayer.

const game = kernel.get<Game>('Game')
game.run()
const multiplayer = kernel.get<Multiplayer>('Multiplayer')
multiplayer.start()

but how should I pass game instance into Multiplayer constructor? If I will use @inject in WebSocketMultiplayer constructor than it will create another game instance.

Temporary solution I'm using for now is to pass game instance in multiplayer start function

start(game: Game){
        this.game = game
}

but how it suppose to be done with Inversify?

Upvotes: 2

Views: 2344

Answers (1)

Remo H. Jansen
Remo H. Jansen

Reputation: 24979

You ca try a few things.

The first options is to use the inSingletonScope method:

container.bind<Game>('Game').to(BasicGame).inSingletonScope();

You can learn more about scope here.

The second option is to use a factory:

container.bind<Game>('Game').to(BasicGame);
container.bind<Multiplayer>('Multiplayer').to(WebSocketMultiplayer);

container.bind<() => Game>("GameFactory").toFactory<Game>((context: interfaces.Context) => {
    const game = context.container.get<Game>("Game");
    game.run();
    return () => game;
});

class WebSocketMultiplayer implements Multiplayer{
    public game: Game;
    constructor(@inject("GameFactory") gameFactory: () => Game){
        this.game = gameFactory();
    }
    start(){}
}

If game.run() is asynchronous then you will need an asynchronous factory (AKA provider).

Upvotes: 4

Related Questions