Created
February 2, 2012 00:02
-
-
Save oinopion/1720269 to your computer and use it in GitHub Desktop.
Simple Dependency Injection with decorators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
""" | |
Dependency injection made simple | |
@requires('stores') | |
class Action(object): | |
self.stores = None | |
@provides('stores') | |
class InMemoryStores(Stores): | |
pass | |
action = SomeAction() | |
assert isinstance(action.stores, InMemoryStores) | |
When first Action is instantiated, this will trigger instantiation of 'stores' | |
providing class. This class constructor cannot take any arguments. | |
""" | |
__all__ = 'requires', 'provides' | |
def requires(name): | |
def decorator(cls): | |
init = cls.__init__ | |
def wrapper(self, *args, **kwargs): | |
setattr(self, name, _get_instance(name)) | |
init(self, *args, **kwargs) | |
cls.__init__ = wrapper | |
return cls | |
return decorator | |
def provides(name): | |
def decorator(factory): | |
_factories[name] = factory | |
return factory | |
return decorator | |
_factories = {} | |
_instances = {} | |
def _get_instance(name): | |
try: | |
return _instances[name] | |
except KeyError: | |
return _create_instance(name) | |
def _create_instance(name): | |
try: | |
instance = _factories[name]() | |
_instances[name] = instance | |
return instance | |
except KeyError: | |
raise StandardError('Nothing registered for name: %s' % name) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment