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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions