mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-22 09:36:48 +03:00
Adding some drafts of @inject decorator docs
This commit is contained in:
parent
9d48044ea3
commit
405c579f7e
|
@ -1,8 +1,51 @@
|
||||||
Decorators
|
Decorators
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
Current section of *Objects* documentation describes several useful decorators.
|
||||||
|
|
||||||
@inject decorator
|
@inject decorator
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
``@inject`` decorator can be used for making *inline* dependency injections.
|
||||||
|
It *patches* decorated callable in such way that dependency injection will be
|
||||||
|
done before every call of decorated callable.
|
||||||
|
|
||||||
|
``@inject`` decorator takes only argument that is supposed to be an
|
||||||
|
``objects.injections.Injection`` instance.
|
||||||
|
|
||||||
|
Any Python object will be injected *as is*, except *Objects* providers,
|
||||||
|
that will be called to provide injectable value.
|
||||||
|
|
||||||
|
Below is an example of how Flask's view could be patched using ``@inject``
|
||||||
|
decorator:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
"""`@inject` decorator example."""
|
||||||
|
|
||||||
|
from objects.providers import NewInstance
|
||||||
|
|
||||||
|
from objects.injections import KwArg
|
||||||
|
from objects.injections import inject
|
||||||
|
|
||||||
|
|
||||||
|
new_object = NewInstance(object)
|
||||||
|
|
||||||
|
|
||||||
|
@inject(KwArg('object_a', new_object))
|
||||||
|
@inject(KwArg('some_setting', 1334))
|
||||||
|
def example_callback(object_a, some_setting):
|
||||||
|
"""This function has dependencies on object a and b.
|
||||||
|
|
||||||
|
Dependencies are injected using `@inject` decorator.
|
||||||
|
"""
|
||||||
|
assert isinstance(object_a, object)
|
||||||
|
assert some_setting == 1334
|
||||||
|
|
||||||
|
|
||||||
|
example_callback()
|
||||||
|
example_callback()
|
||||||
|
|
||||||
|
|
||||||
@override decorator
|
@override decorator
|
||||||
-------------------
|
-------------------
|
||||||
|
|
|
@ -10,6 +10,9 @@ provided.
|
||||||
Instance providers & Injections
|
Instance providers & Injections
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
Providers
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
*Instance* providers are providers that deal with object's creation and
|
*Instance* providers are providers that deal with object's creation and
|
||||||
initialization.
|
initialization.
|
||||||
|
|
||||||
|
@ -50,16 +53,19 @@ Example:
|
||||||
assert isinstance(object_1, object) and isinstance(object_2, object)
|
assert isinstance(object_1, object) and isinstance(object_2, object)
|
||||||
|
|
||||||
|
|
||||||
|
Injections
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
Objects can take dependencies in various forms. Some objects take init
|
Objects can take dependencies in various forms. Some objects take init
|
||||||
arguments, other are using attributes or methods to be initialized. It affects
|
arguments, other are using attributes or methods to be initialized. It affects
|
||||||
how such objects need to be created and initialized, and that is the place
|
how such objects need to be created and initialized, and that is the place
|
||||||
where *Injections* need to be used.
|
where *Injections* need to be used.
|
||||||
|
|
||||||
In terms of computer science, *Injection* of dependency is a way how
|
In terms of computer science, *Injection of dependency* is a way how
|
||||||
dependency can be coupled with dependent object.
|
dependency can be coupled with dependent object.
|
||||||
|
|
||||||
In terms of *Objects*, *Injection* is an instruction how to provide
|
In terms of *Objects*, *Injection* is an instruction how to provide
|
||||||
dependency for the particular object.
|
dependency for the particular provider.
|
||||||
|
|
||||||
Every Python object could be an injection's value. Special case is an *Objects*
|
Every Python object could be an injection's value. Special case is an *Objects*
|
||||||
provider as an injection's value. In such case, injection value is a result of
|
provider as an injection's value. In such case, injection value is a result of
|
||||||
|
|
61
examples/readme2/inject_decorator.py
Normal file
61
examples/readme2/inject_decorator.py
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
"""`@inject` decorator example.
|
||||||
|
|
||||||
|
Flask is required to make this example work.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
from objects.providers import NewInstance
|
||||||
|
from objects.providers import Singleton
|
||||||
|
from objects.injections import KwArg
|
||||||
|
from objects.injections import Attribute
|
||||||
|
from objects.decorators import inject
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectA(object):
|
||||||
|
|
||||||
|
"""ObjectA has dependency on database."""
|
||||||
|
|
||||||
|
def __init__(self, database):
|
||||||
|
"""Initializer.
|
||||||
|
|
||||||
|
Database dependency need to be injected via init arg."""
|
||||||
|
self.database = database
|
||||||
|
|
||||||
|
def get_one(self):
|
||||||
|
"""Select one from database and return it."""
|
||||||
|
return self.database.execute('SELECT 1').fetchone()[0]
|
||||||
|
|
||||||
|
|
||||||
|
# Database and `ObjectA` providers.
|
||||||
|
database = Singleton(sqlite3.Connection,
|
||||||
|
KwArg('database', ':memory:'),
|
||||||
|
KwArg('timeout', 30),
|
||||||
|
KwArg('detect_types', True),
|
||||||
|
KwArg('isolation_level', 'EXCLUSIVE'),
|
||||||
|
Attribute('row_factory', sqlite3.Row))
|
||||||
|
|
||||||
|
object_a = NewInstance(ObjectA,
|
||||||
|
KwArg('database', database))
|
||||||
|
|
||||||
|
|
||||||
|
# Flask application.
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# Flask view with inject decorator.
|
||||||
|
@app.route('/')
|
||||||
|
@inject(KwArg('database', database))
|
||||||
|
@inject(KwArg('object_a', object_a))
|
||||||
|
def hello(database):
|
||||||
|
one = database.execute('SELECT 1').fetchone()[0]
|
||||||
|
return 'Query returned {0}, db connection {1}'.format(one, database)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run()
|
||||||
|
|
||||||
|
# Example output of "GET / HTTP/1.1" is:
|
||||||
|
# Query returned 1, db connection <sqlite3.Connection object at 0x1057e4030>
|
Loading…
Reference in New Issue
Block a user