mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-10-31 07:57:43 +03:00 
			
		
		
		
	Add containers module
This commit is contained in:
		
							parent
							
								
									0cb197802a
								
							
						
					
					
						commit
						97d1dab00a
					
				
							
								
								
									
										93
									
								
								dependency_injector/containers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								dependency_injector/containers.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,93 @@ | ||||||
|  | """IoC containers module.""" | ||||||
|  | 
 | ||||||
|  | import six | ||||||
|  | 
 | ||||||
|  | from dependency_injector import utils | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DeclarativeContainerMetaClass(type): | ||||||
|  |     """Declarative inversion of control container meta class.""" | ||||||
|  | 
 | ||||||
|  |     def __new__(mcs, class_name, bases, attributes): | ||||||
|  |         """Declarative container class factory.""" | ||||||
|  |         cls_providers = tuple((name, provider) | ||||||
|  |                               for name, provider in six.iteritems(attributes) | ||||||
|  |                               if utils.is_provider(provider)) | ||||||
|  | 
 | ||||||
|  |         inherited_providers = tuple((name, provider) | ||||||
|  |                                     for base in bases if utils.is_catalog(base) | ||||||
|  |                                     for name, provider in six.iteritems( | ||||||
|  |                                         base.cls_providers)) | ||||||
|  | 
 | ||||||
|  |         attributes['cls_providers'] = dict(cls_providers) | ||||||
|  |         attributes['inherited_providers'] = dict(inherited_providers) | ||||||
|  | 
 | ||||||
|  |         return type.__new__(mcs, class_name, bases, attributes) | ||||||
|  | 
 | ||||||
|  |     def __setattr__(cls, name, value): | ||||||
|  |         """Set class attribute. | ||||||
|  | 
 | ||||||
|  |         If value of attribute is provider, it will be added into providers | ||||||
|  |         dictionary. | ||||||
|  |         """ | ||||||
|  |         if utils.is_provider(value): | ||||||
|  |             cls.providers[name] = value | ||||||
|  |         super(DeclarativeContainerMetaClass, cls).__setattr__(name, value) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Container(object): | ||||||
|  |     """Inversion of control container.""" | ||||||
|  | 
 | ||||||
|  |     __IS_CATALOG__ = True | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         """Initializer.""" | ||||||
|  |         self.providers = dict() | ||||||
|  | 
 | ||||||
|  |     def bind_providers(self, **providers): | ||||||
|  |         """Bind providers to the container.""" | ||||||
|  |         for name, provider in six.iteritems(providers): | ||||||
|  |             setattr(self, name, utils.ensure_is_provider(provider)) | ||||||
|  |         return self | ||||||
|  | 
 | ||||||
|  |     def __setattr__(self, name, value): | ||||||
|  |         """Set instance attribute. | ||||||
|  | 
 | ||||||
|  |         If value of attribute is provider, it will be added into providers | ||||||
|  |         dictionary. | ||||||
|  |         """ | ||||||
|  |         if utils.is_provider(value): | ||||||
|  |             self.providers[name] = value | ||||||
|  |         super(Container, self).__setattr__(name, value) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @six.add_metaclass(DeclarativeContainerMetaClass) | ||||||
|  | class DeclarativeContainer(object): | ||||||
|  |     """Declarative inversion of control container.""" | ||||||
|  | 
 | ||||||
|  |     cls_providers = dict() | ||||||
|  |     inherited_providers = dict() | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         """Initializer.""" | ||||||
|  |         self.providers = dict() | ||||||
|  |         self.providers.update(self.__class__.inherited_providers) | ||||||
|  |         self.providers.update(self.__class__.cls_providers) | ||||||
|  |         super(DeclarativeContainer, self).__init__() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def override(declarative_container): | ||||||
|  |     """:py:class:`DeclarativeContainer` overriding decorator. | ||||||
|  | 
 | ||||||
|  |     :param declarative_container: Container that should be overridden by | ||||||
|  |                                   decorated container. | ||||||
|  |     :type declarative_container: :py:class:`DeclarativeContainer` | ||||||
|  | 
 | ||||||
|  |     :return: Declarative container's overriding decorator. | ||||||
|  |     :rtype: callable(:py:class:`DeclarativeContainer`) | ||||||
|  |     """ | ||||||
|  |     def decorator(overriding_container): | ||||||
|  |         """Overriding decorator.""" | ||||||
|  |         declarative_container.override(overriding_container) | ||||||
|  |         return overriding_container | ||||||
|  |     return decorator | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user