A pythonic dependency injection library that assembles objects into graphs in an easy, maintainable way
—
Core functionality for creating and configuring dependency injection containers. Object graphs serve as the central point for providing instances with automatic dependency resolution through implicit and explicit bindings.
Creates a new ObjectGraph instance with configurable dependency resolution behavior, module scanning, and binding specifications.
def new_object_graph(
modules=finding.ALL_IMPORTED_MODULES,
classes=None,
binding_specs=None,
only_use_explicit_bindings=False,
allow_injecting_none=False,
configure_method_name='configure',
dependencies_method_name='dependencies',
get_arg_names_from_class_name=bindings.default_get_arg_names_from_class_name,
get_arg_names_from_provider_fn_name=providing.default_get_arg_names_from_provider_fn_name,
id_to_scope=None,
is_scope_usable_from_scope=lambda _1, _2: True,
use_short_stack_traces=True
):
"""
Creates a new object graph for dependency injection.
Parameters:
- modules: modules to search for classes for implicit bindings; defaults to all imported modules
- classes: specific classes for implicit bindings; if None, no classes
- binding_specs: BindingSpec subclasses for custom bindings; if None, no binding specs
- only_use_explicit_bindings: if True, only use explicit bindings (no implicit class discovery)
- allow_injecting_none: if True, allow None values to be injected
- configure_method_name: name of method in BindingSpec classes for configuration
- dependencies_method_name: name of method in BindingSpec classes for dependencies
- get_arg_names_from_class_name: function to extract argument names from class names
- get_arg_names_from_provider_fn_name: function to extract argument names from provider function names
- id_to_scope: mapping of scope IDs to Scope instances for custom scopes
- is_scope_usable_from_scope: function determining if one scope can be used from another
- use_short_stack_traces: if True, provide abbreviated stack traces for errors
Returns:
ObjectGraph instance for dependency injection
"""The main dependency injection container that provides instances with automatic dependency resolution.
class ObjectGraph(object):
def provide(self, cls):
"""
Provides an instance of the specified class with dependencies injected.
Parameters:
- cls: class to instantiate (not an instance)
Returns:
Instance of cls with dependencies injected
Raises:
Error: if instance of cls is not providable
"""import pinject
class DatabaseService(object):
def __init__(self):
self.connection = "database connection"
class UserService(object):
def __init__(self, database_service):
self.db = database_service
# Create object graph with automatic module scanning
obj_graph = pinject.new_object_graph()
# Provide instance with automatic dependency injection
user_service = obj_graph.provide(UserService)
print(user_service.db.connection) # "database connection"import pinject
class ServiceA(object):
def __init__(self):
pass
class ServiceB(object):
def __init__(self, service_a):
self.service_a = service_a
# Create object graph with specific classes only
obj_graph = pinject.new_object_graph(classes=[ServiceA, ServiceB])
service_b = obj_graph.provide(ServiceB)import pinject
class Config(object):
def __init__(self):
self.setting = "production"
class MyBindingSpec(pinject.BindingSpec):
def configure(self, bind):
bind('config').to_instance(Config())
# Only use explicit bindings
obj_graph = pinject.new_object_graph(
binding_specs=[MyBindingSpec()],
only_use_explicit_bindings=True
)import pinject
class CustomScope(pinject.Scope):
def provide(self, binding_key, default_provider_fn):
# Custom scoping logic
return default_provider_fn()
custom_scope_id = "custom"
obj_graph = pinject.new_object_graph(
id_to_scope={custom_scope_id: CustomScope()}
)Install with Tessl CLI
npx tessl i tessl/pypi-pinject