14#include "arccore/base/internal/DependencyInjection.h"
16#include "arccore/base/ExternalRef.h"
17#include "arccore/base/FatalErrorException.h"
18#include "arccore/base/CoreArray.h"
23namespace Arcane::DependencyInjection
25using Arcane::Impl::CoreArray;
38 InstanceInfo(IInjectedInstance* instance,
size_t index)
39 : m_instance(instance)
45 IInjectedInstance* m_instance =
nullptr;
53 for (
auto& x : m_instance_list)
55 m_instance_list.clear();
60 void addInstance(IInjectedInstance* instance)
62 size_t index = m_instance_list.size();
63 m_instance_list.add(InstanceInfo{ instance, index });
65 IInjectedInstance* instance(
size_t index)
const {
return m_instance_list[index].m_instance; }
66 size_t nbInstance()
const {
return m_instance_list.size(); }
70 CoreArray<InstanceInfo> m_instance_list;
76 CoreArray<Ref<impl::IInstanceFactory>> m_factories;
77 CoreArray<impl::FactoryInfo> m_factories_info;
102_add(IInjectedInstance* instance)
104 m_p->addInstance(instance);
113 return m_p->nbInstance();
119IInjectedInstance* Injector::
120_value(
size_t i)
const
122 return m_p->instance(i);
131 return m_p->m_factories.size();
137impl::IInstanceFactory* Injector::
138_factory(
size_t i)
const
140 return m_p->m_factories[i].get();
151namespace Arcane::DependencyInjection::impl
157void ConstructorRegistererBase::
158_doError1(
const String& message,
int nb_value)
160 ARCCORE_FATAL(message,nb_value);
170 FactoryInfoImpl(
const ProviderProperty& property)
171 : m_property(property)
172 , m_name(property.name())
178 bool hasName(
const String& str)
const {
return str == m_name; }
179 void fillWithImplementationNames(
CoreArray<String>& names)
const { names.add(m_name); }
183 const ProviderProperty m_property;
192FactoryInfo(
const ProviderProperty& property)
203 m_p->m_factories.add(f);
210hasName(
const String& str)
const
212 return m_p->hasName(str);
222GlobalRegisterer(FactoryCreateFunc func,
const ProviderProperty& property) noexcept
223: m_factory_create_func(func)
224, m_factory_property(property)
231GenericRegisterer<GlobalRegisterer>::Info GlobalRegisterer::m_global_registerer_info;
238namespace Arcane::DependencyInjection
245fillWithGlobalFactories()
247 impl::GlobalRegisterer* g = impl::GlobalRegisterer::firstRegisterer();
250 auto func = g->infoCreatorWithPropertyFunction();
252 impl::FactoryInfo fi = (*func)(g->property());
253 m_p->m_factories_info.add(fi);
254 for (
auto& x : fi.m_p->m_factories)
255 m_p->m_factories.add(x);
258 g = g->nextRegisterer();
261 ARCCORE_FATAL(
"Infinite loop in DependencyInjection global factories");
269printFactories()
const
271 std::ostringstream ostr;
273 auto f = [&](impl::IInstanceFactory* v) ->
bool {
274 const impl::ConcreteFactoryTypeInfo& cfi = v->concreteFactoryInfo();
275 ostr <<
"I=" << index <<
" " <<
typeid(v).name()
276 <<
"\n interface=" << cfi.interfaceTypeInfo().traceInfo()
277 <<
"\n concrete=" << cfi.concreteTypeInfo().traceInfo()
278 <<
"\n constructor=" << cfi.constructorTypeInfo().traceInfo()
283 FactoryVisitorFunctor ff(f);
284 _iterateFactories(String(), &ff);
285 String s = ostr.str();
293_iterateFactories(
const String& factory_name, IFactoryVisitorFunctor* functor)
const
300 bool has_no_name = factory_name.empty();
301 size_t n = _nbFactory();
302 size_t nb_instance = _nbValue();
303 for (
size_t i = 0; i < n; ++i) {
304 impl::IInstanceFactory* f = _factory(i);
305 size_t nb_constructor_arg = f->nbConstructorArg();
306 if (nb_constructor_arg != nb_instance)
308 if (has_no_name || f->factoryInfoImpl()->hasName(factory_name)) {
309 if (functor->execute(f))
320_iterateInstances(
const std::type_info& t_info,
const String& instance_name,
321 IInstanceVisitorFunctor* lambda)
323 bool has_no_name = instance_name.empty();
324 size_t n = _nbValue();
325 for (
size_t i = 0; i < n; ++i) {
326 IInjectedInstance* ii = _value(i);
327 if (!ii->hasTypeInfo(t_info))
329 if (has_no_name || ii->hasName(instance_name)) {
330 if (lambda->execute(ii))
340_doError(
const TraceInfo& ti,
const String& message)
342 ARCCORE_FATAL(
"Function: {0} : {1}", ti, message);
349_printValidImplementationAndThrow(
const TraceInfo& ti,
350 const String& implementation_name,
351 FactoryFilterFunc filter_func)
357 for (
size_t i = 0, n = _nbFactory(); i < n; ++i) {
358 impl::IInstanceFactory* f = _factory(i);
359 if (filter_func(f)) {
360 f->factoryInfoImpl()->fillWithImplementationNames(valid_names);
363 String message = String::format(
"No implementation named '{0}' found", implementation_name);
367 if (valid_names.
size() == 0)
368 message2 =
" and no implementation is available.";
369 else if (valid_names.
size() == 1)
370 message2 = String::format(
". Valid value is: '{0}'.", valid_names[0]);
373 message2 = String::format(
". Valid values are: '{0}'.", String::join(
", ", valid_names_view));
375 _doError(ti, message + message2);
#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.
Int64 size() const
Retourne la taille du tableau.
Référence à une instance.
Chaîne de caractères unicode.
constexpr __host__ __device__ Integer arccoreCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
Int32 Integer
Type représentant un entier.