2

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.

David Clarke
  • 12,888
  • 9
  • 86
  • 116
  • Could this be a use for https://python-dependency-injector.ets-labs.org/providers/configuration.html#specifying-the-value-type ? with the `as_` callback mechanism? Ie you get “Impl1” string from yaml and your callback looks up the class and builds it? Just guessing. – JL Peyret Oct 26 '22 at 02:57

1 Answers1

0

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),
    )
David Clarke
  • 12,888
  • 9
  • 86
  • 116