Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ServiceFactory.h
Go to the documentation of this file.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ServiceFactory.h (C) 2000-2025 */
9/* */
10/* Service manufacturing. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_CORE_SERVICEFACTORY_H
13#define ARCANE_CORE_SERVICEFACTORY_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/NotSupportedException.h"
18#include "arcane/utils/TraceInfo.h"
19#include "arcane/utils/ExternalRef.h"
20
21#include "arcane/core/IApplication.h"
22#include "arcane/core/ISession.h"
23#include "arcane/core/ISubDomain.h"
24#include "arcane/core/ServiceBuildInfo.h"
25
26#include "arcane/core/IServiceFactory.h"
27#include "arcane/core/ServiceRegisterer.h"
28#include "arcane/core/ServiceInfo.h"
29#include "arcane/core/IService.h"
31#include "arcane/core/ServiceInstance.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::Internal
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
45class DotNetServiceInstance
46: public IServiceInstance
47{
48 public:
49
50 DotNetServiceInstance(IServiceInfo* si)
51 : m_service_info(si)
52 , m_handle(nullptr)
53 {}
54
55 public:
56
57 void addReference() override { ++m_nb_ref; }
58 void removeReference() override
59 {
60 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
61 if (v == 1)
62 delete this;
63 }
64
65 public:
66
67 IServiceInfo* serviceInfo() const override
68 {
69 return m_service_info;
70 }
71 void setDotNetHandle(ExternalRef handle) { m_handle = handle; }
72 ExternalRef _internalDotNetHandle() const override { return m_handle; }
73
74 private:
75
76 std::atomic<Int32> m_nb_ref = 0;
77 IServiceInfo* m_service_info;
78 ExternalRef m_handle;
79};
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
88template <typename InterfaceType>
89class ServiceInstanceT
90: public IServiceInstanceT<InterfaceType>
91{
92 public:
93
94 ServiceInstanceT(Ref<InterfaceType> i, IServiceInfo* si)
95 : m_instance(i)
96 , m_service_info(si)
97 {}
98
99 public:
100
101 void addReference() override { ++m_nb_ref; }
102 void removeReference() override
103 {
104 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
105 if (v == 1)
106 delete this;
107 }
108
109 public:
110
111 Ref<InterfaceType> instance() override
112 {
113 return m_instance;
114 }
115 IServiceInfo* serviceInfo() const override
116 {
117 return m_service_info;
118 }
119
120 private:
121
122 std::atomic<Int32> m_nb_ref = 0;
123 Ref<InterfaceType> m_instance;
124 IServiceInfo* m_service_info;
125};
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
134class ARCANE_CORE_EXPORT ServiceFactoryInfo
135: public IServiceFactoryInfo
136{
137 public:
138
139 explicit ServiceFactoryInfo(IServiceInfo* si)
140 : m_service_info(si)
141 , m_is_autoload(false)
142 , m_is_singleton(false)
143 {}
144 ~ServiceFactoryInfo() override {}
145
146 public:
147
148 IServiceInfo* serviceInfo() const override { return m_service_info; }
149
150 bool isAutoload() const override { return m_is_autoload; }
151 bool isSingleton() const override { return m_is_singleton; }
152
153 virtual bool isModule() const { return false; }
154 virtual void initializeModuleFactory(ISubDomain*) {}
155 virtual IModule* createModule(ISubDomain*, IMesh*) { return nullptr; }
156
157 public:
158
159 void setAutoload(bool v) { m_is_autoload = v; }
160 void setSingleton(bool v) { m_is_singleton = v; }
161 void initProperties(int v)
162 {
163 if (v & SFP_Singleton)
164 setSingleton(v);
165 if (v & SFP_Autoload)
166 setAutoload(v);
167 }
168 void initProperties() {}
169
170 private:
171
172 IServiceInfo* m_service_info;
173 bool m_is_autoload;
174 bool m_is_singleton;
175};
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
185template <typename InterfaceType>
187{
188 public:
189
190 virtual ~IServiceInterfaceFactory() = default;
191
192 public:
193
196};
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
208template <typename InterfaceType>
209class ServiceFactory2TV2
210: public IServiceFactory2T<InterfaceType>
211{
212 public:
213
214 ServiceFactory2TV2(IServiceInfo* si, IServiceInterfaceFactory<InterfaceType>* sub_factory)
215 : m_service_info(si)
216 , m_sub_factory(sub_factory)
217 , m_type_flags(si->usageType())
218 {
219 }
220
221 ~ServiceFactory2TV2() override
222 {
223 delete m_sub_factory;
224 }
225
227 {
228 return _create(this->createServiceReference(sbi));
229 }
230
231 Ref<InterfaceType> createServiceReference(const ServiceBuildInfoBase& sbi) override
232 {
233 if (!(m_type_flags & sbi.creationType()))
234 return {};
235 return _createReference(sbi);
236 }
237
238 IServiceInfo* serviceInfo() const override
239 {
240 return m_service_info;
241 }
242
243 protected:
244
245 IServiceInfo* m_service_info;
247 int m_type_flags;
248
249 private:
250
251 InterfaceType* _createInstance(const ServiceBuildInfoBase& sbib)
252 {
253 InterfaceType* it = m_sub_factory->createInstance(ServiceBuildInfo(m_service_info, sbib));
254 return it;
255 }
256
257 Ref<InterfaceType> _createReference(const ServiceBuildInfoBase& sbib)
258 {
259 return m_sub_factory->createReference(ServiceBuildInfo(m_service_info, sbib));
260 }
261
262 ServiceInstanceRef _create(Ref<InterfaceType> it)
263 {
264 IServiceInstance* x = (!it) ? nullptr : new ServiceInstanceT<InterfaceType>(it, m_service_info);
265 return ServiceInstanceRef::createRef(x);
266 }
267};
268
269/*---------------------------------------------------------------------------*/
270/*---------------------------------------------------------------------------*/
271
276template <typename ServiceType, typename InterfaceType>
278: public IServiceInterfaceFactory<InterfaceType>
279{
280 public:
281
283 {
284 ServiceType* st = new ServiceType(sbi);
285 st->build();
286 return makeRef<InterfaceType>(st);
287 }
288};
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
295class ARCANE_CORE_EXPORT IServiceInstanceAdder
296{
297 public:
298
299 virtual ~IServiceInstanceAdder() = default;
300 virtual void addInstance(ServiceInstanceRef instance) = 0;
301};
302
303/*---------------------------------------------------------------------------*/
304/*---------------------------------------------------------------------------*/
305
312class ARCANE_CORE_EXPORT SingletonServiceFactoryBase
314{
315 public:
316
317 class ServiceInstance;
318
319 public:
320
321 explicit SingletonServiceFactoryBase(IServiceInfo* si)
322 : m_service_info(si)
323 {}
324
325 public:
326
329
331 IServiceInfo* serviceInfo() const override { return m_service_info; }
332
333 protected:
334
335 virtual ServiceInstanceRef _createInstance(const ServiceBuildInfoBase& sbi, IServiceInstanceAdder* instance_adder) = 0;
336
337 private:
338
339 IServiceInfo* m_service_info;
340};
341
342/*---------------------------------------------------------------------------*/
343/*---------------------------------------------------------------------------*/
344
350template <typename ServiceType, typename... Interfaces>
351class SingletonServiceFactory
352: public SingletonServiceFactoryBase
353{
358 class Helper
359 {
360 public:
361
362 Helper(ServiceType* service, IServiceInfo* si, IServiceInstanceAdder* adder)
363 : m_service(service)
364 , m_service_info(si)
365 , m_adder(adder)
366 {}
367
368 private:
369
371 template <typename InterfaceType> void _create()
372 {
373 InterfaceType* x = m_service;
374 // ATTENTION: the following reference must not destroy 'm_service' because
375 // the latter already has a ServiceReference that was constructed during
376 // the call to _createInstance().
377 auto x_ref = Ref<InterfaceType>::_createNoDestroy(x);
378 auto instance = new ServiceInstanceT<InterfaceType>(x_ref, m_service_info);
379 // TODO: indicate that the reference should not be destroyed.
380 auto instance_ref = ServiceInstanceRef::createRef(instance);
381 m_adder->addInstance(instance_ref);
382 }
383
384 template <typename I1, typename I2, typename... OtherInterfaces>
385 void _create()
386 {
387 _create<I1>();
388 // Apply recursion to the remaining types
389 _create<I2, OtherInterfaces...>();
390 }
391
392 public:
393
394 void createInterfaceInstances()
395 {
396 _create<Interfaces...>();
397 }
398
399 private:
400
401 ServiceType* m_service;
402 IServiceInfo* m_service_info;
403 IServiceInstanceAdder* m_adder;
404 };
405
406 public:
407
408 explicit SingletonServiceFactory(IServiceInfo* si)
409 : SingletonServiceFactoryBase(si)
410 {}
411
412 protected:
413
414 ServiceInstanceRef _createInstance(const ServiceBuildInfoBase& sbib, IServiceInstanceAdder* instance_adder) override
415 {
416 ServiceBuildInfo sbi(serviceInfo(), sbib);
417 ServiceType* st = new ServiceType(sbi);
418 st->build();
419 auto st_ref = makeRef(st);
420 Helper ssf(st, serviceInfo(), instance_adder);
421 ssf.createInterfaceInstances();
422 IServiceInstance* si = new ServiceInstanceT<ServiceType>(st_ref, serviceInfo());
423 return ServiceInstanceRef::createRef(si);
424 }
425};
426
427/*---------------------------------------------------------------------------*/
428/*---------------------------------------------------------------------------*/
429
435template <typename InterfaceType>
436class ServiceInterfaceRegisterer
437{
438 public:
439
440 typedef InterfaceType Interface;
441
442 explicit ServiceInterfaceRegisterer(const char* name)
443 : m_name(name)
444 , m_namespace_name(nullptr)
445 {
446 }
447
448 ServiceInterfaceRegisterer(const char* namespace_name, const char* name)
449 : m_name(name)
450 , m_namespace_name(namespace_name)
451 {
452 }
453
454 public:
455
457 template <typename ServiceType> void
459 {
461 if (m_namespace_name)
462 si->addImplementedInterface(String(m_namespace_name) + String("::") + String(m_name));
463 else
464 si->addImplementedInterface(m_name);
465 si->addFactory(new ServiceFactory2TV2<InterfaceType>(si, factory));
466 }
467
468 private:
469
470 const char* m_name;
471 const char* m_namespace_name;
472};
473
474/*---------------------------------------------------------------------------*/
475/*---------------------------------------------------------------------------*/
476
481template <typename ServiceType>
483{
484 private:
485
487 template <typename InterfaceType> static void
488 _create(ServiceInfo* si, const InterfaceType& i1)
489 {
491 }
492
493 template <typename I1, typename I2, typename... OtherInterfaces>
494 static void _create(ServiceInfo* si, const I1& i1, const I2& i2, const OtherInterfaces&... args)
495 {
496 _create<I1>(si, i1);
497 // Apply recursion to the remaining types
498 _create<I2, OtherInterfaces...>(si, i2, args...);
499 }
500
501 public:
502
504 template <typename... Interfaces> static void
505 registerToServiceInfo(ServiceInfo* si, const Interfaces&... args)
506 {
508 _create(si, args...);
509 }
510};
511
512/*---------------------------------------------------------------------------*/
513/*---------------------------------------------------------------------------*/
514
515} // End namespace Arcane::Internal
516
517/*---------------------------------------------------------------------------*/
518/*---------------------------------------------------------------------------*/
519
538#define ARCANE_SERVICE_INTERFACE(ainterface) \
539 Arcane::Internal::ServiceInterfaceRegisterer<ainterface>(#ainterface)
540
542#define ARCANE_SERVICE_INTERFACE_NS(ainterface_ns, ainterface) \
543 Arcane::Internal::ServiceInterfaceRegisterer<ainterface_ns ::ainterface>(#ainterface_ns, #ainterface)
544
545/*---------------------------------------------------------------------------*/
546/*---------------------------------------------------------------------------*/
547
578#define ARCANE_REGISTER_SERVICE(aclass, a_service_property, ...) \
579 namespace \
580 { \
581 Arcane::IServiceInfo* \
582 ARCANE_JOIN_WITH_LINE(arcaneCreateServiceInfo##aclass)(const Arcane::ServiceProperty& property) \
583 { \
584 auto* si = Arcane::Internal::ServiceInfo::create(property, __FILE__, __LINE__); \
585 Arcane::Internal::ServiceAllInterfaceRegisterer<aclass>::registerToServiceInfo(si, __VA_ARGS__); \
586 return si; \
587 } \
588 } \
589 Arcane::ServiceRegisterer ARCANE_EXPORT ARCANE_JOIN_WITH_LINE(globalServiceRegisterer##aclass)(&ARCANE_JOIN_WITH_LINE(arcaneCreateServiceInfo##aclass), a_service_property)
590
591/*---------------------------------------------------------------------------*/
592/*---------------------------------------------------------------------------*/
593
600#define ARCANE_REGISTER_AXL_SERVICE(aclass, a_service_properties) \
601 namespace \
602 { \
603 Arcane::IServiceInfo* \
604 ARCANE_JOIN_WITH_LINE(arcaneCreateServiceInfo##aclass)(const Arcane::ServiceProperty& properties) \
605 { \
606 Arcane::ServiceInfo* si = Arcane::ServiceInfo::create(properties, __FILE__, __LINE__); \
607 aclass ::fillServiceInfo<aclass>(si); \
608 return si; \
609 } \
610 } \
611 Arcane::ServiceRegisterer ARCANE_EXPORT ARCANE_JOIN_WITH_LINE(globalServiceRegisterer##aclass)(&ARCANE_JOIN_WITH_LINE(arcaneCreateServiceInfo##aclass), a_service_properties)
612
613/*---------------------------------------------------------------------------*/
614/*---------------------------------------------------------------------------*/
615
616/*
617 * The following types and macros are obsolete.
618 *
619 * In the future, only the ARCANE_REGISTER_SERVICE macro will be used.
620 */
621
622/*---------------------------------------------------------------------------*/
623/*---------------------------------------------------------------------------*/
624
625/*---------------------------------------------------------------------------*/
626/*---------------------------------------------------------------------------*/
627
636#define ARCANE_REGISTER_APPLICATION_FACTORY(aclass, ainterface, aname) \
637 ARCANE_REGISTER_SERVICE(aclass, Arcane::ServiceProperty(#aname, Arcane::ST_Application), \
638 ARCANE_SERVICE_INTERFACE(ainterface))
639
640/*---------------------------------------------------------------------------*/
641/*---------------------------------------------------------------------------*/
642
651#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname) \
652 ARCANE_REGISTER_SERVICE(aclass, Arcane::ServiceProperty(#aname, Arcane::ST_SubDomain), \
653 ARCANE_SERVICE_INTERFACE(ainterface))
654
655/*---------------------------------------------------------------------------*/
656/*---------------------------------------------------------------------------*/
657
666#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY4(aclass, ainterface_ns, ainterface, aname) \
667 ARCANE_REGISTER_SERVICE(aclass, Arcane::ServiceProperty(#aname, Arcane::ST_SubDomain), \
668 ARCANE_SERVICE_INTERFACE_NS(ainterface_ns, ainterface))
669
670/*---------------------------------------------------------------------------*/
671/*---------------------------------------------------------------------------*/
672
681#define ARCANE_REGISTER_CASE_OPTIONS_NOAXL_FACTORY(aclass, ainterface, aname) \
682 ARCANE_REGISTER_SERVICE(aclass, Arcane::ServiceProperty(#aname, Arcane::ST_CaseOption), \
683 ARCANE_SERVICE_INTERFACE(ainterface))
684
685/*---------------------------------------------------------------------------*/
686/*---------------------------------------------------------------------------*/
687
696#define ARCANE_REGISTER_CASE_OPTIONS_NOAXL_FACTORY4(aclass, ainterface_ns, ainterface, aname) \
697 ARCANE_REGISTER_SERVICE(aclass, Arcane::ServiceProperty(#aname, Arcane::ST_CaseOption), \
698 ARCANE_SERVICE_INTERFACE_NS(ainterface_ns, ainterface))
699
700/*---------------------------------------------------------------------------*/
701/*---------------------------------------------------------------------------*/
702
703#endif
This file contains the various types and classes for specifying service properties.
Information about a service factory.
Interface for service or module information.
virtual int usageType() const =0
Indicates where the service can be used.
Typed interface managing a service instance.
Definition IService.h:112
Interface of a service instance.
Definition IService.h:69
Interface of the subdomain manager.
Definition ISubDomain.h:75
ExternalRef _internalDotNetHandle() const override
void removeReference() override
Removes a reference.
void addReference() override
Adds a reference.
Management of references to an external object.
Factory for a service implementing the InterfaceType interface.
Interface for a factory function (functor) that creates a service instance corresponding to the Inter...
virtual Ref< InterfaceType > createReference(const ServiceBuildInfo &sbi)=0
Creates an instance of the service.
Class allowing the creation and registration of factories for a service.
static void _create(ServiceInfo *si, const I1 &i1, const I2 &i2, const OtherInterfaces &... args)
Overload for 2 or more interfaces.
static void registerToServiceInfo(ServiceInfo *si, const Interfaces &... args)
Registers the factories for the Interfaces interfaces in the service.
static void _create(ServiceInfo *si, const InterfaceType &i1)
Overload for 1 interface.
IServiceInfo * serviceInfo() const override
Returns the IServiceInfo associated with this factory.
ServiceInstanceRef createServiceInstance(const ServiceBuildInfoBase &sbi) override
Create a service instance from the info in sbi.
IServiceInfo * serviceInfo() const override
Information about the service that can be created by this factory.
bool isSingleton() const override
true if the service is a singleton service (a single instance)
bool isAutoload() const override
true if the service is a module and must be loaded automatically
Information about a service.
Definition ServiceInfo.h:51
void addImplementedInterface(const String &name) override
Adds the name interface name to the interfaces implemented by this service.
void removeReference() override
Removes a reference.
void addReference() override
Adds a reference.
Factory for the ServiceType service for the InterfaceType interface.
Ref< InterfaceType > createReference(const ServiceBuildInfo &sbi) override
Creates an instance of the service.
void registerToServiceInfo(ServiceInfo *si) const
Registers in si a factory to create an instance of the service ServiceType.
Ref< ISingletonServiceInstance > createSingletonServiceInstance(const ServiceBuildInfoBase &sbib) override
Creates a singleton service instance.
IServiceInfo * serviceInfo() const override
Returns the IServiceInfo associated with this factory.
void _create()
Overload for 2 or more interfaces.
Factory for the singleton service of type ServiceType implementing the Interfaces interfaces.
Reference to an instance.
Information for creating a service.
eServiceType creationType() const
Type of service that can be created by this instance.
Structure containing the information to create a service.
Reference to a service instance.
Internal types of Arcane.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.