Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
kcenon::common::di::IServiceContainer Class Referenceabstractexport

Abstract interface for dependency injection containers. More...

#include <service_container_interface.h>

Inheritance diagram for kcenon::common::di::IServiceContainer:
Inheritance graph
Collaboration diagram for kcenon::common::di::IServiceContainer:
Collaboration graph

Public Member Functions

virtual ~IServiceContainer ()=default
 
template<concepts::ServiceInterface TInterface, concepts::ServiceImplementation< TInterface > TImpl>
VoidResult register_type (service_lifetime lifetime=service_lifetime::singleton)
 Register a service type with its implementation.
 
template<typename TInterface >
VoidResult register_instance (std::shared_ptr< TInterface > instance)
 Register a pre-existing instance as a singleton.
 
template<concepts::ServiceInterface TInterface, concepts::ServiceFactory< TInterface > TFactory>
VoidResult register_factory (TFactory &&factory, service_lifetime lifetime=service_lifetime::singleton)
 Register a factory function for creating service instances.
 
template<concepts::ServiceInterface TInterface, concepts::SimpleServiceFactory< TInterface > TFactory>
VoidResult register_simple_factory (TFactory &&factory, service_lifetime lifetime=service_lifetime::singleton)
 Register a simple factory function without container access.
 
template<typename TInterface >
Result< std::shared_ptr< TInterface > > resolve ()
 Resolve a service by its interface type.
 
template<typename TInterface >
std::shared_ptr< TInterface > resolve_or_null ()
 Try to resolve a service, returning nullptr if not found.
 
virtual std::unique_ptr< IServiceScopecreate_scope ()=0
 Create a new service scope.
 
template<typename TInterface >
bool is_registered () const
 Check if a service type is registered.
 
virtual std::vector< service_descriptorregistered_services () const =0
 Get list of all registered service descriptors.
 
template<typename TInterface >
VoidResult unregister ()
 Unregister a service type.
 
virtual VoidResult clear ()=0
 Clear all registrations.
 
virtual ~IServiceContainer ()=default
 
template<typename Interface , typename Factory >
void register_factory (Factory &&factory)
 Register a service with a factory function.
 
template<typename Interface >
void register_singleton (std::shared_ptr< Interface > instance)
 Register a singleton instance.
 
template<typename Interface >
std::shared_ptr< Interface > resolve ()
 Resolve a service by interface type.
 
template<typename Interface >
bool has () const
 Check if a service is registered.
 

Protected Member Functions

virtual VoidResult register_factory_internal (std::type_index interface_type, const std::string &type_name, std::function< std::shared_ptr< void >(IServiceContainer &)> factory, service_lifetime lifetime)=0
 Internal factory registration (type-erased).
 
virtual VoidResult register_instance_internal (std::type_index interface_type, const std::string &type_name, std::shared_ptr< void > instance)=0
 Internal instance registration (type-erased).
 
virtual Result< std::shared_ptr< void > > resolve_internal (std::type_index interface_type)=0
 Internal service resolution (type-erased).
 
virtual bool is_registered_internal (std::type_index interface_type) const =0
 Internal registration check (type-erased).
 
virtual VoidResult unregister_internal (std::type_index interface_type)=0
 Internal unregistration (type-erased).
 
virtual void register_impl (std::type_index type, std::any factory)=0
 
virtual void register_singleton_impl (std::type_index type, std::any instance)=0
 
virtual std::any resolve_impl (std::type_index type)=0
 
virtual bool has_impl (std::type_index type) const =0
 

Detailed Description

Abstract interface for dependency injection containers.

Interface for dependency injection containers.

IServiceContainer provides a type-safe mechanism for registering and resolving services with configurable lifetimes. It supports:

  • Type-based service registration and resolution
  • Factory-based lazy instantiation
  • Instance registration for pre-created objects
  • Scoped containers for request-level isolation

Thread Safety Requirements:

  • All public methods MUST be thread-safe for concurrent access
  • Implementations should use shared_mutex or similar for read/write locking
  • Singleton instantiation must use double-checked locking or equivalent

