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>
18 template<
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 {
44 NewBinding_
const & binding;
45 InjectorPtr & injector;
47 Passed(NewBinding_
const & binding, 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) {
57 NewBinding_
const & binding = passed.binding;
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 {
77 NewBinding_
const & binding;
78 InjectorPtr & injector;
81 Passed(NewBinding_
const & binding, InjectorPtr & injector, TypeIds & ids):
82 binding(binding), injector(injector), ids(ids) {}
85 template<
typename T,
int i>
87 template<
typename Passed>
88 void observe(
Passed passed) {
89 NewBinding_
const & binding = passed.binding;
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);
146 namespace i = ::sauce::internal;
150 #endif // SAUCE_INTERNAL_NEW_BINDING_H_
Definition: new_binding.h:43
Definition: apply_variadic.h:49
Definition: new_binding.h:76
A smart pointer deleter that diposes with the given disposal.
Definition: disposal_deleter.h:13
If a type requests injection of its own smart pointer, do so.
Definition: self_injector.h:16
Definition: new_binding.h:52
Wrap dependency requests with Named to choose one of several (statically) named alternatives.
Definition: named.h:12
std::string getName() const
The dynamic name of this binding.
Definition: binding.h:103
void inject(IfacePtr &injected, BindingPtr binding, InjectorPtr injector) const
Inject an Iface.
Definition: new_binding.h:123
Definition: new_binding.h:19
Definition: new_binding.h:86
The base class of all actual binding implementations.
Definition: binding.h:22
A complete specification of a dependency request.
Definition: key.h:15