Adding some drafts of @inject decorator docs

This commit is contained in:
Roman Mogilatov 2015-05-14 11:21:04 +03:00
parent 9d48044ea3
commit 405c579f7e
3 changed files with 112 additions and 2 deletions

View File

@ -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
------------------- -------------------

View File

@ -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

View 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>