mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-22 09:36:48 +03:00
Add simplified kwarg injections syntax for Factory and Singleton providers
This commit is contained in:
parent
6ac0e4a04e
commit
01970dba27
|
@ -1,6 +1,8 @@
|
||||||
"""Providers module."""
|
"""Providers module."""
|
||||||
|
|
||||||
from six import class_types
|
import six
|
||||||
|
|
||||||
|
from .injections import KwArg
|
||||||
|
|
||||||
from .utils import ensure_is_provider
|
from .utils import ensure_is_provider
|
||||||
from .utils import is_kwarg_injection
|
from .utils import is_kwarg_injection
|
||||||
|
@ -100,7 +102,7 @@ class Factory(Provider):
|
||||||
|
|
||||||
__slots__ = ('_provides', '_kwargs', '_attributes', '_methods')
|
__slots__ = ('_provides', '_kwargs', '_attributes', '_methods')
|
||||||
|
|
||||||
def __init__(self, provides, *injections):
|
def __init__(self, provides, *injections, **kwargs):
|
||||||
"""Initializer."""
|
"""Initializer."""
|
||||||
if not callable(provides):
|
if not callable(provides):
|
||||||
raise Error('Factory provider expects to get callable, ' +
|
raise Error('Factory provider expects to get callable, ' +
|
||||||
|
@ -109,6 +111,9 @@ class Factory(Provider):
|
||||||
self._kwargs = tuple((injection
|
self._kwargs = tuple((injection
|
||||||
for injection in injections
|
for injection in injections
|
||||||
if is_kwarg_injection(injection)))
|
if is_kwarg_injection(injection)))
|
||||||
|
if kwargs:
|
||||||
|
self._kwargs += tuple((KwArg(name, value)
|
||||||
|
for name, value in six.iteritems(kwargs)))
|
||||||
self._attributes = tuple((injection
|
self._attributes = tuple((injection
|
||||||
for injection in injections
|
for injection in injections
|
||||||
if is_attribute_injection(injection)))
|
if is_attribute_injection(injection)))
|
||||||
|
@ -149,10 +154,10 @@ class Singleton(Provider):
|
||||||
|
|
||||||
__slots__ = ('_instance', '_factory')
|
__slots__ = ('_instance', '_factory')
|
||||||
|
|
||||||
def __init__(self, provides, *injections):
|
def __init__(self, provides, *injections, **kwargs):
|
||||||
"""Initializer."""
|
"""Initializer."""
|
||||||
self._instance = None
|
self._instance = None
|
||||||
self._factory = Factory(provides, *injections)
|
self._factory = Factory(provides, *injections, **kwargs)
|
||||||
super(Singleton, self).__init__()
|
super(Singleton, self).__init__()
|
||||||
|
|
||||||
def _provide(self, *args, **kwargs):
|
def _provide(self, *args, **kwargs):
|
||||||
|
@ -178,7 +183,7 @@ class ExternalDependency(Provider):
|
||||||
|
|
||||||
def __init__(self, instance_of):
|
def __init__(self, instance_of):
|
||||||
"""Initializer."""
|
"""Initializer."""
|
||||||
if not isinstance(instance_of, class_types):
|
if not isinstance(instance_of, six.class_types):
|
||||||
raise Error('ExternalDependency provider expects to get class, ' +
|
raise Error('ExternalDependency provider expects to get class, ' +
|
||||||
'got {0} instead'.format(str(instance_of)))
|
'got {0} instead'.format(str(instance_of)))
|
||||||
self._instance_of = instance_of
|
self._instance_of = instance_of
|
||||||
|
|
|
@ -28,17 +28,16 @@ class Catalog(di.AbstractCatalog):
|
||||||
"""Catalog of providers."""
|
"""Catalog of providers."""
|
||||||
|
|
||||||
database = di.Singleton(sqlite3.Connection,
|
database = di.Singleton(sqlite3.Connection,
|
||||||
di.KwArg('database', ':memory:'),
|
database=':memory:')
|
||||||
di.Attribute('row_factory', sqlite3.Row))
|
|
||||||
""":type: (di.Provider) -> sqlite3.Connection"""
|
""":type: (di.Provider) -> sqlite3.Connection"""
|
||||||
|
|
||||||
object_a_factory = di.Factory(ObjectA,
|
object_a_factory = di.Factory(ObjectA,
|
||||||
di.KwArg('db', database))
|
db=database)
|
||||||
""":type: (di.Provider) -> ObjectA"""
|
""":type: (di.Provider) -> ObjectA"""
|
||||||
|
|
||||||
object_b_factory = di.Factory(ObjectB,
|
object_b_factory = di.Factory(ObjectB,
|
||||||
di.KwArg('a', object_a_factory),
|
a=object_a_factory,
|
||||||
di.KwArg('db', database))
|
db=database)
|
||||||
""":type: (di.Provider) -> ObjectB"""
|
""":type: (di.Provider) -> ObjectB"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,28 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance1, self.Example)
|
self.assertIsInstance(instance1, self.Example)
|
||||||
self.assertIsInstance(instance2, self.Example)
|
self.assertIsInstance(instance2, self.Example)
|
||||||
|
|
||||||
|
def test_call_with_init_args_simplified_syntax(self):
|
||||||
|
"""Test creation of new instances with init args injections.
|
||||||
|
|
||||||
|
Simplified syntax.
|
||||||
|
"""
|
||||||
|
provider = Factory(self.Example,
|
||||||
|
init_arg1='i1',
|
||||||
|
init_arg2='i2')
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
self.assertEqual(instance1.init_arg1, 'i1')
|
||||||
|
self.assertEqual(instance1.init_arg2, 'i2')
|
||||||
|
|
||||||
|
self.assertEqual(instance2.init_arg1, 'i1')
|
||||||
|
self.assertEqual(instance2.init_arg2, 'i2')
|
||||||
|
|
||||||
|
self.assertIsNot(instance1, instance2)
|
||||||
|
self.assertIsInstance(instance1, self.Example)
|
||||||
|
self.assertIsInstance(instance2, self.Example)
|
||||||
|
|
||||||
def test_call_with_attributes(self):
|
def test_call_with_attributes(self):
|
||||||
"""Test creation of new instances with attribute injections."""
|
"""Test creation of new instances with attribute injections."""
|
||||||
provider = Factory(self.Example,
|
provider = Factory(self.Example,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user