1#ifndef SAUCE_INTERNAL_NEW_BINDING_H_
2#define SAUCE_INTERNAL_NEW_BINDING_H_
4#include <sauce/injector.h>
5#include <sauce/memory.h>
6#include <sauce/named.h>
7#include <sauce/provider.h>
8#include <sauce/internal/apply_variadic.h>
9#include <sauce/internal/binding.h>
10#include <sauce/internal/key.h>
11#include <sauce/internal/resolved_binding.h>
12#include <sauce/internal/self_injector.h>
13#include <sauce/internal/type_id.h>
18template<
typename Dependency,
typename Scope,
typename Constructor,
typename Allocator>
26 struct NewBindingFriend {
28 void validateAcyclicHelper(
NewBinding_ const & binding, InjectorPtr injector, TypeIds & ids, std::string name) {
29 binding.template validateAcyclicHelper<T>(injector, ids, name);
33 typename Key<T>::Ptr injectHelper(
NewBinding_ const & binding, InjectorPtr injector, std::string name) {
34 typename Key<T>::Ptr injected;
35 binding.template injectHelper<typename i::Key<T>::Normalized>(injected, injector, name);
40 friend class NewBindingFriend;
42 struct InjectParameters {
45 InjectorPtr & injector;
48 binding(binding), injector(injector) {}
51 template<
typename T,
int i>
53 typedef typename Key<T>::Ptr Type;
55 template<
typename Passed>
56 Type yield(
Passed passed) {
58 InjectorPtr & injector = passed.injector;
59 std::string dependencyName = binding.dynamicDependencyNames[i];
61 return this->NewBindingFriend::template injectHelper<T>(binding, injector, dependencyName);
67 typedef typename Inject::Constructed Impl;
70 typedef sauce::shared_ptr<Impl> ImplPtr;
73 std::vector<std::string> dynamicDependencyNames;
75 struct ValidateAcyclicParameters {
78 InjectorPtr & injector;
82 binding(binding), injector(injector), ids(ids) {}
85 template<
typename T,
int i>
87 template<
typename Passed>
88 void observe(
Passed passed) {
90 InjectorPtr & injector = passed.injector;
91 TypeIds & ids = passed.ids;
92 std::string dependencyName = binding.dynamicDependencyNames[i];
94 this->NewBindingFriend::template validateAcyclicHelper<T>(binding, injector, ids, dependencyName);
99 void validateAcyclic(InjectorPtr injector, TypeIds & ids)
const {
101 observeConstructor<ValidateAcyclicParameters, Constructor, Allocator>(passed);
104 void setDynamicDependencyNames(std::vector<std::string>
const & dynamicDependencyNames) {
105 this->dynamicDependencyNames = dynamicDependencyNames;
106 this->dynamicDependencyNames.resize(Inject::arity(), unnamed());
111 typedef typename ResolvedBinding<Dependency>::BindingPtr BindingPtr;
114 dynamicDependencyNames(Inject::arity(), unnamed()) {}
123 void inject(IfacePtr & injected, BindingPtr binding, InjectorPtr injector)
const {
125 Deleter deleter(sauce::static_pointer_cast<NewBinding_>(binding));
126 ImplPtr impl(applyConstructor<InjectParameters, Constructor, Allocator>(passed), deleter);
128 selfInjector.setSelf(impl);
130 this->
template injectHelper<NormalizedImpl>(impl, injector, this->
getName());
131 injected = sauce::static_pointer_cast<Iface>(impl);
134 void dispose(Iface * iface)
const {
135 typedef typename Allocator::template rebind<Impl>::other ImplAllocator;
136 ImplAllocator allocator;
137 Impl * impl =
static_cast<Impl *
>(iface);
139 allocator.deallocate(impl, 1);
146namespace i = ::sauce::internal;
Wrap dependency requests with Named to choose one of several (statically) named alternatives.
Definition: named.h:12
Definition: apply_variadic.h:49
The base class of all actual binding implementations.
Definition: binding.h:22
std::string getName() const
The dynamic name of this binding.
Definition: binding.h:103
A smart pointer deleter that diposes with the given disposal.
Definition: disposal_deleter.h:13
A complete specification of a dependency request.
Definition: key.h:15
Definition: new_binding.h:19
void inject(IfacePtr &injected, BindingPtr binding, InjectorPtr injector) const
Inject an Iface.
Definition: new_binding.h:123
If a type requests injection of its own smart pointer, do so.
Definition: self_injector.h:16
Definition: new_binding.h:52
Definition: new_binding.h:43
Definition: new_binding.h:86
Definition: new_binding.h:76