【问题标题】:Unable to get nameko-injector Python package to work无法让 nameko-injector Python 包工作
【发布时间】:2020-06-19 06:06:05
【问题描述】:

我正忙于使用 Nameko 在 Python 中编写微服务后端。在寻找一个好的依赖注入包时,我遇到了 Injector。我真的很喜欢它,想和 Nameko 一起使用。然后我注意到了一个小问题:Nameko 实例化了 worker,并且不能使用开箱即用的依赖注入包。在尝试使用文档使其工作后,我偶然发现了包nameko-injector。我喜欢这个概念并尝试实现它,但我得到了错误:

参数“绑定”未填充

使用 git 存储库中的示例代码(如下所示),问题发生在 NamekoInjector 类的初始化时。

微服务工作者类:

from nameko.rpc import rpc
from services.order_service import OrderService
from nameko_injector.core import NamekoInjector

INJECTOR = NamekoInjector()


@INJECTOR.decorate_service
class OrderWorker:

    # Mandatory field for service discovery
    name = "order_worker"

    def __init__(self, service: OrderService):
        self.service = service

    @rpc
    def get_orders(self):
        return self.service.orders()

OrderService 类:

from models.order.order import Order


class OrderService(object):

    def __init__(self):
        self.orders = [Order(1), Order(2)]

    def get_users(self):
        return self.orders

订单类:

class Order:
    def __init__(self, orderid):
        self.orderid = orderid

    def __str__(self):
        return str(self.orderid)

在查看 NamekoInjector 类时,我无法找出绑定的确切作用和使用时间。首先,我什至不需要它,但是当我删除 NamekoInjector 类中的绑定字段和其他用法时,它仍然不起作用。有人可以帮我吗?谢谢!

【问题讨论】:

    标签: python dependency-injection microservices nameko


    【解决方案1】:

    我意识到它已经晚了,但也许仍然相关。 您已经非常接近解决方案了。

    缺失的部分:

    • 传递给NamekoInjectorconfigure 函数。它告诉库如何创建依赖项、它们的范围等。
    • 必须在入口点上指定依赖项,而不是在工作类初始化程序中。

    我对您的代码进行了一些修改并将其放在一个模块中,但您可以随意组织代码。我这样做是为了简单。

    下面的代码应该按原样工作。我还包括了一些帮助我运行项目的部分。

    import injector
    from nameko.rpc import rpc
    from nameko_injector.core import NamekoInjector
    
    class Order:
        def __init__(self, orderid):
            self.orderid = orderid
    
        def __str__(self):
            return str(self.orderid)
    
    class OrderService(object):
    
        def __init__(self):
            self.orders = [Order(1), Order(2)]
    
        def get_orders(self):
            return self.orders
        
    class Calculator:
        # class to demonstrate transitive dependency
        def __init__(self, randomiser):
            self.__randomiser = randomiser
    
        def calculate(self):
            return self.__randomiser()
    
    # I usually keep the providers in the same place with the provided
    @injector.provider
    def provide_calculator() -> Calculator:
        # simple function that initialises one dependency
        return Calculator(randomiser=lambda: 42)
    
        
    class ComplexInitService:
        """Service with own dependencies."""
        # the service to demonstrate providers.
        
        def __init__(self, calculator: Calculator):
            self.__calculator = calculator
      
        def calculate(self):
            return self.__calculator.calculate()
    
    @injector.provider
    def provide_complex_service(calculator: Calculator) -> ComplexInitService:
        return ComplexInitService(calculator)
    
    def configure(binder):
        # function that tells the framework how to create a dependency based on the requested type
        # in the RPC/HTTP endpoint
        binder.bind(Calculator, to=provide_calculator)
        binder.bind(ComplexInitService, to=provide_calculator)
        
    INJECTOR = NamekoInjector(configure)
    
    @INJECTOR.decorate_service
    class OrderWorker:
    
        # Mandatory field for service discovery
        name = "order_worker"
    
        @rpc
        def get_orders(self, service: OrderService):
            return [order.orderid for order in service.get_orders()]
        
        @rpc
        def calcualte_complex_stuff(self, service: ComplexInitService):
            return service.calculate()
    

    我使用下面的sn-ps来初始化项目

    rm pyproject.toml poetry.lock
    poetry init \
    --name nameko-injector-demo \
    --no-interaction \
    --dependency 'nameko-injector:1.1.2'
    # poetry install
    

    Nameko 配置示例

    AMQP_URI: 'amqps://user:password@vhots.rmq.cloudamqp.com/vhost'
    rpc_exchange: 'nameko-rpc'
    max_workers: 10
    parent_calls_tracked: 10
    

    运行服务

    poetry run nameko run --config config.yml service:OrderWorker
    

    nameko shell测试

    poetry run nameko shell --config config.yml
    Nameko Python 3.8.9 (default, May 13 2021, 00:13:06)
    [Clang 7.1.0 (tags/RELEASE_710/final)] shell on darwin
    Broker: amqps://user:password@crow.rmq.cloudamqp.com/vhost (from --config)
    >>> n.rpc.order_worker.get_orders()
    [1, 2]
    >>> n.rpc.order_worker.calcualte_complex_stuff()
    42
    

    【讨论】:

    • 顺便说一句,我会在 nameko-injector 问题上分享这个问题,以获得更快的答案。
    猜你喜欢
    • 1970-01-01
    • 2021-07-21
    • 2021-05-29
    • 2018-10-27
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 2018-05-11
    相关资源
    最近更新 更多