Skip to content

Commit c0d1d68

Browse files
committed
chore: polish api by renaming dependency -> service, factory_args -> factory_kwargs, etc.
1 parent 5fe8b00 commit c0d1d68

19 files changed

+586
-269
lines changed

src/dependency_injection/container.py

Lines changed: 223 additions & 81 deletions
Large diffs are not rendered by default.

src/dependency_injection/registration.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@
66
class Registration:
77
def __init__(
88
self,
9-
dependency: Type,
9+
service: Type,
1010
implementation: Optional[Type],
1111
scope: Scope,
1212
tags: Optional[set] = None,
13-
constructor_args: Optional[Dict[str, Any]] = None,
13+
constructor_kwargs: Optional[Dict[str, Any]] = None,
1414
factory: Optional[Callable[[Any], Any]] = None,
15-
factory_args: Optional[Dict[str, Any]] = None,
15+
factory_kwargs: Optional[Dict[str, Any]] = None,
1616
):
17-
self.dependency = dependency
17+
self.service = service
1818
self.implementation = implementation
1919
self.scope = scope
2020
self.tags = tags or set()
21-
self.constructor_args = constructor_args or {}
21+
self.constructor_kwargs = constructor_kwargs or {}
2222
self.factory = factory
23-
self.factory_args = factory_args or {}
23+
self.factory_kwargs = factory_kwargs or {}
2424

2525
if not any([self.implementation, self.factory]):
2626
raise Exception("There must be either an implementation or a factory.")
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import warnings
2+
3+
import pytest
4+
5+
from dependency_injection.container import DependencyContainer
6+
from unit_test.unit_test_case import UnitTestCase
7+
8+
9+
class TestRegisterDeprecations(UnitTestCase):
10+
def test_register_transient_dependency_alias_warns_and_works(self):
11+
# arrange
12+
class IFoo:
13+
pass
14+
15+
class Foo(IFoo):
16+
pass
17+
18+
dependency_container = DependencyContainer.get_instance()
19+
20+
# act
21+
with pytest.warns(DeprecationWarning):
22+
dependency_container.register_transient(dependency=IFoo, implementation=Foo)
23+
resolved = dependency_container.resolve(IFoo)
24+
25+
# assert
26+
self.assertIsInstance(resolved, Foo)
27+
28+
def test_register_transient_constructor_args_alias_warns_and_works(self):
29+
# arrange
30+
class Foo:
31+
def __init__(self, x: int):
32+
self.x = x
33+
34+
dependency_container = DependencyContainer.get_instance()
35+
36+
# act
37+
with pytest.warns(DeprecationWarning):
38+
dependency_container.register_transient(Foo, constructor_args={"x": 123})
39+
obj = dependency_container.resolve(Foo)
40+
41+
# assert
42+
self.assertEqual(123, obj.x)
43+
44+
def test_register_transient_new_names_no_warning(self):
45+
# arrange
46+
class Foo:
47+
def __init__(self, x: int):
48+
self.x = x
49+
50+
dependency_container = DependencyContainer.get_instance()
51+
52+
# act
53+
with warnings.catch_warnings(record=True) as rec:
54+
warnings.simplefilter("always", DeprecationWarning)
55+
dependency_container.register_transient(Foo, constructor_kwargs={"x": 1})
56+
57+
obj = dependency_container.resolve(Foo)
58+
59+
# assert
60+
dep_warnings = [w for w in rec if issubclass(w.category, DeprecationWarning)]
61+
self.assertEqual([], dep_warnings)
62+
self.assertEqual(1, obj.x)
63+
64+
def test_register_scoped_dependency_alias_warns_and_works(self):
65+
# arrange
66+
class IService:
67+
pass
68+
69+
class Service(IService):
70+
pass
71+
72+
dependency_container = DependencyContainer.get_instance()
73+
74+
# act
75+
with pytest.warns(DeprecationWarning):
76+
dependency_container.register_scoped(
77+
dependency=IService, implementation=Service
78+
)
79+
a1 = dependency_container.resolve(IService, scope_name="req-A")
80+
a2 = dependency_container.resolve(IService, scope_name="req-A")
81+
b1 = dependency_container.resolve(IService, scope_name="req-B")
82+
83+
# assert
84+
self.assertIsInstance(a1, Service)
85+
self.assertIs(a1, a2) # same scope -> same instance
86+
self.assertIsNot(a1, b1) # different scope -> different instance
87+
88+
def test_register_singleton_dependency_alias_warns_and_works(self):
89+
# arrange
90+
class IService:
91+
pass
92+
93+
class Service(IService):
94+
pass
95+
96+
dependency_container = DependencyContainer.get_instance()
97+
98+
# act
99+
with pytest.warns(DeprecationWarning):
100+
dependency_container.register_singleton(
101+
dependency=IService, implementation=Service
102+
)
103+
s1 = dependency_container.resolve(IService)
104+
s2 = dependency_container.resolve(IService)
105+
106+
# assert
107+
self.assertIs(s1, s2)
108+
109+
def test_register_factory_factory_args_alias_warns_and_works(self):
110+
# arrange
111+
def build_cfg(*, env="prod"):
112+
return {"env": env}
113+
114+
dependency_container = DependencyContainer.get_instance()
115+
116+
# act
117+
with pytest.warns(DeprecationWarning):
118+
dependency_container.register_factory(
119+
dependency=dict, factory=build_cfg, factory_args={"env": "dev"}
120+
)
121+
cfg = dependency_container.resolve(dict)
122+
123+
# assert
124+
self.assertEqual("dev", cfg["env"])
125+
126+
def test_register_instance_dependency_alias_warns_and_works(self):
127+
# arrange
128+
class Foo:
129+
pass
130+
131+
foo = Foo()
132+
dependency_container = DependencyContainer.get_instance()
133+
134+
# act
135+
with pytest.warns(DeprecationWarning):
136+
dependency_container.register_instance(dependency=Foo, instance=foo)
137+
resolved = dependency_container.resolve(Foo)
138+
139+
# assert
140+
self.assertIs(foo, resolved)
141+
142+
def test_register_transient_unexpected_kw_raises_type_error(self):
143+
# arrange
144+
class Foo:
145+
pass
146+
147+
dependency_container = DependencyContainer.get_instance()
148+
149+
# act + assert
150+
with pytest.raises(TypeError):
151+
dependency_container.register_transient(Foo, unexpected_kw=1)