Error Handling:

  • Registration failures return VoidResult with error details
  • Resolution failures return Result<shared_ptr<T>> with error details
  • Circular dependency detection returns error with cycle information

Usage Example:

auto& container = service_container::global();
// Register services
container.register_factory<ILogger>(
[]() { return std::make_shared<ConsoleLogger>(); },
);
container.register_type<IDatabase, PostgresDatabase>(
);
// Resolve services
auto logger_result = container.resolve<ILogger>();
if (logger_result.is_ok()) {
auto logger = logger_result.value();
logger->info("Service resolved successfully");
}
// Create scoped container
auto scope = container.create_scope();
auto db = scope->resolve<IDatabase>().value();
// db instance is unique to this scope
static service_container & global()
Get the global service container instance.
@ singleton
Single instance shared globally.
@ scoped
Single instance within a scope.
Examples
service_container_example.cpp.

Definition at line 39 of file di.cppm.

Constructor & Destructor Documentation

◆ ~IServiceContainer() [1/2]

virtual kcenon::common::di::IServiceContainer::~IServiceContainer ( )
virtualdefault

◆ ~IServiceContainer() [2/2]

virtual kcenon::common::di::IServiceContainer::~IServiceContainer ( )
exportvirtualdefault

Member Function Documentation

◆ clear()

virtual VoidResult kcenon::common::di::IServiceContainer::clear ( )
pure virtual

Clear all registrations.

Removes all service registrations. Existing resolved instances remain valid but no services can be resolved after this call.

Returns
VoidResult - error if the container is frozen, ok otherwise

Implemented in kcenon::common::di::service_container, and kcenon::common::di::service_scope.

◆ create_scope()

virtual std::unique_ptr< IServiceScope > kcenon::common::di::IServiceContainer::create_scope ( )
pure virtual

Create a new service scope.

Returns a scoped container that shares singleton registrations with the parent but maintains its own instances for scoped services.

Returns
Unique pointer to the new scope

Implemented in kcenon::common::di::service_container, and kcenon::common::di::service_scope.

◆ has()

template<typename Interface >
bool kcenon::common::di::IServiceContainer::has ( ) const
export

Check if a service is registered.

Definition at line 102 of file di.cppm.

102 {
103 return has_impl(std::type_index(typeid(Interface)));
104}
virtual bool has_impl(std::type_index type) const =0

References has_impl().

Here is the call graph for this function:

◆ has_impl()

virtual bool kcenon::common::di::IServiceContainer::has_impl ( std::type_index type) const
exportprotectedpure virtual

Implemented in kcenon::common::di::ServiceContainer.

Referenced by has().

Here is the caller graph for this function:

◆ is_registered()

template<typename TInterface >
bool kcenon::common::di::IServiceContainer::is_registered ( ) const
inline

Check if a service type is registered.

Template Parameters
TInterfaceThe interface type to check
Returns
true if registered, false otherwise

Definition at line 371 of file service_container_interface.h.

371 {
372 return is_registered_internal(std::type_index(typeid(TInterface)));
373 }
virtual bool is_registered_internal(std::type_index interface_type) const =0
Internal registration check (type-erased).

References is_registered_internal().

Here is the call graph for this function:

◆ is_registered_internal()

virtual bool kcenon::common::di::IServiceContainer::is_registered_internal ( std::type_index interface_type) const
protectedpure virtual

Internal registration check (type-erased).

Implemented in kcenon::common::di::service_container, and kcenon::common::di::service_scope.

Referenced by is_registered().

Here is the caller graph for this function:

◆ register_factory() [1/2]

template<typename Interface , typename Factory >
void kcenon::common::di::IServiceContainer::register_factory ( Factory && factory)
export

Register a service with a factory function.

Definition at line 75 of file di.cppm.

75 {
76 register_impl(std::type_index(typeid(Interface)),
77 std::function<std::shared_ptr<Interface>()>(std::forward<Factory>(factory)));
78}
virtual void register_impl(std::type_index type, std::any factory)=0

