Inject different implementation based on yaml configuration

Question:

Using python package dependency injector, I need to instantiate/inject a different implementation of an interface based on a yaml configuration file.

class SomeInterface(abc.ABC):
    @abc.abstractmethod
    def some_method(self):
        pass

class Impl1(SomeInterface):
    def some_method(self):
        # e.g. file-based implementation

class Impl2(SomeInterface):
    def some_method(self):
        # e.g. service-based implementation

I have different yaml configuration files for the different implementations and I want the container to return/inject the appropriate implementation based on the config file. So using dependency injector package, I’ve created a container:

class Container(containers.DeclarativeContainer):

    config = providers.Configuration(strict=True)

    some_implementation = provider.Singleton(Impl1) # <- how to vary this based on config?

And I load the yaml config file passed in:

container = Container()
container.config.from_yaml(config_yaml_file, required=True)

It’s not obvious to me how to vary which implementation is injected based on the configuration file passed in to the container.

Asked By: David Clarke

||

Answers:

Ok never mind, of course it’s in the docs. There are a number of approaches but in my case the Selector provider matches the code I’m refactoring:

class Container(containers.DeclarativeContainer):

    config = providers.Configuration()

    selector = providers.Selector(
        config.one_or_another,
        one=providers.Factory(Impl1),
        another=providers.Factory(Impl2),
    )
Answered By: David Clarke