Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding inside a factory method #1414

Open
1b0x opened this issue Dec 29, 2021 · 2 comments
Open

Binding inside a factory method #1414

1b0x opened this issue Dec 29, 2021 · 2 comments

Comments

@1b0x
Copy link

1b0x commented Dec 29, 2021

Hello there,
I have a question about this piece of code:

This is how my factory looks like. As you can see I'm binding/unbinding some classes inside this factory method.

export function SceneFactory(context: interfaces.Context) {
    return (key: string, scene: any) => {
        // Unbind the scene if it exists
        if (context.container.isBound(key)) {
            context.container.unbind(key);
        }
       
        // Bind the new scene class
        context.container.bind<IScene>(key).to(scene);
        return context.container.get<IScene>(key);
    };
}

I'm using it like that:

@injectable()
export class SceneManager implements ISceneManager {
    scenes: IScene[];

    constructor(
        @inject(ISceneFactory)
        protected sceneFactory: (key: string, scene: any) => IScene
    ) { }

    add(key: string, scene: IScene) {
        const sceneInstance = this.sceneFactory(key, scene);

        this.scenes.push(sceneInstance);
    }
}

class SceneA extends Scene {}
class SceneB extends Scene {}
sceneManager.add('sceneA', SceneA);
sceneManager.add('sceneB', SceneB);

So, the question is:
Is it okay to bind/unbind classes in a factory method? Is it a good approach to do that?

@kyle-johnson
Copy link

A better approach is to create a child container in the factory. This way, the original container isn't modified:

export function SceneFactory(context: interfaces.Context) {
    return (key: string, scene: any) => {
        const childContainer = context.container.createChild();
       
        // Bind the new scene class (since this is bound in the child container, it will override any existing binds)
        childContainer.bind<IScene>(key).to(scene);
        return childContainer.get<IScene>(key);
    };
}

More info here: https://github.com/inversify/InversifyJS/blob/master/wiki/hierarchical_di.md

@1b0x
Copy link
Author

1b0x commented Jan 17, 2022

Thank you! I really appreciate it!

Is it good to create multiple child containers for other manager classes?
Let's say that If I have Sound Manager (which has SoundFactory), should I create a new child container?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

2 participants