References register_impl().

Here is the call graph for this function:

◆ register_factory() [2/2]

template<concepts::ServiceInterface TInterface, concepts::ServiceFactory< TInterface > TFactory>
VoidResult kcenon::common::di::IServiceContainer::register_factory ( TFactory && factory,
service_lifetime lifetime = service_lifetime::singleton )
inline

Register a factory function for creating service instances.

The factory is called each time the service needs to be instantiated (once for singleton, each time for transient, once per scope for scoped). The factory receives a reference to the container for resolving dependencies.

Template Parameters
TInterfaceThe interface type to register (must satisfy ServiceInterface)
TFactoryCallable returning shared_ptr<TInterface> (must satisfy ServiceFactory)
Parameters
factoryFactory function: (IServiceContainer&) -> shared_ptr<TInterface>
lifetimeLifetime policy for the service
Returns
VoidResult indicating success or registration error
Note
Uses C++20 concepts for compile-time type validation.

Definition at line 263 of file service_container_interface.h.

264 {
266 std::type_index(typeid(TInterface)),
267 typeid(TInterface).name(),
268 [f = std::forward<TFactory>(factory)](IServiceContainer& c) -> std::shared_ptr<void> {
269 return std::static_pointer_cast<void>(f(c));
270 },
271 lifetime
272 );
273 }
virtual VoidResult register_factory_internal(std::type_index interface_type, const std::string &type_name, std::function< std::shared_ptr< void >(IServiceContainer &)> factory, service_lifetime lifetime)=0
Internal factory registration (type-erased).

References register_factory_internal().

Here is the call graph for this function:

◆ register_factory_internal()

virtual VoidResult kcenon::common::di::IServiceContainer::register_factory_internal ( std::type_index interface_type,
const std::string & type_name,
std::function< std::shared_ptr< void >(IServiceContainer &)> factory,
service_lifetime lifetime )
protectedpure virtual

Internal factory registration (type-erased).

Implemented in kcenon::common::di::service_container, and kcenon::common::di::service_scope.

Referenced by register_factory(), register_simple_factory(), and register_type().

Here is the caller graph for this function:

◆ register_impl()

virtual void kcenon::common::di::IServiceContainer::register_impl ( std::type_index type,
std::any factory )
exportprotectedpure virtual

Implemented in kcenon::common::di::ServiceContainer.

Referenced by register_factory().

Here is the caller graph for this function:

◆ register_instance()

template<typename TInterface >
VoidResult kcenon::common::di::IServiceContainer::register_instance ( std::shared_ptr< TInterface > instance)
inline

Register a pre-existing instance as a singleton.

The provided instance will be returned for all resolution requests. The container takes shared ownership of the instance.

Template Parameters
TInterfaceThe interface type to register
Parameters
instanceThe instance to register
Returns
VoidResult indicating success or registration error

Definition at line 230 of file service_container_interface.h.

230 {
231 if (!instance) {
234 "Cannot register null instance",
235 "di::IServiceContainer"
236 );
237 }
238
240 std::type_index(typeid(TInterface)),
241 typeid(TInterface).name(),
242 std::static_pointer_cast<void>(instance)
243 );
244 }
virtual VoidResult register_instance_internal(std::type_index interface_type, const std::string &type_name, std::shared_ptr< void > instance)=0
Internal instance registration (type-erased).
constexpr int INVALID_ARGUMENT
Definition compat.h:31
Result< T > make_error(int code, const std::string &message, const std::string &module="")
Create an error result with code and message.
Definition utilities.h:91

References kcenon::common::error_codes::INVALID_ARGUMENT, kcenon::common::make_error(), and register_instance_internal().

Here is the call graph for this function:

◆ register_instance_internal()

virtual VoidResult kcenon::common::di::IServiceContainer::register_instance_internal ( std::type_index interface_type,
const std::string & type_name,
std::shared_ptr< void > instance )
protectedpure virtual

Internal instance registration (type-erased).

Implemented in kcenon::common::di::service_container, and kcenon::common::di::service_scope.

