Metadata-Version: 1.0
Name: pythonioc
Version: 0.4.0
Summary: Simplistic dependency injection container for python
Home-page: https://bitbucket.org/eh14/python-ioc
Author: Franz Eichhorn
Author-email: frairon@googlemail.com
License: MIT
Description: .. role:: bash(code)
            :language: bash
        
        Simple Inversion-Of-Control-Container for python
        ================================================
        
        This package provides a simple inversion-of-control container.
        
        Install with 
        
        .. code:: bash
        
            pip install pythonioc
        
        Quick Start
        -----------
        
        The main idea is: services are registered to a service-registry and can be injected into users of that service (which can of course be services themselves).
        
        You have two options: 
        
        (A) use a global registry (never create a registry yourself)
            
        (B) use a local registry
            
        Examples are below, more details will follow.
        
        Global Registry
        ^^^^^^^^^^^^^^^
        
        .. code:: python
        
            import pythonioc
        
            # register your service with a default name (here: 'someService', see Notes On Names)
            @pythonioc.Service
            class SomeService(object):
            
                # called when the service is auto-instantiated.
                def postInit(self):
                    pass
                
            @pythonioc.NamedService('DifferentNameService')
            class DifferentService(object):
                pass        
                
            # for classes which we cannot decorate:
            pythonioc.registerService(ExternalService)
            
            # when we don't even have the class (or don't care about lazy-initialization)
            pythonioc.registerServiceInstance(SomeService())
            
            
            class ServiceUser(object):
                # inject the dependency by class
                service = pythonioc.Inject(SomeService)
                
                # inject the dependency by name (for cyclic dependencies)
                service2 = pythonioc.Inject('DifferentNameService')
               
              
             myUser = ServiceUser()
             
             myUser.service # --> automatically created and injected service instance.
             
             # explicitly get a service
             pythonioc.getService(SomeService)
             pythonioc.getService('DifferentNameService')
        
             
        
        Local Registry
        ^^^^^^^^^^^^^^
        
        .. code:: python
        
        
            class Service(object):
                
                # this will make the service registry inject a service named "someOtherService" which 
                # comes from class SomeOtherService
                _someOtherService = None
                
                def __init__(self):
                    pass
                    
                # will be called after everything is injected
                def postInit(self):
                    pass
                    
                # will be called right before the object is destroyed (the registry's clean
                # method is called)
                def preDestroy(self):
                    pass
                    
                    
        
            class SomeOtherService(object):
                pass
                
            # let's register our services
            reg = ServiceRegistry()
            reg.registerService(Service)
            reg.registerService(SomeOtherService)
        
        Once everything is registered, a service can be injected by
        
        .. code:: python
        
        
            class WiredUser(object):
        
                _service=None
                
                def __init__(self, *args):
                    pass
                    
            wiredUser = reg.createWired(WiredUser, 'arg1', 'arg2')
        
        Wired objects are not automatically part of the service registry, only
        if added by calling ``reg.registerServiceInstance``. 
        
        Wired objects can inject their own service registry, so they can create wired objects on the fly:
        
        .. code:: python
        
        
            class WiredUser(object):
                _service=None
                
        
            class UserCreator(object):
                _serviceRegistry=None
                
                def createUser(self):
                    return self._serviceRegistry.createWired(WiredUser) 
                
            userCreator = reg.createWired(UserCreator)
        
            # create some wired users
            userA = userCreator.createUser()
            userB = userCreator.createUser()
        
        
        Notes on Names
        --------------
        
        Services added to the registry need a name. If no name is provided, the class' name (or the instance's class name) is used. The name's first character is lowered by convention.
        
        Example:
        
        .. code:: python
        
            import pythonioc
            
            class MyService(object):
                pass
            
            pythonioc.registerService(MyService)            # --> name is 'myService'
            pythonioc.registerServiceInstance(MyService())  # --> name is 'myService'
            pythonioc.registerService(MyService, serviceName='customName') # --> name is 'customName'
            pythonioc.registerServiceInstance(MyService(), serviceName='customName2')  # --> name is 'customName2'
            
        
        Notes on Dependency Cycles
        --------------------------
        
        Generally, dependency cycles are resolved by lazily initializing services. Critical cycles can still occur, when two services depend on each other within their `postInit`-methods that are executed after initialization. Those cycles are detected by keeping track of the currently running postInit methods and throwing an exception.
        
        The service creation is thread safe, so accessing a non-initialized service with a long-running init or postInit method from two different threads will block one of the threads.
        
        
        Bugs
        ----
        
        Bug reports, suggestions for improvements etc. are always welcome!
        
Platform: UNKNOWN
