mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-10-30 23:47:40 +03:00 
			
		
		
		
	Merge pull request #5 from rmk135/scoped_provider
Adding scoped provider with examples
This commit is contained in:
		
						commit
						2c449e9820
					
				
							
								
								
									
										79
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								README.md
									
									
									
									
									
								
							|  | @ -14,6 +14,7 @@ Concept example of objects catalogs. | ||||||
| from objects import AbstractCatalog | from objects import AbstractCatalog | ||||||
| from objects.providers import Singleton, NewInstance | from objects.providers import Singleton, NewInstance | ||||||
| from objects.injections import InitArg, Attribute | from objects.injections import InitArg, Attribute | ||||||
|  | 
 | ||||||
| import sqlite3 | import sqlite3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -121,6 +122,7 @@ Concept example of objects overrides. | ||||||
| from objects import AbstractCatalog, overrides | from objects import AbstractCatalog, overrides | ||||||
| from objects.providers import Singleton, NewInstance | from objects.providers import Singleton, NewInstance | ||||||
| from objects.injections import InitArg, Attribute | from objects.injections import InitArg, Attribute | ||||||
|  | 
 | ||||||
| import sqlite3 | import sqlite3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -183,6 +185,7 @@ Concept example of objects catalogs. | ||||||
| from objects import AbstractCatalog | from objects import AbstractCatalog | ||||||
| from objects.providers import Singleton, NewInstance, ExternalDependency | from objects.providers import Singleton, NewInstance, ExternalDependency | ||||||
| from objects.injections import InitArg, Attribute | from objects.injections import InitArg, Attribute | ||||||
|  | 
 | ||||||
| import sqlite3 | import sqlite3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -231,3 +234,79 @@ assert a1 is not a2 | ||||||
| assert b1 is not b2 | assert b1 is not b2 | ||||||
| assert a1.db is a2.db is b1.db is b2.db is Catalog.database() | assert a1.db is a2.db is b1.db is b2.db is Catalog.database() | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | Example of objects catalog with scoped provider: | ||||||
|  | 
 | ||||||
