dependency_injection.py¶
This Python library defines a helper for building a dependency injection framework.
Installation¶
dependency_injection
is available on GitHub and on PyPI:
$ pip install dependency_injection
We test against Python 2.6, 2.7, 3.2, and 3.3.
dependency_injection
is MIT-licensed.
What is Dependency Injection?¶
When you define a function you specify its parameters, and when you call the function you pass in arguments for those parameters. Dependency injection means dynamically passing arguments to a function based on the parameters it defines. So if you define a function:
>>> def foo(bar, baz):
... pass
Then you are advertising to a dependency injection framework that your function
wants to have the bar
and baz
objects passed into it. What bar
and
baz
resolve to depends on the dependency injection framework. This library
provides a helper, resolve_dependencies
, for building your own
dependency injection framework. It doesn’t provide such a framework itself,
because that would take away all the fun.
API Reference¶
-
exception
dependency_injection.
CantUseThis
¶
-
dependency_injection.
get_signature
(function)¶ - Given a function object, return a
namedtuple
representing the function - signature.
Parameters: function – a function object or other callable Returns: a namedtuple
representing the function signatureThis function is a helper for
resolve_dependencies
. It returns anamedtuple
with these items:parameters
- atuple
of all parameters, in the order they were definedrequired
- atuple
of required parameters, in the order they were definedoptional
- adict
of optional parameters mapped to their defaults
For example, if you have this function:
>>> def foo(bar, baz=1): ... pass ...
Then
get_signature
will return:>>> get_signature(foo) Signature(parameters=('bar', 'baz'), required=('bar',), optional={'baz': 1})
Here are the kinds of callable objects we support (in this resolution order):
- functions
- methods (both bound and unbound)
- classes (both newstyle and oldstyle) with a user-defined
__new__
- classes (both newstyle and oldstyle) with a user-defined
__init__
- object instances with a
__call__
method
So you can do:
>>> class Foo(object): ... def __init__(self, bar, baz=1): ... pass ... >>> get_signature(Foo) Signature(parameters=('self', 'bar', 'baz'), required=('self', 'bar'), optional={'baz': 1})
- Given a function object, return a
-
dependency_injection.
resolve_dependencies
(function, available)¶ - Given a function object and a mapping of available dependencies, return a
namedtuple
that has arguments to suit the function’s parameters.
Parameters: - function – a function object or other callable
- available – a
dict
mapping arbitrary names to objects
Returns: a
namedtuple
representing the arguments to use in calling the functionThe return value of this function is a
namedtuple
with these attributes:as_args
- atuple
of argument valuesas_kwargs
- adict
of keyword argumentssignature
- anamedtuple
as returned byget_signature
The
as_args
andas_kwargs
arguments are functionally equivalent. You could call the function using either one and you’d get the same result, and which one you use depends on the needs of the dependency injection framework you’re writing, and your personal preference.This is the main function you want to use from this library. The idea is that in your dependency injection framework, you call this function to resolve the dependencies for a function, and then call the function. So here’s a function:
>>> def foo(bar, baz): ... return bar + baz
And here’s the basics of a dependency injection framework:
>>> def inject_dependencies(func): ... my_state = {'bar': 1, 'baz': 2, 'bloo': 'blee'} ... dependencies = resolve_dependencies(func, my_state) ... return func(*dependencies.as_args) ...
And here’s what it looks like to call it:
>>> inject_dependencies(foo) 3
See
get_signature
for details on support for non-function callables.