Referenced by register_instance().

Here is the caller graph for this function:

◆ register_simple_factory()

template<concepts::ServiceInterface TInterface, concepts::SimpleServiceFactory< TInterface > TFactory>
VoidResult kcenon::common::di::IServiceContainer::register_simple_factory ( TFactory && factory,
service_lifetime lifetime = service_lifetime::singleton )
inline

Register a simple factory function without container access.

Convenience overload for factories that don't need to resolve dependencies.

Template Parameters
TInterfaceThe interface type to register (must satisfy ServiceInterface)
TFactoryCallable returning shared_ptr<TInterface> (must satisfy SimpleServiceFactory)
Parameters
factoryFactory function: () -> shared_ptr<TInterface>
lifetimeLifetime policy for the service
Returns
VoidResult indicating success or registration error
Note
Uses C++20 concepts for compile-time type validation.

Definition at line 290 of file service_container_interface.h.

291 {
293 std::type_index(typeid(TInterface)),
294 typeid(TInterface).name(),
295 [f = std::forward<TFactory>(factory)](IServiceContainer&) -> std::shared_ptr<void> {
296 return std::static_pointer_cast<void>(f());
297 },
298 lifetime
299 );
300 }

References register_factory_internal().

Here is the call graph for this function:

◆ register_singleton()

template<typename Interface >
void kcenon::common::di::IServiceContainer::register_singleton ( std::shared_ptr< Interface > instance)
export

Register a singleton instance.

Definition at line 81 of file di.cppm.

81 {
82 register_singleton_impl(std::type_index(typeid(Interface)), std::any(instance));
83}
virtual void register_singleton_impl(std::type_index type, std::any instance)=0

References register_singleton_impl().

Here is the call graph for this function:

◆ register_singleton_impl()

virtual void kcenon::common::di::IServiceContainer::register_singleton_impl ( std::type_index type,
std::any instance )
exportprotectedpure virtual

Implemented in kcenon::common::di::ServiceContainer.

Referenced by register_singleton().

Here is the caller graph for this function:

◆ register_type()

template<concepts::ServiceInterface TInterface, concepts::ServiceImplementation< TInterface > TImpl>
VoidResult kcenon::common::di::IServiceContainer::register_type ( service_lifetime lifetime = service_lifetime::singleton)
inline

Register a service type with its implementation.

Creates a factory that constructs TImpl instances when TInterface is resolved. TImpl must be constructible with no arguments or with dependencies that are also registered in the container.

Template Parameters
TInterfaceThe interface type to register (must satisfy ServiceInterface)
TImplThe implementation type (must satisfy ServiceImplementation)
Parameters
lifetimeLifetime policy for the service
Returns
VoidResult indicating success or registration error
Note
TImpl must have a default constructor or use register_factory for types requiring constructor arguments.
Uses C++20 concepts for compile-time type validation.

Definition at line 207 of file service_container_interface.h.

207 {
208
210 std::type_index(typeid(TInterface)),
211 typeid(TInterface).name(),
212 [](IServiceContainer&) -> std::shared_ptr<void> {
213 return std::make_shared<TImpl>();
214 },
215 lifetime
216 );
217 }

References register_factory_internal().

Here is the call graph for this function:

◆ registered_services()

virtual std::vector< service_descriptor > kcenon::common::di::IServiceContainer::registered_services ( ) const
pure virtual

Get list of all registered service descriptors.

Returns
Vector of service descriptors

Implemented in kcenon::common::di::service_container, and kcenon::common::di::service_scope.

◆ resolve() [1/2]

template<typename TInterface >
Result< std::shared_ptr< TInterface > > kcenon::common::di::IServiceContainer::resolve ( )
inline

Resolve a service by its interface type.

Returns a shared pointer to the service instance. For singletons, returns the cached instance. For transient, creates a new instance. For scoped, returns the instance for the current scope.

Template Parameters
TInterfaceThe interface type to resolve
Returns
Result containing the service or an error

