You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于YAML配置,使用Dependency Injector注入不同接口实现

基于YAML配置动态注入接口实现(dependency injector)

核心思路

通过配置文件指定实现类名称,结合dependency injector的Selector提供者或自定义工厂方法,从预定义的实现类注册表中动态选择并注入对应实例。

步骤1:编写YAML配置文件

在配置文件中明确指定要使用的实现类名称,例如:

配置文件1(使用Impl1):config_impl1.yaml

implementation:
  some_interface: Impl1

配置文件2(使用Impl2):config_impl2.yaml

implementation:
  some_interface: Impl2

步骤2:修改容器类实现动态选择

方法1:使用providers.Selector(推荐)

利用dependency injector内置的Selector提供者,根据配置值直接匹配对应的实现类,并用Singleton保证单例:

import abc
from dependency_injector import containers, providers

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

class Impl1(SomeInterface):
    def some_method(self):
        print("File-based implementation")

class Impl2(SomeInterface):
    def some_method(self):
        print("Service-based implementation")

class Container(containers.DeclarativeContainer):
    config = providers.Configuration(strict=True)

    # 实现类注册表:映射类名字符串到实际类
    _impl_registry = {
        "Impl1": Impl1,
        "Impl2": Impl2,
    }

    # 动态选择实现类并创建单例实例
    some_implementation = providers.Singleton(
        providers.Selector(
            config.implementation.some_interface,
            **_impl_registry
        )
    )

方法2:自定义工厂方法

如果需要更灵活的逻辑(比如参数处理、默认值),可以用工厂方法结合@providers.Singleton装饰器:

class Container(containers.DeclarativeContainer):
    config = providers.Configuration(strict=True)

    _impl_registry = {
        "Impl1": Impl1,
        "Impl2": Impl2,
    }

    @providers.Singleton
    def some_implementation(self) -> SomeInterface:
        # 从配置中获取实现类名称,注册表中匹配对应类
        impl_name = self.config.implementation.some_interface()
        impl_class = self._impl_registry.get(impl_name)
        if not impl_class:
            raise ValueError(f"Unsupported implementation: {impl_name}")
        return impl_class()

步骤3:加载配置并使用

保持原有的配置加载逻辑,获取实例时会自动根据配置选择对应实现:

# 加载Impl1的配置
container = Container()
container.config.from_yaml("config_impl1.yaml", required=True)
impl = container.some_implementation()
impl.some_method()  # 输出: File-based implementation

# 切换为Impl2的配置
container.config.from_yaml("config_impl2.yaml", required=True)
impl = container.some_implementation()
impl.some_method()  # 输出: Service-based implementation

注意事项

  • 注册表的键必须与YAML配置中的类名字符串完全一致(区分大小写)。
  • 如果需要给实现类的构造函数传递依赖,可以在Selector中添加参数,或在工厂方法中从容器获取其他服务。
  • 若配置中指定的实现类不在注册表中,可添加默认值或异常处理逻辑,避免程序崩溃。

内容的提问来源于stack exchange,提问作者David Clarke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:45:35