python的简单依赖注入容器
pythonioc的Python项目详细描述
这个包提供了一个简单的控制容器反转。
使用安装
pip install pythonioc
快速启动
其主要思想是:服务注册到一个服务注册中心,并且可以被注入到该服务的用户中(当然也可以是服务本身)。
您有两个选项:
- 使用全局注册表(不要自己创建注册表)
- 使用本地注册表
下面是一些例子,下面将详细介绍。
全球注册
importpythonioc# register your service with a default name (here: 'someService', see Notes On Names)@pythonioc.ServiceclassSomeService(object):# called when the service is auto-instantiated.defpostInit(self):pass@pythonioc.NamedService('DifferentNameService')classDifferentService(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())classServiceUser(object):# inject the dependency by classservice=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 servicepythonioc.getService(SomeService)pythonioc.getService('DifferentNameService')
本地注册表
classService(object):# this will make the service registry inject a service named "someOtherService" which# comes from class SomeOtherService_someOtherService=Nonedef__init__(self):pass# will be called after everything is injecteddefpostInit(self):pass# will be called right before the object is destroyed (the registry's clean# method is called)defpreDestroy(self):passclassSomeOtherService(object):pass# let's register our servicesreg=ServiceRegistry()reg.registerService(Service)reg.registerService(SomeOtherService)
注册所有内容后,可以通过
classWiredUser(object):_service=Nonedef__init__(self,*args):passwiredUser=reg.createWired(WiredUser,'arg1','arg2')
有线对象不是服务注册表的自动组成部分,仅 如果通过调用reg.registerServiceInstance添加。
有线对象可以注入它们自己的服务注册表,因此它们可以动态创建有线对象:
classWiredUser(object):_service=NoneclassUserCreator(object):_serviceRegistry=NonedefcreateUser(self):returnself._serviceRegistry.createWired(WiredUser)userCreator=reg.createWired(UserCreator)# create some wired usersuserA=userCreator.createUser()userB=userCreator.createUser()
姓名注释
添加到注册表的服务需要一个名称。如果未提供名称,则使用类的名称(或实例的类名)。名字的第一个字符按惯例降低。
示例:
importpythoniocclassMyService(object):passpythonioc.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'
有关依赖循环的说明
一般来说,依赖循环是通过延迟初始化服务来解决的。当两个服务在初始化后执行的postinit方法内相互依赖时,仍然会发生关键周期。通过跟踪当前运行的postinit方法并引发异常来检测这些周期。
服务创建是线程安全的,因此从两个不同的线程使用长时间运行的init或postinit方法访问未初始化的服务将阻塞其中一个线程。
错误
错误报告,改进建议等总是受欢迎的!