The main goal of nameko is to make it easy for developers to write services. A secondary goal is to make it easy for developers to write injection and entry providers to support the first goal.
The current implementation has some shortcomings with respect to the first
goal. It just doesn't play well with code analysis tools due to the injection
magic.
class FoobarService(object):
db = db_session(...)
@rpc
def shrub(self):
# should auto-complete in editors that support it
# should not complain when running flake8 or
# similar code analysis tools
self.db.quer...
# should show the same help as if being inside the shrub()
# method and calling help(self.db)
help(FoobarService.db)
I propose we remove the factory functions for injeciton providers and adopt
a different protocol to declare and manage injections.
class FoobarService(object):
db = DbSession(...)
...
The first step is to declare injections via prototypes.
The prototypes are instances of the same type as the objects being injected
during a worker life-cycle. This will get rid of the issue we currently have
with code analysis tools. Additionally it is more consistent when reading
the code.
We now have a new challenge, the life-cycle management of the injection.
For each running container we require a provider instance which generates
injection instances which are applied to a worker instances of the service
class.
We can associate an injection provider with the prototype via it's type,
using a decorator.
We can now build a map to allow a container to inspect a service class and infer
what provider class to use for a particular attribute (injection).
When a provider is instantiated it will be given the prototype to allow proper
initialization. We could also make it part of an existing or additional life-cycle
method. From there on it will behave the same way providers behave now.
A minimal implementation of the injection provider and helper API would look something like:
The main goal of nameko is to make it easy for developers to write services. A secondary goal is to make it easy for developers to write injection and entry providers to support the first goal.
The current implementation has some shortcomings with respect to the first goal. It just doesn't play well with code analysis tools due to the injection magic.
I propose we remove the factory functions for injeciton providers and adopt a different protocol to declare and manage injections.
The first step is to declare injections via prototypes. The prototypes are instances of the same type as the objects being injected during a worker life-cycle. This will get rid of the issue we currently have with code analysis tools. Additionally it is more consistent when reading the code.
We now have a new challenge, the life-cycle management of the injection. For each running container we require a provider instance which generates injection instances which are applied to a worker instances of the service class.
We can associate an injection provider with the prototype via it's type, using a decorator.
We can now build a map to allow a container to inspect a service class and infer what provider class to use for a particular attribute (injection). When a provider is instantiated it will be given the prototype to allow proper initialization. We could also make it part of an existing or additional life-cycle method. From there on it will behave the same way providers behave now.
A minimal implementation of the injection provider and helper API would look something like: