14#include "arcane/utils/internal/DependencyInjection.h"
16#include "arcane/utils/UniqueArray.h"
17#include "arcane/utils/ExternalRef.h"
18#include "arcane/utils/FatalErrorException.h"
23namespace Arcane::DependencyInjection
38 : m_instance(instance)
52 for (Integer i = 0,
n = m_instance_list.size(); i <
n; ++i)
53 delete m_instance_list[i].m_instance;
54 m_instance_list.clear();
61 Int32 index = m_instance_list.size();
62 m_instance_list.add(InstanceInfo{ instance, index });
64 IInjectedInstance* instance(Int32 index)
const {
return m_instance_list[index].m_instance; }
65 Int32 nbInstance()
const {
return m_instance_list.size(); }
69 UniqueArray<InstanceInfo> m_instance_list;
75 UniqueArray<Ref<impl::IInstanceFactory>> m_factories;
76 UniqueArray<impl::FactoryInfo> m_factories_info;
101_add(IInjectedInstance* instance)
103 m_p->addInstance(instance);
112 return m_p->nbInstance();
118IInjectedInstance* Injector::
119_value(Integer i)
const
121 return m_p->instance(i);
130 return m_p->m_factories.size();
136impl::IInstanceFactory* Injector::
137_factory(Integer i)
const
139 return m_p->m_factories[i].get();
150namespace Arcane::DependencyInjection::impl
156void ConstructorRegistererBase::
157_doError1(
const String& message,
int nb_value)
170 : m_property(property)
171 , m_name(property.name())
177 bool hasName(
const String& str)
const {
return str == m_name; }
202 m_p->m_factories.add(f);
209hasName(
const String& str)
const
211 return m_p->hasName(str);
221GlobalRegisterer(FactoryCreateFunc func,
const ProviderProperty& property) noexcept
222: m_factory_create_func(func)
223, m_factory_property(property)
230GenericRegisterer<GlobalRegisterer>::Info GlobalRegisterer::m_global_registerer_info;
237namespace Arcane::DependencyInjection
244fillWithGlobalFactories()
246 impl::GlobalRegisterer* g = impl::GlobalRegisterer::firstRegisterer();
249 auto func = g->infoCreatorWithPropertyFunction();
251 impl::FactoryInfo fi = (*func)(g->property());
252 m_p->m_factories_info.add(fi);
253 m_p->m_factories.addRange(fi.m_p->m_factories);
256 g = g->nextRegisterer();
259 ARCANE_FATAL(
"Infinite loop in DependencyInjection global factories");
267printFactories()
const
269 std::ostringstream ostr;
271 auto f = [&](impl::IInstanceFactory* v) ->
bool {
272 const impl::ConcreteFactoryTypeInfo& cfi = v->concreteFactoryInfo();
273 ostr <<
"I=" << index <<
" " <<
typeid(v).name()
274 <<
"\n interface=" << cfi.interfaceTypeInfo().traceInfo()
275 <<
"\n concrete=" << cfi.concreteTypeInfo().traceInfo()
276 <<
"\n constructor=" << cfi.constructorTypeInfo().traceInfo()
281 FactoryVisitorFunctor ff(f);
282 _iterateFactories(String(), &ff);
283 String s = ostr.str();
291_iterateFactories(
const String& factory_name, IFactoryVisitorFunctor* functor)
const
298 bool has_no_name = factory_name.empty();
300 Integer nb_instance = _nbValue();
301 for (Integer i = 0; i < n; ++i) {
302 impl::IInstanceFactory* f = _factory(i);
303 Int32 nb_constructor_arg = f->nbConstructorArg();
304 if (nb_constructor_arg >= 0 && nb_constructor_arg != nb_instance)
306 if (has_no_name || f->factoryInfoImpl()->hasName(factory_name)) {
307 if (functor->execute(f))
318_iterateInstances(
const std::type_info& t_info,
const String& instance_name,
319 IInstanceVisitorFunctor* lambda)
321 bool has_no_name = instance_name.empty();
323 for (Integer i = 0; i < n; ++i) {
324 IInjectedInstance* ii = _value(i);
325 if (!ii->hasTypeInfo(t_info))
327 if (has_no_name || ii->hasName(instance_name)) {
328 if (lambda->execute(ii))
338_doError(
const TraceInfo& ti,
const String& message)
347_printValidImplementationAndThrow(
const TraceInfo& ti,
348 const String& implementation_name,
349 FactoryFilterFunc filter_func)
354 UniqueArray<String> valid_names;
355 for (
Int32 i = 0, n = _nbFactory(); i < n; ++i) {
356 impl::IInstanceFactory* f = _factory(i);
357 if (filter_func(f)) {
358 f->factoryInfoImpl()->fillWithImplementationNames(valid_names);
361 String message = String::format(
"No implementation named '{0}' found", implementation_name);
365 if (valid_names.size() == 0)
366 message2 =
" and no implementation is available.";
367 else if (valid_names.size() == 1)
368 message2 = String::format(
". Valid value is: '{0}'.", valid_names[0]);
370 message2 = String::format(
". Valid values are: '{0}'.", String::join(
", ", valid_names));
371 _doError(ti, message + message2);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS(class_name)
Macro pour définir les méthodes et types une classe qui utilise un compteur de référence.
Référence à une instance.
Chaîne de caractères unicode.
Espace de nom de Arccore.
Int32 Integer
Type représentant un entier.