Dependency Injection#
from pprint import pprint
from dicfg import ConfigReader, build_config
!cat ./configs/config.yml
config_reader = ConfigReader(name="myconfig")
default:
config_int: 1
config_string: "fire"
config_list: [1, 2, 3]
config_none: None
config_dict:
sub_config: "water"
To use dependency injection in our config we first need to setup a project with object dependencies.#
class ProjectComponent:
def __init__(self, name):
self.name = name
class MyProject:
def __init__(self, project_component: ProjectComponent):
self.project_component = project_component
Objects can be build with build_config when using the *object key.#
user_config = {
"myconfig": {
"default": {
"project_component": {
# a classes/functions can be build via the *object key
"*object": "__main__.ProjectComponent",
# any arguments can specified below
"name": "my_project_component",
# non-keyword arguments can be specified with *args, e.g.,
# "*args": ["my_project_component"],
},
},
},
}
config = config_reader.read(user_config)
pprint(config, sort_dicts=False)
objects = build_config(config["default"])
print("\n build objects: \n")
pprint(objects)
{'default': {'config_int': 1,
'config_string': 'fire',
'config_list': [1, 2, 3],
'config_none': 'None',
'config_dict': {'sub_config': 'water'},
'project_component': {'*object': '__main__.ProjectComponent',
'name': 'my_project_component'}}}
build objects:
{'config_dict': {'sub_config': 'water'},
'config_int': 1,
'config_list': [1, 2, 3],
'config_none': None,
'config_string': 'fire',
'project_component': <__main__.ProjectComponent object at 0x7f1dc82a0df0>}
Dependency Injection can be done by object interpolation.#
user_config = {
"myconfig": {
"default": {
"project_component": {
"*object": "__main__.ProjectComponent",
"name": "my_project_component",
},
"project": {
"*object": "__main__.MyProject",
# object interpolation
"project_component": "${project_component}",
},
},
},
}
config = config_reader.read(user_config)
pprint(config, sort_dicts=False)
objects = build_config(config["default"])
print("\n build objects: \n")
pprint(objects, sort_dicts=False)
print("\nproject component name:", objects["project"].project_component.name)
{'default': {'config_int': 1,
'config_string': 'fire',
'config_list': [1, 2, 3],
'config_none': 'None',
'config_dict': {'sub_config': 'water'},
'project_component': {'*object': '__main__.ProjectComponent',
'name': 'my_project_component'},
'project': {'*object': '__main__.MyProject',
'project_component': '${project_component}'}}}
build objects:
{'config_int': 1,
'config_string': 'fire',
'config_list': [1, 2, 3],
'config_none': None,
'config_dict': {'sub_config': 'water'},
'project_component': <__main__.ProjectComponent object at 0x7f1dc82a0ac0>,
'project': <__main__.MyProject object at 0x7f1dc82a0be0>}
project component name: my_project_component
Interpolation of objects is done by object reference.#
user_config = {
"myconfig": {
"default": {
"project_component": {
"*object": "__main__.ProjectComponent",
"name": "my_project_component",
},
"project": {
"*object": "__main__.MyProject",
# object interpolation by object reference
"project_component": "${project_component}",
},
# object interpolation by object reference
"my_interpolation_component": "${project_component}",
},
},
}
config = config_reader.read(user_config)
pprint(config, sort_dicts=False)
objects = build_config(config["default"])
print("\n build objects: \n")
pprint(objects, sort_dicts=False)
print("\nreference project_component:", objects["project_component"])
print("reference interpolation_component:", objects["my_interpolation_component"])
{'default': {'config_int': 1,
'config_string': 'fire',
'config_list': [1, 2, 3],
'config_none': 'None',
'config_dict': {'sub_config': 'water'},
'project_component': {'*object': '__main__.ProjectComponent',
'name': 'my_project_component'},
'project': {'*object': '__main__.MyProject',
'project_component': '${project_component}'},
'my_interpolation_component': '${project_component}'}}
build objects:
{'config_int': 1,
'config_string': 'fire',
'config_list': [1, 2, 3],
'config_none': None,
'config_dict': {'sub_config': 'water'},
'project_component': <__main__.ProjectComponent object at 0x7f1dc82a02b0>,
'project': <__main__.MyProject object at 0x7f1dc82a08b0>,
'my_interpolation_component': <__main__.ProjectComponent object at 0x7f1dc82a02b0>}
reference project_component: <__main__.ProjectComponent object at 0x7f1dc82a02b0>
reference interpolation_component: <__main__.ProjectComponent object at 0x7f1dc82a02b0>
Object attribute interpolation is possible via accesing attributes of object references.#
user_config = {
"myconfig": {
"default": {
"project_component": {
"*object": "__main__.ProjectComponent",
"name": "my_project_component",
},
"project": {
"*object": "__main__.MyProject",
"project_component": "${project_component}",
},
"my_attribute_component": "${project_component}",
# object attribute interpolation
"my_attribute_component_name": "${project_component.name}",
},
},
}
config = config_reader.read(user_config)
pprint(config, sort_dicts=False)
objects = build_config(config["default"])
print("\n build objects: \n")
pprint(objects, sort_dicts=False)
print("\nmy_attribute_component_name:", objects["my_attribute_component_name"])
{'default': {'config_int': 1,
'config_string': 'fire',
'config_list': [1, 2, 3],
'config_none': 'None',
'config_dict': {'sub_config': 'water'},
'project_component': {'*object': '__main__.ProjectComponent',
'name': 'my_project_component'},
'project': {'*object': '__main__.MyProject',
'project_component': '${project_component}'},
'my_attribute_component': '${project_component}',
'my_attribute_component_name': '${project_component.name}'}}
build objects:
{'config_int': 1,
'config_string': 'fire',
'config_list': [1, 2, 3],
'config_none': None,
'config_dict': {'sub_config': 'water'},
'project_component': <__main__.ProjectComponent object at 0x7f1dc830c790>,
'project': <__main__.MyProject object at 0x7f1dc830c6d0>,
'my_attribute_component': <__main__.ProjectComponent object at 0x7f1dc830c790>,
'my_attribute_component_name': 'my_project_component'}
my_attribute_component_name: my_project_component