Possible errors:

  • NOT_FOUND: Service not registered
  • INTERNAL_ERROR: Circular dependency detected
  • INTERNAL_ERROR: Factory threw an exception

Definition at line 320 of file service_container_interface.h.

320 {
321 auto result = resolve_internal(std::type_index(typeid(TInterface)));
322
323 if (result.is_err()) {
324 return make_error<std::shared_ptr<TInterface>>(result.error());
325 }
326
327 return Result<std::shared_ptr<TInterface>>::ok(
328 std::static_pointer_cast<TInterface>(result.value())
329 );
330 }
virtual Result< std::shared_ptr< void > > resolve_internal(std::type_index interface_type)=0
Internal service resolution (type-erased).
VoidResult ok()
Create a successful void result.
Definition utilities.h:71

References kcenon::common::make_error(), kcenon::common::ok(), and resolve_internal().

Referenced by resolve_or_null().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resolve() [2/2]

template<typename Interface >
std::shared_ptr< Interface > kcenon::common::di::IServiceContainer::resolve ( )
export

Resolve a service by interface type.

Definition at line 86 of file di.cppm.

86 {
87 auto result = resolve_impl(std::type_index(typeid(Interface)));
88 if (result.has_value()) {
89 try {
90 // Try singleton first
91 return std::any_cast<std::shared_ptr<Interface>>(result);
92 } catch (const std::bad_any_cast&) {
93 // Try factory
94 auto factory = std::any_cast<std::function<std::shared_ptr<Interface>()>>(result);
95 return factory();
96 }
97 }
98 return nullptr;
99}
virtual std::any resolve_impl(std::type_index type)=0

References resolve_impl().

Here is the call graph for this function:

◆ resolve_impl()

virtual std::any kcenon::common::di::IServiceContainer::resolve_impl ( std::type_index type)
exportprotectedpure virtual

Implemented in kcenon::common::di::ServiceContainer.

Referenced by resolve().

Here is the caller graph for this function:

◆ resolve_internal()

virtual Result< std::shared_ptr< void > > kcenon::common::di::IServiceContainer::resolve_internal ( std::type_index interface_type)
protectedpure virtual

Internal service resolution (type-erased).

Implemented in kcenon::common::di::service_container, and kcenon::common::di::service_scope.

Referenced by resolve().

Here is the caller graph for this function:

◆ resolve_or_null()

template<typename TInterface >
std::shared_ptr< TInterface > kcenon::common::di::IServiceContainer::resolve_or_null ( )
inline

Try to resolve a service, returning nullptr if not found.

Unlike resolve(), this method does not return an error for unregistered services. Use when the service is optional.

Template Parameters
TInterfaceThe interface type to resolve
Returns
Shared pointer to service or nullptr if not registered

Definition at line 342 of file service_container_interface.h.

342 {
343 auto result = resolve<TInterface>();
344 if (result.is_ok()) {
345 return result.value();
346 }
347 return nullptr;
348 }
Result< std::shared_ptr< TInterface > > resolve()
Resolve a service by its interface type.

References resolve().

Here is the call graph for this function:

◆ unregister()

template<typename TInterface >
VoidResult kcenon::common::di::IServiceContainer::unregister ( )
inline

Unregister a service type.

Removes the registration for the specified interface. Existing resolved instances remain valid but no new instances can be resolved.

Template Parameters
TInterfaceThe interface type to unregister
Returns
VoidResult indicating success or error

Definition at line 392 of file service_container_interface.h.

392 {
393 return unregister_internal(std::type_index(typeid(TInterface)));
394 }
virtual VoidResult unregister_internal(std::type_index interface_type)=0
Internal unregistration (type-erased).

References unregister_internal().

Here is the call graph for this function:

◆ unregister_internal()

virtual VoidResult kcenon::common::di::IServiceContainer::unregister_internal ( std::type_index interface_type)
protectedpure virtual

Internal unregistration (type-erased).

Implemented in kcenon::common::di::service_container, and kcenon::common::di::service_scope.

Referenced by unregister().

Here is the caller graph for this function:

The documentation for this class was generated from the following files: