@@ -48,6 +48,7 @@ class Injector;
4848namespace Arcane ::DependencyInjection::impl
4949{
5050class FactoryInfo ;
51+ class FactoryInfoImpl ;
5152class IInstanceFactory ;
5253template <typename InterfaceType>
5354class IConcreteFactory ;
@@ -337,12 +338,40 @@ class ARCANE_UTILS_EXPORT IInstanceFactory
337338 public:
338339
339340 virtual InjectedInstanceRef createGenericReference (Injector& injector, const String& name) = 0;
341+ virtual const FactoryInfoImpl* factoryInfoImpl () const = 0;
342+ virtual ConcreteFactoryTypeInfo concreteFactoryInfo () const = 0;
343+ virtual Int32 nbConstructorArg () const = 0;
344+ };
340345
341- virtual const FactoryInfo* factoryInfo () const = 0;
346+ /* ---------------------------------------------------------------------------*/
347+ /* ---------------------------------------------------------------------------*/
348+ /* !
349+ * \internal
350+ * \brief Informations pour une fabrique.
351+ */
352+ class ARCANE_UTILS_EXPORT FactoryInfo
353+ {
354+ friend class Arcane ::DependencyInjection::Injector;
342355
343- virtual ConcreteFactoryTypeInfo concreteFactoryInfo () const = 0;
356+ private:
344357
345- virtual Int32 nbConstructorArg () const = 0;
358+ explicit FactoryInfo (const ProviderProperty& property);
359+
360+ public:
361+
362+ static FactoryInfo create (const ProviderProperty& property, const char * file_name, int line_number)
363+ {
364+ ARCANE_UNUSED (file_name);
365+ ARCANE_UNUSED (line_number);
366+ return FactoryInfo (property);
367+ }
368+ void addFactory (Ref<IInstanceFactory> f);
369+ bool hasName (const String& str) const ;
370+ const FactoryInfoImpl* _impl () const { return m_p.get (); }
371+
372+ private:
373+
374+ std::shared_ptr<FactoryInfoImpl> m_p;
346375};
347376
348377/* ---------------------------------------------------------------------------*/
@@ -367,10 +396,14 @@ template <typename InterfaceType>
367396class InstanceFactory
368397: public AbstractInstanceFactory
369398{
399+ // NOTE: On ne conserve pas une instance de 'FactoryInfo'
400+ // mais uniquement son implémentation pour éviter des références croisées
401+ // avec le std::shared_ptr.
402+
370403 public:
371404
372- InstanceFactory (FactoryInfo * si, IConcreteFactory<InterfaceType>* sub_factory)
373- : m_factory_info (si)
405+ InstanceFactory (const FactoryInfoImpl * si, IConcreteFactory<InterfaceType>* sub_factory)
406+ : m_factory_info_impl (si)
374407 , m_sub_factory(sub_factory)
375408 {
376409 }
@@ -390,9 +423,9 @@ class InstanceFactory
390423 return _createReference (injector);
391424 }
392425
393- const FactoryInfo* factoryInfo () const override
426+ const FactoryInfoImpl* factoryInfoImpl () const override
394427 {
395- return m_factory_info ;
428+ return m_factory_info_impl ;
396429 }
397430
398431 ConcreteFactoryTypeInfo concreteFactoryInfo () const override
@@ -407,8 +440,8 @@ class InstanceFactory
407440
408441 protected:
409442
410- FactoryInfo* m_factory_info ;
411- IConcreteFactory<InterfaceType>* m_sub_factory;
443+ const FactoryInfoImpl* m_factory_info_impl = nullptr ;
444+ IConcreteFactory<InterfaceType>* m_sub_factory = nullptr ;
412445
413446 private:
414447
@@ -460,44 +493,6 @@ class IConcreteFactory
460493 virtual Ref<InterfaceType> createReference (Injector&) = 0;
461494};
462495
463- /* ---------------------------------------------------------------------------*/
464- /* ---------------------------------------------------------------------------*/
465- /* !
466- * \internal
467- * \brief Informations pour une fabrique.
468- */
469- class ARCANE_UTILS_EXPORT FactoryInfo
470- {
471- friend class Arcane ::DependencyInjection::Injector;
472- class Impl ;
473-
474- public:
475-
476- FactoryInfo (const FactoryInfo&) = delete ;
477- FactoryInfo& operator =(const FactoryInfo&) = delete ;
478- ~FactoryInfo ();
479-
480- private:
481-
482- explicit FactoryInfo (const ProviderProperty& property);
483-
484- public:
485-
486- static FactoryInfo* create (const ProviderProperty& property, const char * file_name, int line_number)
487- {
488- ARCANE_UNUSED (file_name);
489- ARCANE_UNUSED (line_number);
490- return new FactoryInfo (property);
491- }
492- void addFactory (Ref<IInstanceFactory> f);
493- bool hasName (const String& str) const ;
494- void fillWithImplementationNames (Array<String>& names) const ;
495-
496- private:
497-
498- Impl* m_p = nullptr ;
499- };
500-
501496/* ---------------------------------------------------------------------------*/
502497/* ---------------------------------------------------------------------------*/
503498
@@ -516,7 +511,7 @@ class ARCANE_UTILS_EXPORT GlobalRegisterer
516511
517512 public:
518513
519- typedef FactoryInfo* (*FactoryCreateFunc)(const ProviderProperty& property);
514+ typedef FactoryInfo (*FactoryCreateFunc)(const ProviderProperty& property);
520515
521516 public:
522517
@@ -914,7 +909,7 @@ class InterfaceListRegisterer
914909 * créer une instance de \a ConcreteType via le constructeur \a ConstructorType
915910 */
916911 template <typename ConcreteType, typename ConstructorType> void
917- registerFactory (FactoryInfo* si)
912+ registerFactory (FactoryInfo& si)
918913 {
919914 _registerFactory<ConcreteType, ConstructorType, Interfaces...>(si);
920915 }
@@ -924,10 +919,10 @@ class InterfaceListRegisterer
924919 template <typename ConcreteType, typename ConstructorType,
925920 typename InterfaceType, typename ... OtherInterfaces>
926921 void
927- _registerFactory (FactoryInfo* fi)
922+ _registerFactory (FactoryInfo& fi)
928923 {
929924 auto * factory = new ConcreteFactory<InterfaceType, ConcreteType, ConstructorType>();
930- fi-> addFactory (createRef<InstanceFactory<InterfaceType>>(fi, factory));
925+ fi. addFactory (createRef<InstanceFactory<InterfaceType>>(fi. _impl () , factory));
931926 // Applique récursivement pour les autres interfaces si nécessaire
932927 if constexpr (sizeof ...(OtherInterfaces) > 0 )
933928 _registerFactory<ConcreteType, ConstructorType, OtherInterfaces...>(fi);
@@ -949,7 +944,7 @@ class InjectionRegisterer
949944
950945 // ! Enregistre dans \a si les fabriques correspondentes aux constructeurs \a Constructors
951946 template <typename ... Constructors> void
952- registerProviderInfo (FactoryInfo* si, const Constructors&... args)
947+ registerProviderInfo (FactoryInfo& si, const Constructors&... args)
953948 {
954949 _create (si, args...);
955950 }
@@ -963,14 +958,14 @@ class InjectionRegisterer
963958
964959 // ! Surcharge pour 1 constructeur
965960 template <typename ConstructorType> void
966- _create (FactoryInfo* si, const ConstructorType&)
961+ _create (FactoryInfo& si, const ConstructorType&)
967962 {
968963 m_interface_list.template registerFactory <ConcreteType, ConstructorType>(si);
969964 }
970965
971966 // ! Surcharge pour 2 constructeurs ou plus
972967 template <typename C1, typename C2, typename ... OtherConstructors>
973- void _create (FactoryInfo* si, const C1& c1, const C2& c2, const OtherConstructors&... args)
968+ void _create (FactoryInfo& si, const C1& c1, const C2& c2, const OtherConstructors&... args)
974969 {
975970 _create<C1>(si, c1);
976971 // Applique la récursivité sur les types restants
@@ -1000,10 +995,10 @@ class InjectionRegisterer
1000995#define ARCANE_DI_REGISTER_PROVIDER (t_class, t_provider_property, t_interfaces, ...) \
1001996 namespace \
1002997 { \
1003- Arcane::DependencyInjection::impl::FactoryInfo* \
998+ Arcane::DependencyInjection::impl::FactoryInfo \
1004999 ARCANE_JOIN_WITH_LINE (arcaneCreateDependencyInjectionProviderInfo##t_class)(const Arcane::DependencyInjection::ProviderProperty& property) \
10051000 { \
1006- auto * si = Arcane::DependencyInjection::impl::FactoryInfo::create (property, __FILE__, __LINE__); \
1001+ auto si = Arcane::DependencyInjection::impl::FactoryInfo::create (property, __FILE__, __LINE__); \
10071002 Arcane::DependencyInjection::impl::InjectionRegisterer<t_class, t_interfaces> injection_registerer; \
10081003 injection_registerer.registerProviderInfo (si, __VA_ARGS__); \
10091004 return si; \
0 commit comments