From 6ac0e4a04e5964c52cf517784f10712c783aa5b9 Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Tue, 1 Sep 2015 00:30:38 +0300 Subject: [PATCH] Add simplified syntax for @inject decorator --- dependency_injector/injections.py | 20 +++++++++------ examples/concept.py | 42 +++++++++++++------------------ tests/test_injections.py | 29 ++++++++++++++++++--- 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/dependency_injector/injections.py b/dependency_injector/injections.py index 546fdeb9..2faac4bb 100644 --- a/dependency_injector/injections.py +++ b/dependency_injector/injections.py @@ -1,6 +1,6 @@ """Injections module.""" -from six import wraps +import six from .utils import is_provider from .utils import ensure_is_injection @@ -48,28 +48,32 @@ class Method(Injection): __IS_METHOD_INJECTION__ = True -def inject(injection): +def inject(*args, **kwargs): """Dependency injection decorator. :type injection: Injection :return: (callable) -> (callable) """ - injection = ensure_is_injection(injection) + injections = tuple((KwArg(name, value) + for name, value in six.iteritems(kwargs))) + if args: + injections += tuple((ensure_is_injection(injection) + for injection in args)) def decorator(callback): """Dependency injection decorator.""" if hasattr(callback, '_injections'): - callback._injections += (injection,) + callback._injections += injections + return callback - @wraps(callback) + @six.wraps(callback) def decorated(*args, **kwargs): """Decorated with dependency injection callback.""" return callback(*args, **get_injectable_kwargs(kwargs, - getattr(decorated, - '_injections'))) + decorated._injections)) - setattr(decorated, '_injections', (injection,)) + decorated._injections = injections return decorated return decorator diff --git a/examples/concept.py b/examples/concept.py index 59f9eab6..aeeb6e74 100644 --- a/examples/concept.py +++ b/examples/concept.py @@ -1,15 +1,7 @@ """Concept example of `Dependency Injector`.""" -from dependency_injector.catalog import AbstractCatalog - -from dependency_injector.providers import Factory -from dependency_injector.providers import Singleton - -from dependency_injector.injections import KwArg -from dependency_injector.injections import Attribute -from dependency_injector.injections import inject - import sqlite3 +import dependency_injector as di class ObjectA(object): @@ -31,23 +23,23 @@ class ObjectB(object): self.db = db -class Catalog(AbstractCatalog): +class Catalog(di.AbstractCatalog): - """Catalog of dependency_injector providers.""" + """Catalog of providers.""" - database = Singleton(sqlite3.Connection, - KwArg('database', ':memory:'), - Attribute('row_factory', sqlite3.Row)) - """:type: (dependency_injector.Provider) -> sqlite3.Connection""" + database = di.Singleton(sqlite3.Connection, + di.KwArg('database', ':memory:'), + di.Attribute('row_factory', sqlite3.Row)) + """:type: (di.Provider) -> sqlite3.Connection""" - object_a_factory = Factory(ObjectA, - KwArg('db', database)) - """:type: (dependency_injector.Provider) -> ObjectA""" + object_a_factory = di.Factory(ObjectA, + di.KwArg('db', database)) + """:type: (di.Provider) -> ObjectA""" - object_b_factory = Factory(ObjectB, - KwArg('a', object_a_factory), - KwArg('db', database)) - """:type: (dependency_injector.Provider) -> ObjectB""" + object_b_factory = di.Factory(ObjectB, + di.KwArg('a', object_a_factory), + di.KwArg('db', database)) + """:type: (di.Provider) -> ObjectB""" # Catalog static provides. @@ -60,9 +52,9 @@ assert a1.db is a2.db is b1.db is b2.db is Catalog.database() # Example of inline injections. -@inject(KwArg('a', Catalog.object_a_factory)) -@inject(KwArg('b', Catalog.object_b_factory)) -@inject(KwArg('database', Catalog.database)) +@di.inject(a=Catalog.object_a_factory) +@di.inject(b=Catalog.object_b_factory) +@di.inject(database=Catalog.database) def example(a, b, database): """Example callback.""" assert a.db is b.db is database is Catalog.database() diff --git a/tests/test_injections.py b/tests/test_injections.py index 6e344d4b..b5cbaf34 100644 --- a/tests/test_injections.py +++ b/tests/test_injections.py @@ -76,8 +76,8 @@ class InjectTests(unittest.TestCase): provider1 = Factory(object) provider2 = Factory(list) - @inject(KwArg('a', provider1)) - @inject(KwArg('b', provider2)) + @inject(a=provider1) + @inject(b=provider2) def test(a, b): return a, b @@ -98,8 +98,8 @@ class InjectTests(unittest.TestCase): provider2 = Factory(list) object_a = object() - @inject(KwArg('a', provider1)) - @inject(KwArg('b', provider2)) + @inject(a=provider1) + @inject(b=provider2) def test(a, b): return a, b @@ -120,6 +120,27 @@ class InjectTests(unittest.TestCase): provider = Factory(list) object_a = object() + @inject(b=provider) + def test(a, b): + return a, b + + a1, b1 = test(object_a) + a2, b2 = test(object_a) + + self.assertIsInstance(a1, object) + self.assertIsInstance(a2, object) + self.assertIs(a1, object_a) + self.assertIs(a2, object_a) + + self.assertIsInstance(b1, list) + self.assertIsInstance(b2, list) + self.assertIsNot(b1, b2) + + def test_injection_kwarg_syntax(self): + """Test `inject()` decorated callback with "old" style using KwArg.""" + provider = Factory(list) + object_a = object() + @inject(KwArg('b', provider)) def test(a, b): return a, b