@@ -12,6 +12,8 @@ A simple Python dependency injection framework.
12
12
13
13
** This project is under active development. The following example does not represent the final state for the project.**
14
14
15
+ ### Dependency Injection
16
+
15
17
The injection framework is configured to inject any default values for method arguments that are instances
16
18
of ` providers.Provider ` .
17
19
@@ -21,7 +23,7 @@ arguments at runtime.
21
23
All dependency injection is lazily evaluated so providers are only evaluated when a method is called. This approach is
22
24
optimal as it reduces necessary computation for expensive services and reduces
23
25
24
- ### Decorator Injection
26
+ #### Decorator Injection
25
27
26
28
With this approach you can automatically inject functions at load time using the ` @wiring.injected ` decorator.
27
29
@@ -30,7 +32,7 @@ from pif import wiring, providers
30
32
31
33
32
34
@wiring.injected # <- automatically injects providers.Provider default arguments!
33
- def my_function (a : str = providers.Singleton [str ](lambda : " hello world" )):
35
+ def my_function (a : str = providers.Factory [str ](lambda : " hello world" )):
34
36
return a
35
37
36
38
@@ -46,7 +48,7 @@ With this approach you can wire all methods in the specified modules.
46
48
from pif import wiring, providers
47
49
48
50
49
- def my_function (a : str = providers.Singleton [str ](lambda : " hello world" )):
51
+ def my_function (a : str = providers.Factory [str ](lambda : " hello world" )):
50
52
return a
51
53
52
54
@@ -56,6 +58,65 @@ if __name__ == "__main__":
56
58
assert " hello world" == my_function()
57
59
```
58
60
61
+ ### Overriding
62
+
63
+ This package provides a simple mechanism to override providers. This can be very useful when it comes to mocking
64
+ services for testing or dynamically patching application behavior based on application configuration.
65
+
66
+ #### Standard Overriding
67
+
68
+ If you want to patch a value all you need to do is call ` .override() ` on the provider in question.
69
+
70
+ ``` python
71
+ from pif import wiring, providers
72
+
73
+ StringProvider = providers.Factory[str ](lambda : " hello world" )
74
+
75
+
76
+ @wiring.injected
77
+ def my_function (a : str = StringProvider):
78
+ return a
79
+
80
+
81
+ if __name__ == " __main__" :
82
+ assert " hello world" == my_function()
83
+
84
+ override = StringProvider.override(providers.Factory[str ](lambda : " overridden_1" ))
85
+
86
+ assert " overridden_1"
87
+ ```
88
+
89
+ ### Context Managers
90
+
91
+ If you want more control around the override lifecycles then you may use the ` Override ` context manager.
92
+
93
+ ``` python
94
+ from pif import wiring, providers
95
+
96
+ StringProvider = providers.Factory[str ](lambda : " hello world" )
97
+
98
+
99
+ @wiring.injected
100
+ def my_function (a : str = StringProvider):
101
+ return a
102
+
103
+
104
+ if __name__ == " __main__" :
105
+ assert " hello world" == my_function()
106
+
107
+ OverrideProvider = providers.Factory[str ](lambda : " overridden_1" )
108
+
109
+ with StringProvider.override(OverrideProvider):
110
+ assert " overridden_1" == my_function()
111
+
112
+ with OverrideProvider.override(providers.Factory[str ](" overridden_2" )):
113
+ assert " overridden_2" == my_function() # You can even stack overrides!!
114
+
115
+ assert " overridden_1" == my_function()
116
+
117
+ assert " hello world" == my_function()
118
+ ```
119
+
59
120
## Authors
60
121
61
122
| [ ![ Zac Scott] ( https://avatars.githubusercontent.com/u/38968222?s=128&v=4 )] ( https://github.com/scottzach1 ) |
0 commit comments