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.
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),
)
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.
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),
)