1#ifndef LINTEL_CORE_DI_CONTAINER_H
2#define LINTEL_CORE_DI_CONTAINER_H
13#include <unordered_map>
23 class ContainerBuilder;
56 template<
typename TContainer>
static std::shared_ptr<TDependency>
resolve(
TContainer &container)
64 template<
typename TContainer>
static std::vector<std::shared_ptr<TDependency>>
resolve(
TContainer &container)
77 std::enable_if_t<IsSupportedArgument<std::decay_t<T>>::value && !std::is_convertible<TOwner, T>::value>>
89 return std::is_constructible_v<T, InjectorFor<T, Indices>...>;
99 if constexpr (
N == 0) {
100 if constexpr (std::is_constructible_v<T>) {
117 if constexpr (!std::is_class_v<T> || std::is_abstract_v<T>) {
124 template<
typename T, std::size_t...
Indices>
138 thread_local std::vector<const void *> active;
148 if (std::find(active.begin(), active.end(), m_registration) != active.end()) {
151 active.push_back(m_registration);
158 const void *m_registration;
167 std::vector<std::type_index>
keys;
173 std::unordered_map<std::type_index, std::function<std::shared_ptr<void>(
const std::shared_ptr<void> &)>>
casts;
180 std::shared_ptr<void>
castTo(
const std::type_index &
key,
const std::shared_ptr<void> &
concrete)
const
200 template<
typename T> std::shared_ptr<T>
resolve()
204 std::lock_guard<std::mutex>
lock(m_mutex);
205 auto found = m_registrations.find(std::type_index(
typeid(
T)));
218 template<
typename T> std::vector<std::shared_ptr<T>>
resolveAll()
222 std::lock_guard<std::mutex>
lock(m_mutex);
223 auto found = m_registrations.find(std::type_index(
typeid(
T)));
226 std::vector<std::shared_ptr<T>>
instances;
238 void addRegistration(
const std::shared_ptr<Registration> &
registration);
239 std::shared_ptr<void> instantiate(
const std::shared_ptr<Registration> &
registration);
240 template<
typename T> std::shared_ptr<Registration> tryAutoRegister();
242 std::unordered_map<std::type_index, std::vector<std::shared_ptr<Registration>>> m_registrations;
257 m_registration->keys.push_back(std::type_index(
typeid(
TInterface)));
258 m_registration->casts[std::type_index(
typeid(
TInterface))] =
259 [](
const std::shared_ptr<void> &instance) -> std::shared_ptr<void> {
260 return std::static_pointer_cast<void>(
261 std::static_pointer_cast<TInterface>(std::static_pointer_cast<TInstance>(instance)));
272 m_registration->singleton =
true;
277 std::shared_ptr<Registration> m_registration;
288 std::shared_ptr<void>
shared = std::move(instance);
292 [](
const std::shared_ptr<void> &instance) -> std::shared_ptr<void> {
return instance; };
303 static_assert(detail::hasInjectableConstructor<TInstance>(),
304 "registerType<T> requires T to be default-constructible or to have a constructor whose parameters are "
305 "std::shared_ptr<...> or std::vector<std::shared_ptr<...>>");
309 [](
const std::shared_ptr<void> &instance) -> std::shared_ptr<void> {
return instance; };
311 return std::static_pointer_cast<void>(detail::createInstance<TInstance>(container));
321 auto container = std::make_shared<Container>();
330 [](
const std::shared_ptr<void> &instance) -> std::shared_ptr<void> {
return instance; };
331 std::weak_ptr<Container>
weak = container;
333 return std::static_pointer_cast<void>(
weak.lock());
340 std::vector<std::shared_ptr<Registration>> m_registrations;
343 inline void Container::addRegistration(
const std::shared_ptr<Registration> &
registration)
345 std::lock_guard<std::mutex>
lock(m_mutex);
349 inline std::shared_ptr<void> Container::instantiate(
const std::shared_ptr<Registration> &
registration)
358 template<
typename T> std::shared_ptr<Registration> Container::tryAutoRegister()
360 if constexpr (!detail::hasInjectableConstructor<T>()) {
363 std::lock_guard<std::mutex>
lock(m_mutex);
364 auto &
registrations = m_registrations[std::type_index(
typeid(
T))];
369 [](
const std::shared_ptr<void> &instance) -> std::shared_ptr<void> {
return instance; };
371 return std::static_pointer_cast<void>(detail::createInstance<T>(container));
Definition Container.h:282
RegistrationBuilder< TInstance > registerType()
Definition Container.h:301
std::shared_ptr< Container > build()
Definition Container.h:319
void registerInstance(std::shared_ptr< TInstance > instance)
Definition Container.h:286
Definition Container.h:190
std::vector< std::shared_ptr< T > > resolveAll()
Definition Container.h:218
std::shared_ptr< T > resolve()
Definition Container.h:200
Container & operator=(const Container &)=delete
Container(const Container &)=delete
Definition Container.h:248
RegistrationBuilder & asSelf()
Definition Container.h:267
RegistrationBuilder & as()
Definition Container.h:255
RegistrationBuilder(std::shared_ptr< Registration > registration)
Definition Container.h:251
RegistrationBuilder & singleInstance()
Definition Container.h:270
Definition Container.h:27
ResolutionException(const std::string &message)
Definition Container.h:30
constexpr bool isInjectableWith()
Definition Container.h:92
constexpr bool hasInjectableConstructor()
Definition Container.h:115
constexpr std::size_t constructorArity()
Definition Container.h:97
std::shared_ptr< T > createInstance(Container &container)
Definition Container.h:130
std::shared_ptr< T > createWithInjectors(Container &container, std::index_sequence< Indices... >)
Definition Container.h:125
constexpr std::size_t kMaxConstructorArguments
Definition Container.h:36
std::vector< const void * > & activeRegistrations()
Definition Container.h:136
Definition BaseFeature.h:6
constexpr std::string_view type_name()
Definition TypeName.h:9
Definition Container.h:165
std::shared_ptr< void > instance
Definition Container.h:175
std::unordered_map< std::type_index, std::function< std::shared_ptr< void >(const std::shared_ptr< void > &)> > casts
Definition Container.h:173
std::function< std::shared_ptr< void >(Container &)> factory
Definition Container.h:171
bool singleton
Definition Container.h:169
std::shared_ptr< void > castTo(const std::type_index &key, const std::shared_ptr< void > &concrete) const
Definition Container.h:180
std::vector< std::type_index > keys
Definition Container.h:167
std::mutex mutex
Definition Container.h:177
Definition Container.h:144
ActivationScope(const ActivationScope &)=delete
ActivationScope(const void *registration)
Definition Container.h:145
~ActivationScope()
Definition Container.h:153
ActivationScope & operator=(const ActivationScope &)=delete
static std::shared_ptr< TDependency > resolve(TContainer &container)
Definition Container.h:56
static std::vector< std::shared_ptr< TDependency > > resolve(TContainer &container)
Definition Container.h:64
Definition Container.h:52
Definition Container.h:72
Container & container
Definition Container.h:73
Definition Container.h:40