|  | ```python | ||||||
|  | """ | ||||||
|  | Scoped provider examples. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from objects import AbstractCatalog | ||||||
|  | from objects.providers import Singleton, Scoped | ||||||
|  | from objects.injections import InitArg, Attribute | ||||||
|  | 
 | ||||||
|  | import sqlite3 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ObjectA(object): | ||||||
|  |     def __init__(self, db): | ||||||
|  |         self.db = db | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Catalog of objects providers. | ||||||
|  | class Catalog(AbstractCatalog): | ||||||
|  |     """ | ||||||
|  |     Objects catalog. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     database = Singleton(sqlite3.Connection, | ||||||
|  |                          InitArg('database', ':memory:'), | ||||||
|  |                          Attribute('row_factory', sqlite3.Row)) | ||||||
|  |     """ :type: (objects.Provider) -> sqlite3.Connection """ | ||||||
|  | 
 | ||||||
|  |     object_a = Scoped(ObjectA, | ||||||
|  |                       InitArg('db', database)) | ||||||
|  |     """ :type: (objects.Provider) -> ObjectA """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Making scope using `with` statement. | ||||||
|  | with Catalog.object_a as object_a_provider: | ||||||
|  |     object_a1 = object_a_provider() | ||||||
|  |     object_a2 = object_a_provider() | ||||||
|  | 
 | ||||||
|  |     assert object_a1 is object_a2 | ||||||
|  |     assert object_a1.db is object_a2.db | ||||||
|  | 
 | ||||||
|  | # Making another one scope using `with` statement. | ||||||
|  | with Catalog.object_a as object_a_provider: | ||||||
|  |     object_a3 = object_a_provider() | ||||||
|  |     object_a4 = object_a_provider() | ||||||
|  | 
 | ||||||
|  |     assert object_a3 is object_a4 | ||||||
|  |     assert object_a3.db is object_a4.db | ||||||
|  | 
 | ||||||
|  |     assert (object_a1 is not object_a3) and \ | ||||||
|  |            (object_a1 is not object_a4) | ||||||
|  |     assert (object_a2 is not object_a3) and \ | ||||||
|  |            (object_a2 is not object_a4) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Making one more scope using provider methods. | ||||||
|  | Catalog.object_a.in_scope() | ||||||
|  | 
 | ||||||
|  | object_a5 = Catalog.object_a() | ||||||
|  | object_a6 = Catalog.object_a() | ||||||
|  | 
 | ||||||
|  | assert object_a5 is object_a6 | ||||||
|  | assert object_a5.db is object_a6.db | ||||||
|  | 
 | ||||||
|  | assert (object_a1 is not object_a3) and \ | ||||||
|  |        (object_a1 is not object_a4) and \ | ||||||
|  |        (object_a1 is not object_a5) and \ | ||||||
|  |        (object_a1 is not object_a6) | ||||||
|  | assert (object_a2 is not object_a3) and \ | ||||||
|  |        (object_a2 is not object_a4) and \ | ||||||
|  |        (object_a2 is not object_a5) and \ | ||||||
|  |        (object_a2 is not object_a6) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ Concept example of objects catalogs. | ||||||
| from objects import AbstractCatalog | from objects import AbstractCatalog | ||||||
| from objects.providers import Singleton, NewInstance | from objects.providers import Singleton, NewInstance | ||||||
| from objects.injections import InitArg, Attribute | from objects.injections import InitArg, Attribute | ||||||
|  | 
 | ||||||
| import sqlite3 | import sqlite3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ Concept example of objects catalogs. | ||||||
| from objects import AbstractCatalog | from objects import AbstractCatalog | ||||||
| from objects.providers import Singleton, NewInstance, ExternalDependency | from objects.providers import Singleton, NewInstance, ExternalDependency | ||||||
| from objects.injections import InitArg, Attribute | from objects.injections import InitArg, Attribute | ||||||
|  | 
 | ||||||
| import sqlite3 | import sqlite3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ Concept example of objects overrides. | ||||||
| from objects import AbstractCatalog, overrides | from objects import AbstractCatalog, overrides | ||||||
| from objects.providers import Singleton, NewInstance | from objects.providers import Singleton, NewInstance | ||||||
| from objects.injections import InitArg, Attribute | from objects.injections import InitArg, Attribute | ||||||
|  | 
 | ||||||
| import sqlite3 | import sqlite3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										71
									
								
								examples/scoped_provider.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								examples/scoped_provider.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | ||||||
|  | """ | ||||||
|  | Scoped provider examples. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from objects import AbstractCatalog | ||||||
|  | from objects.providers import Singleton, Scoped | ||||||
|  | from objects.injections import InitArg, Attribute | ||||||
|  | 
 | ||||||
|  | import sqlite3 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ObjectA(object): | ||||||
|  |     def __init__(self, db): | ||||||
|  |         self.db = db | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Catalog of objects providers. | ||||||
|  | class Catalog(AbstractCatalog): | ||||||
|  |     """ | ||||||
|  |     Objects catalog. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     database = Singleton(sqlite3.Connection, | ||||||
|  |                          InitArg('database', ':memory:'), | ||||||
|  |                          Attribute('row_factory', sqlite3.Row)) | ||||||
|  |     """ :type: (objects.Provider) -> sqlite3.Connection """ | ||||||
|  | 
 | ||||||
|  |     object_a = Scoped(ObjectA, | ||||||
|  |                       InitArg('db', database)) | ||||||
|  |     """ :type: (objects.Provider) -> ObjectA """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Making scope using `with` statement. | ||||||
|  | with Catalog.object_a as object_a_provider: | ||||||
|  |     object_a1 = object_a_provider() | ||||||
|  |     object_a2 = object_a_provider() | ||||||
|  | 
 | ||||||
|  |     assert object_a1 is object_a2 | ||||||
|  |     assert object_a1.db is object_a2.db | ||||||
|  | 
 | ||||||
|  | # Making another one scope using `with` statement. | ||||||
|  | with Catalog.object_a as object_a_provider: | ||||||
|  |     object_a3 = object_a_provider() | ||||||
|  |     object_a4 = object_a_provider() | ||||||
|  | 
 | ||||||
|  |     assert object_a3 is object_a4 | ||||||
|  |     assert object_a3.db is object_a4.db | ||||||
|  | 
 | ||||||
|  |     assert (object_a1 is not object_a3) and \ | ||||||
|  |            (object_a1 is not object_a4) | ||||||
|  |     assert (object_a2 is not object_a3) and \ | ||||||
|  |            (object_a2 is not object_a4) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Making one more scope using provider methods. | ||||||
|  | Catalog.object_a.in_scope() | ||||||
|  | 
 | ||||||
|  | object_a5 = Catalog.object_a() | ||||||
|  | object_a6 = Catalog.object_a() | ||||||
|  | 
 | ||||||
|  | assert object_a5 is object_a6 | ||||||
|  | assert object_a5.db is object_a6.db | ||||||
|  | 
 | ||||||
|  | assert (object_a1 is not object_a3) and \ | ||||||
|  |        (object_a1 is not object_a4) and \ | ||||||
|  |        (object_a1 is not object_a5) and \ | ||||||
|  |        (object_a1 is not object_a6) | ||||||
|  | assert (object_a2 is not object_a3) and \ | ||||||
|  |        (object_a2 is not object_a4) and \ | ||||||
|  |        (object_a2 is not object_a5) and \ | ||||||
|  |        (object_a2 is not object_a6) | ||||||
|  | @ -108,6 +108,60 @@ class Singleton(NewInstance): | ||||||
|             self.instance = super(Singleton, self).__call__(*args, **kwargs) |             self.instance = super(Singleton, self).__call__(*args, **kwargs) | ||||||
|         return self.instance |         return self.instance | ||||||
| 
 | 
 | ||||||
|  |     def _reset_instance(self): | ||||||
|  |         """ | ||||||
|  |         Resets instance. | ||||||
|  |         """ | ||||||
|  |         self.instance = None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Scoped(Singleton): | ||||||
|  |     """ | ||||||
|  |     Scoped provider will create instance once for every scope and return it on every call. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self, *args, **kwargs): | ||||||
|  |         """ | ||||||
|  |         Initializer. | ||||||
|  |         """ | ||||||
|  |         self.is_in_scope = None | ||||||
|  |         super(Scoped, self).__init__(*args, **kwargs) | ||||||
|  | 
 | ||||||
|  |     def in_scope(self): | ||||||
|  |         """ | ||||||
|  |         Sets provider in "in scope" state. | ||||||
|  |         """ | ||||||
|  |         self.is_in_scope = True | ||||||
|  |         self._reset_instance() | ||||||
|  | 
 | ||||||
|  |     def out_of_scope(self): | ||||||
|  |         """ | ||||||
|  |         Sets provider in "out of scope" state. | ||||||
|  |         """ | ||||||
|  |         self.is_in_scope = False | ||||||
|  |         self._reset_instance() | ||||||
|  | 
 | ||||||
|  |     def __call__(self, *args, **kwargs): | ||||||
|  |         """ | ||||||
|  |         Returns provided instance. | ||||||
|  |         """ | ||||||
|  |         if not self.is_in_scope: | ||||||
|  |             raise RuntimeError('Trying to provide {} while provider is not in scope'.format(self.provides)) | ||||||
|  |         return super(Scoped, self).__call__(*args, **kwargs) | ||||||
|  | 
 | ||||||
|  |     def __enter__(self): | ||||||
|  |         """ | ||||||
|  |         With __enter__() implementation. Makes provider to be in scope. | ||||||
|  |         """ | ||||||
|  |         self.in_scope() | ||||||
|  |         return self | ||||||
|  | 
 | ||||||
|  |     def __exit__(self, *_): | ||||||
|  |         """ | ||||||
|  |         With __exit__() implementation. Makes provider to be out of scope. | ||||||
|  |         """ | ||||||
|  |         self.out_of_scope() | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class ExternalDependency(Provider): | class ExternalDependency(Provider): | ||||||
|     """ |     """ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user