def __init__(self, modules=None, binder=None, stage=None): if modules is None: modules = [] elif not hasattr(modules, '__iter__'): modules = [modules] if binder: self._binder = binder.create_child() else: self._binder = Binder() self._stage = stage self.add_modules(modules)
def describe_a_Binder(): binder = Binder() binder.bind(object, to_instance=object()) def describe_when_adding_a_duplicate_binding(): try: binder.bind(object, to_instance=object()) e = None except BindingError, e: pass def then_a_BindingError_is_raised(): assert isinstance(e, BindingError)
class Injector(object): def __init__(self, modules=None, binder=None, stage=None): if modules is None: modules = [] elif not hasattr(modules, '__iter__'): modules = [modules] if binder: self._binder = binder.create_child() else: self._binder = Binder() self._stage = stage self.add_modules(modules) def add_modules(self, modules): provides_helper = ProvidesBinderHelper() for module in modules: ModuleAdapter(module, self).configure(self._binder) provides_helper.bind_providers(module, self._binder) def get_provider(self, cls, annotation=None): injector = self class DynamicProvider(object): def get(self): return injector.get_instance(cls, annotation) return DynamicProvider() def get_instance(self, cls, annotation=None): if cls is IInjector: # TODO: i don't like this, but it works for now return self key = Key(cls, annotation) binding = self._binder.get_binding(cls, annotation) if binding: # Both the binding.provider and the scope's # provider could be types, so inject both. bindingProvider = binding.provider if isinstance(bindingProvider, type): # We can't update binding.provider as an optimization # unless we can prove that the provider can only # have one instance. # (by existing inside our binder/parent binders Singleton scopes, # or via some other additional proof that there can be only one # instance) # The reasoning behind this is that all bindings have # scopes, and the proivder's binding could exist in a scope. bindingProvider = self.get_instance(bindingProvider) provider = binding.scope.scope(key, bindingProvider) if isinstance(provider, type): provider = self.get_instance(provider) return provider.get() else: instance = self.create_object(cls) return self.inject_members(instance) def create_child(self, modules): """Create a new injector that inherits the state from this injector. All bindings are inherited. In the future this may become closer to child injectors on google-guice. """ binder = self._binder.create_child() return Injector(modules, binder=binder, stage=self._stage) def create_object(self, cls): if not hasattr(cls, '__mro__'): warnings.warn("can't create an instance of %r - no __mro__; " "this legacy behavior will be removed in a future " "version") return cls guice_data = _GuiceData.composite_from_class(cls) if not guice_data.init: instance = cls() else: kwargs = {} for name, guicearg in guice_data.init.items(): kwargs[name] = self.get_instance(guicearg.datatype, guicearg.annotation) instance = cls(**kwargs) return instance def inject_members(self, instance): # this may be a little slow; done twice guice_data = _GuiceData.composite_from_class(instance.__class__) for name, gm in guice_data.methods.items(): kwargs = {} for param, guicearg in gm.items(): kwargs[param] = self.get_instance(guicearg.datatype, guicearg.annotation) getattr(instance, name)(**kwargs) return instance
class Injector(object): def __init__(self, modules=None, binder=None, stage=None): if modules is None: modules = [] elif not hasattr(modules, '__iter__'): modules = [modules] if binder: self._binder = binder.create_child() else: self._binder = Binder() self._stage = stage self.add_modules(modules) def add_modules(self, modules): provides_helper = ProvidesBinderHelper() for module in modules: ModuleAdapter(module, self).configure(self._binder) provides_helper.bind_providers(module, self._binder) def get_provider(self, cls, annotation=None): injector = self class DynamicProvider(object): def get(self): return injector.get_instance(cls, annotation) return DynamicProvider() def get_instance(self, cls, annotation=None): if cls is IInjector: # TODO: i don't like this, but it works for now return self key = Key(cls, annotation) binding = self._binder.get_binding(key) if binding: provider = binding.scope.scope(key, binding.provider) if isinstance(provider, type): provider = self.get_instance(provider) return provider.get() else: instance = self.create_object(cls) return self.inject_members(instance) def create_child(self, modules): """Create a new injector that inherits the state from this injector. All bindings are inherited. In the future this may become closer to child injectors on google-guice. """ binder = self._binder.create_child() return Injector(modules, binder=binder, stage=self._stage) def create_object(self, cls): if not hasattr(cls, '__mro__'): warnings.warn("can't create an instance of %r - no __mro__; " "this legacy behavior will be removed in a future " "version") return cls guice_data = _GuiceData.composite_from_class(cls) if not guice_data.init: instance = cls() else: kwargs = {} for name, guicearg in guice_data.init.items(): kwargs[name] = self.get_instance(guicearg.datatype, guicearg.annotation) instance = cls(**kwargs) return instance def inject_members(self, instance): # this may be a little slow; done twice guice_data = _GuiceData.composite_from_class(instance.__class__) for name, gm in guice_data.methods.items(): kwargs = {} for param, guicearg in gm.items(): kwargs[param] = self.get_instance(guicearg.datatype, guicearg.annotation) getattr(instance, name)(**kwargs) return instance