Skip to content

Bind a provider to multiple interfaces? #205

@bo-at-work

Description

@bo-at-work

Hello Alec & open source contributors - I love this library - it feels very well designed and strikes a sweet spot between complexity / ease of use. However, I am running into a little bit of a snag and was wondering if anyone else came across this problem:

I currently have some helper provider modules that specify how to provide for a certain interface type (this is defined as a class member on modules that I wanted to bind DI to):

class _ModuleProvider(Module):
    @singleton
    @provider
    def provide_base(self, context : Context, config: Configuration) -> BaseType:
        return DerivedType(context, **config)

I dynamically load all modules and then add these to the provider container:

provider_containers = [config_provider]

# register all providers
for component in component_classes:
    # all modules should implement this provider class
    assert hasattr(
        component, "_ModuleProvider"
    ), "Component {} does not define a provider".format(component.__name__)
    provider_containers.append(component._ModuleProvider())

# later on
injector = Injector(provider_containers, auto_bind=False) # note I disabled autobind here
pipeline = injector.get(Pipeline)

However, some Pipeline implementations might have stricter requirements on the interface type so their constructor might take a DerivedType directly.

I currently work around this by declaring another provider

class _ModuleProvider(Module):
    @singleton
    @provider
    def provide_base(self, context : Context, config: Configuration) -> BaseType:
        return DerivedType(context, **config)

    @singleton
    @provider
    def provide_derived(self, context : Context, config: Configuration) -> DerivedType:
        return DerivedType(context, **config)

But I was just wondering if it's possible to do this:

class _ModuleProvider(Module):
    @singleton
    @provider
    def provide_derived(self, context : Context, config: Configuration) -> Union[BaseType, DerivedType]:
        return DerivedType(context, **config)

If there's a better way than what I was doing, I'd appreciate it too. Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions