Usage examples¶
Injecting services and parameters¶
from glorpen.di import Container
class MyParamService(object):
pass
class MyService(object):
def __init__(self, obj, text, value):
super(MyService, self).__init__()
print("service instance: %s" % obj)
print("container parameter: %s" % text)
print("provided value: %s" % value)
c = Container()
c.add_service(MyParamService)
c.add_parameter('my-param', "value from container")
c.add_service(MyService).kwargs(obj__svc=MyParamService, text__param="my-param", value="defined value")
c.get(MyService)
Running snippet will print:
service instance: <__main__.MyParamService object at 0x7f2fef6e9828>
container parameter: value from container
provided value: defined value
Arguments¶
In cases when you want to use inject parameter already used by internal methods, eg. glorpen.di.container.Service.call()
,
you can pass args with glorpen.di.container.Kwargs
helper class.
svc.configurator(callable=configurator, kwargs=Kwargs(router__svc=Router), other_param="param")
svc.call("some_method", kwargs=Kwargs(router__svc=Router), other_param="param")
Arguments defined by glorpen.di.container.Kwargs
are overriding ones provided by **kwargs notation.
Configurators¶
Configurators are services or callables used to configure main service. Provided callables are given main service instance as first argument.
def configurator(obj, some_service):
obj.some_thing = some_service()
svc.configurator(callable=configurator, some_service__svc=MyClass)
svc.configurator(service=ConfiguratorClass, method="some_method", some_service__svc=MyClass)
Factories¶
Services that create other objects. It is possible to provide parameters/other services from Container to given callables.
def factory(some_service):
return some_service("arg1")
svc1.factory(callable=factory, some_service__svc=MyClass)
class FactoryClass(object):
def create_new(self, some_service):
return some_service("arg1")
svc2.factory(service=FactoryClass, method="create_new", some_service__svc=MyClass)
Calling methods and settings properties¶
To call method on service creation:
svc.call("some_method", some_service__svc=MyClass)
To set properties on service creation:
svc.set(my_prop__svc=MyClass)
Using type hints for auto injection¶
Sometimes it is easier to just auto-fill function arguments, when using Python3 it can be done by arguments type hinting (see typing
for more information).
You can enable function hints lookup by using glorpen.di.container.Service.kwargs_from_signature()
for constructor arguments
and glorpen.di.container.Service.call_with_signature()
for methods.
from glorpen.di import Container
class MyParamService(object):
pass
class MyService(object):
def __init__(self, param:MyParamService):
super(MyService, self).__init__()
print("MyService.__init__: %s" % param.__class__.__name__)
def some_method(self, param:MyParamService):
print("MyService.some_method: %s" % param.__class__.__name__)
c = Container()
c.add_service(MyParamService)
c.add_service(MyService).kwargs_from_signature().call_with_signature("some_method")
print("Continer.get: %s" % c.get(MyService).__class__.__name__)
Snippet will create following output:
MyService.__init__: MyParamService
MyService.some_method: MyParamService
Continer.get: MyService
Adding custom scope¶
You can define new scope by extending glorpen.di.scopes.ScopeBase
and using glorpen.di.container.Container.set_scope_hierarchy()
.
from glorpen.di.scopes import ScopePrototype, ScopeSingleton, ScopeBase
from random import randint
class RandomScope(ScopeBase):
"""Returns new or cached instances based on random factor."""
def __init__(self, randomity=3):
super(RandomScope, self).__init__()
self.rnd = randomity
self.instances = {}
def get(self, creator, name):
if not name in self.instances or randint(0, self.rnd) == 0:
self.instances[name] = creator()
return self.instances[name]
c = Container()
# add scope with parameter
c.set_scope_hierarchy(ScopeSingleton, RandomScope(5), ScopePrototype)
# configure "str" service so we can see instances count
counter = 0
def configurator(kwargs):
global counter
kwargs.setdefault("object", "instance number: %d" % counter)
counter+=1
c.add_service('arg.test').implementation(str)\
.configurator(args_callable=configurator)\
.scope(RandomScope)
for i in range(0,10):
print(c.get("arg.test"))
Running script will print:
instance number: 0
instance number: 0
instance number: 0
instance number: 0
instance number: 1
instance number: 2
instance number: 2
instance number: 3
instance number: 4
instance number: 4