12#ifndef ARCANE_UTILS_DEPENDENCYINJECTION_H
13#define ARCANE_UTILS_DEPENDENCYINJECTION_H
21#include "arcane/utils/Ref.h"
22#include "arcane/utils/ExternalRef.h"
23#include "arcane/utils/GenericRegisterer.h"
28#include "arcane/utils/NotImplementedException.h"
43namespace Arcane::DependencyInjection
48namespace Arcane::DependencyInjection::impl
51class IInstanceFactory;
52template <
typename InterfaceType>
53class IConcreteFactory;
54class ConcreteFactoryTypeInfo;
62namespace Arcane::DependencyInjection
72 virtual bool hasName(
const String& str)
const = 0;
73 virtual bool hasTypeInfo(
const std::type_info&
tinfo)
const = 0;
92 const char* name()
const {
return m_name; }
106namespace Arcane::DependencyInjection::impl
121 template <
typename Type>
static TypeInfo create()
125 const TraceInfo& traceInfo()
const {
return m_trace_info; }
126 const std::type_info& stdTypeInfo()
const {
return m_type_info; }
130 const std::type_info& m_type_info;
146 : m_interface_info(a)
148 , m_constructor_info(
c)
152 template <
typename InterfaceType,
typename ConcreteType,
typename ConstructorType>
156 TypeInfo::create<ConcreteType>(),
157 TypeInfo::create<ConstructorType>());
159 const TypeInfo& interfaceTypeInfo()
const {
return m_interface_info; }
160 const TypeInfo& concreteTypeInfo()
const {
return m_concrete_info; }
161 const TypeInfo& constructorTypeInfo()
const {
return m_constructor_info; }
175template <
typename InterfaceType>
191template <
typename InterfaceType>
206 bool hasName(
const String& str)
const override {
return m_name == str; }
220template <
typename Type>
225 virtual Type instance()
const = 0;
236template <
typename Type>
250 Type instance()
const override {
return m_instance; }
251 bool hasName(
const String& str)
const override {
return m_name == str; }
295 void reset() { m_instance.reset(); }
317 virtual const FactoryInfo* factoryInfo()
const = 0;
321 virtual Int32 nbConstructorArg()
const = 0;
342template <
typename InterfaceType>
355 delete m_sub_factory;
360 return _create(_createReference(
injector), name);
370 return m_factory_info;
375 return m_sub_factory->concreteFactoryInfo();
378 Int32 nbConstructorArg()
const override
380 return m_sub_factory->nbConstructorArg();
390 return m_sub_factory->createReference(
injector);
396 return InjectedInstanceRef::createRef(x);
410 virtual Int32 nbConstructorArg()
const = 0;
420template <
typename InterfaceType>
459 bool hasName(
const String& str)
const;
472 static BaseClass::Info m_global_registerer_info;
478 return m_global_registerer_info;
495 FactoryCreateFunc infoCreatorWithPropertyFunction() {
return m_factory_create_func; }
498 const char*
name() {
return m_name; }
504 FactoryCreateFunc m_factory_create_func =
nullptr;
505 const char* m_name =
nullptr;
516namespace Arcane::DependencyInjection
528 template <
class Type>
538 return i._getValue<
Type>(name);
543 template <
class Po
interType>
556 return i._getRef<PointerType>(name);
616 template <
typename Type>
void
622 template <
typename Type>
Type
625 return InjectorHelper<Type>::get(*
this, name);
631 using FactoryType = impl::InstanceFactory<InterfaceType>;
633 auto f = [&](impl::IInstanceFactory* v) ->
bool {
634 auto*
t =
dynamic_cast<FactoryType*
>(v);
645 FactoryVisitorFunctor ff(f);
646 _iterateFactories(service_name, &ff);
650 _doError(A_FUNCINFO,
"Can not create instance");
653 String printFactories()
const;
655 void fillWithGlobalFactories();
661 void _add(IInjectedInstance* instance);
664 void _iterateInstances(
const std::type_info& t_info,
const String& instance_name,
665 IInstanceVisitorFunctor* lambda);
667 IInjectedInstance* _value(Integer i)
const;
677 void _iterateFactories(
const String& factory_name, IFactoryVisitorFunctor* functor)
const;
679 impl::IInstanceFactory* _factory(Integer i)
const;
682 template <
typename InterfaceType> Ref<InterfaceType>
683 _getRef(
const String& instance_name)
685 using InjectedType = impl::IInjectedRefInstanceT<InterfaceType>;
686 InjectedType* t =
nullptr;
687 auto f = [&](IInjectedInstance* v) ->
bool {
688 t =
dynamic_cast<InjectedType*
>(v);
691 InstanceVisitorFunctor ff(f);
692 _iterateInstances(
typeid(Ref<InterfaceType>), instance_name, &ff);
694 return t->instance();
696 ARCANE_THROW(NotImplementedException,
"Create Ref<InterfaceType> from factory");
699 template <
typename Type>
Type
700 _getValue(
const String& instance_name)
702 using InjectedType = impl::IInjectedValueInstance<Type>;
703 InjectedType* t =
nullptr;
704 auto f = [&](IInjectedInstance* v) ->
bool {
705 t =
dynamic_cast<InjectedType*
>(v);
708 InstanceVisitorFunctor ff(f);
709 _iterateInstances(
typeid(
Type), instance_name, &ff);
711 return t->instance();
712 _doError(A_FUNCINFO,
"Can not find value for type");
714 [[noreturn]]
void _doError(
const TraceInfo& ti,
const String& message);
722namespace Arcane::DependencyInjection::impl
740template <
typename... Args>
745 using ArgsType = std::tuple<Args...>;
750 template <std::
size_t I>
751 static auto _get(
Injector& i) -> std::tuple_element_t<I, ArgsType>
761 constexpr int tuple_size = std::tuple_size<ArgsType>();
762 static_assert(
tuple_size < 3,
"Too many arguments for createTuple (max=2)");
773 _doError1(
"Too many arguments for createTuple n={0} max=2",
tuple_size);
784template <
typename InterfaceType,
typename ConcreteType,
typename ConstructorType>
788 using Args =
typename ConstructorType::ArgsType;
799 return ConcreteFactoryTypeInfo::create<InterfaceType, ConcreteType, ConstructorType>();
801 Int32 nbConstructorArg()
const override
803 return std::tuple_size<Args>();
836 template <
typename ConcreteType,
typename ConstructorType>
void
851 if constexpr (
sizeof...(OtherInterfaces) > 0)
864template <
typename ConcreteType,
typename InterfaceList>
881 template <
typename ConstructorType>
void
905#define ARCANE_DI_CONSTRUCTOR(...) \
906 ::Arcane::DependencyInjection::impl::ConstructorRegisterer<__VA_ARGS__>()
908#define ARCANE_DI_EMPTY_CONSTRUCTOR(...) \
909 ::Arcane::DependencyInjection::impl::ConstructorRegisterer<>()
913#define ARCANE_DI_INTERFACES(...) \
914 ::Arcane::DependencyInjection::impl::InterfaceListRegisterer<__VA_ARGS__>
916#define ARCANE_DI_REGISTER_PROVIDER(t_class, t_provider_property, t_interfaces, ...) \
919 Arcane::DependencyInjection::impl::FactoryInfo* \
920 ARCANE_JOIN_WITH_LINE(arcaneCreateDependencyInjectionProviderInfo##t_class)(const Arcane::DependencyInjection::ProviderProperty& property) \
922 auto* si = Arcane::DependencyInjection::impl::FactoryInfo::create(property, __FILE__, __LINE__); \
923 Arcane::DependencyInjection::impl::InjectionRegisterer<t_class, t_interfaces> injection_registerer; \
924 injection_registerer.registerProviderInfo(si, __VA_ARGS__); \
928 Arcane::DependencyInjection::impl::GlobalRegisterer ARCANE_EXPORT ARCANE_JOIN_WITH_LINE(globalServiceRegisterer##aclass)(&ARCANE_JOIN_WITH_LINE(arcaneCreateDependencyInjectionProviderInfo##t_class), t_provider_property)
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS()
Macro pour déclarer les méthodes virtuelles gérant les compteurs de référence.
#define ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(class_name)
Macro pour déclarer qu'une classe utilise un compteur de référence.
#define ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS()
Macro pour définir les méthodes gérant les compteurs de référence.
Interface d'un fonctor pour appliqué à chaque fabrique.
Interface d'un fonctor pour appliqué à chaque fabrique.
Informations sur les types d'une fabrique.
Fabrique pour le type ConcreteType pour l'interface InterfaceType via le constructeur ConstructorType...
ConcreteType * _create(const Args &&tuple_args)
Ref< InterfaceType > createReference(Injector &injector) override
Créé une instance du service .
Classe permettant d'enregistrer un constructeur pour créer un objet via un Injector....
Informations pour une fabrique.
const char * name()
Nom du service.
Interface d'un fonctor de création d'une instance de service correspondant à l'interface InterfaceTyp...
virtual Ref< InterfaceType > createReference(Injector &)=0
Créé une instance du service .
Interface typée gérant l'instance d'un service.
Interface typée gérant une instance.
Fabrique pour une instance encapsulée par une référence (i.e Ref<T>).
Référence sur une instance injectée.
Interface typée gérant l'instance d'un service.
Interface typée gérant l'instance d'un service.
Classe permettant d'enregistrer des constructeurs pour créer un type ConcreteType implémentant les in...
void _create(FactoryInfo *si, const C1 &c1, const C2 &c2, const OtherConstructors &... args)
Surcharge pour 2 constructeurs ou plus.
void registerProviderInfo(FactoryInfo *si, const Constructors &... args)
Enregistre dans si les fabriques correspondentes aux constructeurs Constructors.
void _create(FactoryInfo *si, const ConstructorType &)
Surcharge pour 1 constructeur.
Classe permettant d'enregistrer la liste des interfaces d'un service. Interfaces contient la liste de...
void registerFactory(FactoryInfo *si)
Enregistre une fabrique.
Classe template pour gérer une liste globale permettant d'enregistrer des fabriques.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Gestion des références sur un objet externe.
Référence à une instance.
Implémentation thread-safe d'un compteur de référence.
Chaîne de caractères unicode.
Int32 Integer
Type représentant un entier.