CKGrafico / inversify-props

Wrapper of Inversify to inject your dependencies in the components, made with TypeScript and compatible with Vue, React and other component libraries.
MIT License
85 stars 9 forks source link

[Question] Is there a way to pass parameters to a concrete type when registering? #44

Open amura11 opened 3 years ago

amura11 commented 3 years ago

Assuming I have the following:

interface IMyService {
    doTheThing(): void;
}

class MyService extends IMyService {
     constructor(baseUrl: string) {
        this.baseUrl = baseUrl;
    }

    doTheThing(): void {
        //Do something here
    }

    private baseUrl!: string;
}

Is there a way to pass baseUrl when registering MyService with the container? Something like: container.addTransient<IMyService>(() => new MyService("BaseUrl"));? Coming from C# this is typically how it's done so I might just be approaching this completely wrong.

I want to set baseUrl at the time of registering as it will change depending on the environment.

CKGrafico commented 3 years ago

Hello and thanks for your question, if you want to pass the same baseUrl to all the instances of your service I think the good practise (in inversify) is to use a Factory https://github.com/inversify/InversifyJS/blob/master/wiki/factory_injection.md

If you want to have different baseUrl for each instance I usually create another method instead of passing to the constructor.

Please confirm, that this helped you and have a nice day.

amura11 commented 3 years ago

Would it be possible to extend the container with something like:

class CustomContainer extends Container {
    public addDynamicTransient<T>(constructor: Constructor<T>, func: () => T): interfaces.BindingWhenOnSyntax<T> {
        const id = generateIdAndAddToCache(constructor);
        this.decorateCatchable(injectable(), constructor);

        return super.bind<T>(id).toDynamicValue(func).inTransientScope();
    }
}

const container = new CustomContainer();

container.addDynamicTransient<IMyService>(MyService, () => new MyService("BaseUrl"));

I tried exactly this but I get an error that no bindings were found

CKGrafico commented 3 years ago

Why are you extending the container and not using as factory?