tests/unit_test/container/register/test_register_factory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def create(cls) -> Car:
2828
# assert
2929
# (no exception thrown)
3030

31-
def test_register_with_factory_args(
31+
def test_register_with_factory_kwargs(
3232
self,
3333
):
3434
# arrange
@@ -51,7 +51,7 @@ def create(cls, color: str, mileage: int) -> Car:
5151
dependency_container.register_factory(
5252
Vehicle,
5353
factory=CarFactory.create,
54-
factory_args={"color": "red", "mileage": 3800},
54+
factory_kwargs={"color": "red", "mileage": 3800},
5555
)
5656

5757
def test_register_with_lambda_method(

tests/unit_test/container/register/test_register_scoped.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ class Car(Vehicle):
1616
pass
1717

1818
dependency_container = DependencyContainer.get_instance()
19-
dependency = Vehicle
19+
service = Vehicle
2020
implementation = Car
2121

2222
# act
23-
dependency_container.register_scoped(dependency, implementation)
23+
dependency_container.register_scoped(service, implementation)
2424

2525
# assert
2626
# (no exception thrown)
@@ -36,13 +36,13 @@ class Car(Vehicle):
3636
pass
3737

3838
dependency_container = DependencyContainer.get_instance()
39-
dependency = Vehicle
39+
service = Vehicle
4040
implementation = Car
41-
dependency_container.register_scoped(dependency, implementation)
41+
dependency_container.register_scoped(service, implementation)
4242

4343
# act + assert
4444
with pytest.raises(ValueError, match="is already registered"):
45-
dependency_container.register_scoped(dependency, implementation)
45+
dependency_container.register_scoped(service, implementation)
4646

4747
def test_register_scoped_when_dependency_and_implementation_being_the_same(
4848
self,
@@ -52,9 +52,9 @@ class Vehicle:
5252
pass
5353

5454
dependency_container = DependencyContainer.get_instance()
55-
dependency = Vehicle
55+
service = Vehicle
5656

5757
# act
58-
dependency_container.register_scoped(dependency)
58+
dependency_container.register_scoped(service)
5959

6060
# assert (no exception thrown)

tests/unit_test/container/register/test_register_singleton.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ class Car(Vehicle):
1616
pass
1717

1818
dependency_container = DependencyContainer.get_instance()
19-
dependency = Vehicle
19+
service = Vehicle
2020
implementation = Car
2121

2222
# act
23-
dependency_container.register_singleton(dependency, implementation)
23+
dependency_container.register_singleton(service, implementation)
2424

2525
# assert
2626
# (no exception thrown)
@@ -36,13 +36,13 @@ class Car(Vehicle):
3636
pass
3737

3838
dependency_container = DependencyContainer.get_instance()
39-
dependency = Vehicle
39+
service = Vehicle
4040
implementation = Car
41-
dependency_container.register_singleton(dependency, implementation)
41+
dependency_container.register_singleton(service, implementation)
4242

4343
# act + assert
4444
with pytest.raises(ValueError, match="is already registered"):
45-
dependency_container.register_singleton(dependency, implementation)
45+
dependency_container.register_singleton(service, implementation)
4646

4747
def test_register_singleton_when_dependency_and_implementation_being_the_same(
4848
self,
@@ -52,9 +52,9 @@ class Vehicle:
5252
pass
5353

5454
dependency_container = DependencyContainer.get_instance()
55-
dependency = Vehicle
55+
service = Vehicle
5656

5757
# act
58-
dependency_container.register_singleton(dependency)
58+
dependency_container.register_singleton(service)
5959

6060
# assert (no exception thrown)

tests/unit_test/container/register/test_register_transient.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ class Car(Vehicle):
1616
pass
1717

1818
dependency_container = DependencyContainer.get_instance()
19-
dependency = Vehicle
19+
service = Vehicle
2020
implementation = Car
2121

2222
# act
23-
dependency_container.register_transient(dependency, implementation)
23+
dependency_container.register_transient(service, implementation)
2424

2525
# assert (no exception thrown)
2626

@@ -35,13 +35,13 @@ class Car(Vehicle):
3535
pass
3636

3737
dependency_container = DependencyContainer.get_instance()
38-
dependency = Vehicle
38+
service = Vehicle
3939
implementation = Car
40-
dependency_container.register_transient(dependency, implementation)
40+
dependency_container.register_transient(service, implementation)
4141

4242
# act + assert
4343
with pytest.raises(ValueError, match="is already registered"):
44-
dependency_container.register_transient(dependency, implementation)
44+
dependency_container.register_transient(service, implementation)
4545

4646
def test_success_when_dependency_and_implementation_same(
4747
self,
@@ -51,10 +51,10 @@ class Vehicle:
5151
pass
5252

5353
dependency_container = DependencyContainer.get_instance()
54-
dependency = Vehicle
54+
service = Vehicle
5555

5656
# act
57-
dependency_container.register_transient(dependency)
57+
dependency_container.register_transient(service)
5858

5959
# assert (no exception thrown)
6060

tests/unit_test/container/register/test_register_with_args.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44

55
class TestRegisterWithArgs(UnitTestCase):
6-
def test_register_with_constructor_args(
6+
def test_register_with_constructor_kwargs(
77
self,
88
):
99
# arrange
@@ -14,12 +14,12 @@ class Car(Vehicle):
1414
pass
1515

1616
dependency_container = DependencyContainer.get_instance()
17-
dependency = Vehicle
17+
service = Vehicle
1818
implementation = Car
1919

2020
# act + assert (no exception)
2121
dependency_container.register_transient(
22-
dependency,
22+
service,
2323
implementation,
24-
constructor_args={"color": "red", "mileage": 3800},
24+
constructor_kwargs={"color": "red", "mileage": 3800},
2525
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import warnings
2+
3+
import pytest
4+
5+
from dependency_injection.container import DependencyContainer
6+
from unit_test.unit_test_case import UnitTestCase
7+
8+
9+
class TestResolveDeprecations(UnitTestCase):
10+
def test_resolve_dependency_alias_warns_and_works(self):
11+
# arrange
12+
class Foo:
13+
pass
14+
15+
dependency_container = DependencyContainer.get_instance()
16+
dependency_container.register_transient(Foo)
17+
18+
# act
19+
with pytest.warns(DeprecationWarning):
20+
obj = dependency_container.resolve(dependency=Foo)
21+
22+
# assert
23+
self.assertIsInstance(obj, Foo)
24+
25+
def test_resolve_new_name_no_warning(self):
26+
# arrange
27+
class Foo:
28+
pass
29+
30+
dependency_container = DependencyContainer.get_instance()
31+
dependency_container.register_transient(Foo)
32+
33+
# act
34+
with warnings.catch_warnings(record=True) as rec:
35+
warnings.simplefilter("always", DeprecationWarning)
36+
obj = dependency_container.resolve(service=Foo)
37+
38+
# assert
39+
dep_warnings = [w for w in rec if issubclass(w.category, DeprecationWarning)]
40+
self.assertEqual([], dep_warnings)
41+
self.assertIsInstance(obj, Foo)

0 commit comments

Comments
 (0)