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

Scoped service container implementation. More...

#include <service_container.h>

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

Public Member Functions

 service_scope (service_container &parent)
 Construct a scope with a parent container.
 
 ~service_scope () override=default
 Destructor - disposes scoped instances.
 
 service_scope (const service_scope &)=delete
 
service_scopeoperator= (const service_scope &)=delete
 
 service_scope (service_scope &&)=delete
 
service_scopeoperator= (service_scope &&)=delete
 
IServiceContainerparent () override
 Get the parent container.
 
const IServiceContainerparent () const override
 Get the parent container (const).
 
std::unique_ptr< IServiceScopecreate_scope () override
 Create a new service scope.
 
std::vector< service_descriptorregistered_services () const override
 Get list of all registered service descriptors.
 
VoidResult clear () override
 Clear all registrations.
 
- Public Member Functions inherited from kcenon::common::di::IServiceScope
 ~IServiceScope () override=default
 
- Public Member Functions inherited from kcenon::common::di::IServiceContainer
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.
 
template<typename TInterface >
bool is_registered () const
 Check if a service type is registered.
 
template<typename TInterface >
VoidResult unregister ()
 Unregister a service type.
 
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

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) override
 Internal factory registration (type-erased).
 
VoidResult register_instance_internal (std::type_index interface_type, const std::string &type_name, std::shared_ptr< void > instance) override
 Internal instance registration (type-erased).
 
Result< std::shared_ptr< void > > resolve_internal (std::type_index interface_type) override
 Internal service resolution (type-erased).
 
bool is_registered_internal (std::type_index interface_type) const override
 Internal registration check (type-erased).
 
VoidResult unregister_internal (std::type_index interface_type) override
 Internal unregistration (type-erased).
 
- Protected Member Functions inherited from kcenon::common::di::IServiceContainer
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
 

Private Attributes

service_containerparent_
 
std::shared_mutex mutex_
 
std::unordered_map< std::type_index, std::shared_ptr< void > > scoped_instances_
 

Detailed Description

Scoped service container implementation.

A service scope shares singleton registrations with its parent container but maintains its own instances for scoped services. When the scope is destroyed, all scoped instances are disposed.

Thread Safety:

  • service_scope is thread-safe for concurrent resolution.
  • Multiple threads can safely resolve services from the same scope.
  • Uses std::shared_mutex for read/write locking of scoped instances.
  • Recommended usage pattern: one scope per request/thread for best performance.
Note
While thread-safe, creating separate scopes per thread is recommended for optimal performance and natural isolation of scoped instances.

Definition at line 280 of file service_container.h.

Constructor & Destructor Documentation

◆ service_scope() [1/3]

kcenon::common::di::service_scope::service_scope ( service_container & parent)
inlineexplicit

Construct a scope with a parent container.

Parameters
parentReference to the parent container

Definition at line 745 of file service_container.h.

746 : parent_(parent) {}
IServiceContainer & parent() override
Get the parent container.

◆ ~service_scope()

kcenon::common::di::service_scope::~service_scope ( )
overridedefault

Destructor - disposes scoped instances.

◆ service_scope() [2/3]

kcenon::common::di::service_scope::service_scope ( const service_scope & )
delete

◆ service_scope() [3/3]

kcenon::common::di::service_scope::service_scope ( service_scope && )
delete

Member Function Documentation

◆ clear()

VoidResult kcenon::common::di::service_scope::clear ( )
inlineoverridevirtual

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

Implements kcenon::common::di::IServiceContainer.

Definition at line 766 of file service_container.h.

766 {
767 std::unique_lock lock(mutex_);
768 scoped_instances_.clear();
769 return VoidResult::ok({});
770}
static Result< T > ok(U &&value)
Create a successful result with value (static factory)
Definition core.h:223
std::unordered_map< std::type_index, std::shared_ptr< void > > scoped_instances_

References mutex_, kcenon::common::Result< T >::ok(), and scoped_instances_.

Here is the call graph for this function:

◆ create_scope()

std::unique_ptr< IServiceScope > kcenon::common::di::service_scope::create_scope ( )
inlineoverridevirtual

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

Implements kcenon::common::di::IServiceContainer.

Definition at line 756 of file service_container.h.

756 {
757 // Nested scopes share the same root parent
758 return std::make_unique<service_scope>(parent_);
759}

References parent_.

◆ is_registered_internal()

bool kcenon::common::di::service_scope::is_registered_internal ( std::type_index interface_type) const
inlineoverrideprotectedvirtual

Internal registration check (type-erased).

Implements kcenon::common::di::IServiceContainer.

Definition at line 798 of file service_container.h.

798 {
799 return parent_.is_registered_internal(interface_type);
800}
bool is_registered_internal(std::type_index interface_type) const override
Internal registration check (type-erased).

References kcenon::common::di::service_container::is_registered_internal(), and parent_.

Here is the call graph for this function:

◆ operator=() [1/2]

service_scope & kcenon::common::di::service_scope::operator= ( const service_scope & )
delete

◆ operator=() [2/2]

service_scope & kcenon::common::di::service_scope::operator= ( service_scope && )
delete

◆ parent() [1/2]

const IServiceContainer & kcenon::common::di::service_scope::parent ( ) const
inlineoverridevirtual

Get the parent container (const).

Returns
Const reference to the parent container

Implements kcenon::common::di::IServiceScope.

Definition at line 752 of file service_container.h.

752 {
753 return parent_;
754}

References parent_.

◆ parent() [2/2]

IServiceContainer & kcenon::common::di::service_scope::parent ( )
inlineoverridevirtual

Get the parent container.

Returns
Reference to the parent container

Implements kcenon::common::di::IServiceScope.

Definition at line 748 of file service_container.h.

748 {
749 return parent_;
750}

References parent_.

◆ register_factory_internal()

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

Internal factory registration (type-erased).

Implements kcenon::common::di::IServiceContainer.

Definition at line 772 of file service_container.h.

776 {
777 // Delegate to parent
778 return parent_.register_factory_internal(interface_type, type_name, std::move(factory), lifetime);
779}
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) override
Internal factory registration (type-erased).

References parent_, and kcenon::common::di::service_container::register_factory_internal().

Here is the call graph for this function:

◆ register_instance_internal()

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

Internal instance registration (type-erased).

Implements kcenon::common::di::IServiceContainer.

Definition at line 781 of file service_container.h.

784 {
785 // Delegate to parent
786 return parent_.register_instance_internal(interface_type, type_name, std::move(instance));
787}
VoidResult register_instance_internal(std::type_index interface_type, const std::string &type_name, std::shared_ptr< void > instance) override
Internal instance registration (type-erased).

References parent_, and kcenon::common::di::service_container::register_instance_internal().

Here is the call graph for this function:

◆ registered_services()

std::vector< service_descriptor > kcenon::common::di::service_scope::registered_services ( ) const
inlineoverridevirtual

Get list of all registered service descriptors.

Returns
Vector of service descriptors

Implements kcenon::common::di::IServiceContainer.

Definition at line 761 of file service_container.h.

761 {
762 // Return parent's registered services
764}
std::vector< service_descriptor > registered_services() const override
Get list of all registered service descriptors.

References parent_, and kcenon::common::di::service_container::registered_services().

Here is the call graph for this function:

◆ resolve_internal()

Result< std::shared_ptr< void > > kcenon::common::di::service_scope::resolve_internal ( std::type_index interface_type)
inlineoverrideprotectedvirtual

Internal service resolution (type-erased).

Implements kcenon::common::di::IServiceContainer.

Definition at line 789 of file service_container.h.

790 {
791 // Protect scoped_instances_ for thread-safe concurrent resolution.
792 // The mutex is held during the entire resolution to prevent data races
793 // when multiple threads resolve the same scoped service simultaneously.
794 std::unique_lock lock(mutex_);
795 return parent_.resolve_with_detection(interface_type, &scoped_instances_);
796}
Result< std::shared_ptr< void > > resolve_with_detection(std::type_index interface_type, std::unordered_map< std::type_index, std::shared_ptr< void > > *scoped_instances=nullptr)
Resolve a service with circular dependency detection.

References mutex_, parent_, kcenon::common::di::service_container::resolve_with_detection(), and scoped_instances_.

Here is the call graph for this function:

◆ unregister_internal()

VoidResult kcenon::common::di::service_scope::unregister_internal ( std::type_index interface_type)
inlineoverrideprotectedvirtual

Internal unregistration (type-erased).

Implements kcenon::common::di::IServiceContainer.

Definition at line 802 of file service_container.h.

802 {
803 // Delegate to parent
804 return parent_.unregister_internal(interface_type);
805}
VoidResult unregister_internal(std::type_index interface_type) override
Internal unregistration (type-erased).

References parent_, and kcenon::common::di::service_container::unregister_internal().

Here is the call graph for this function:

Member Data Documentation

◆ mutex_

std::shared_mutex kcenon::common::di::service_scope::mutex_
mutableprivate

Definition at line 340 of file service_container.h.

Referenced by clear(), and resolve_internal().

◆ parent_

◆ scoped_instances_

std::unordered_map<std::type_index, std::shared_ptr<void> > kcenon::common::di::service_scope::scoped_instances_
private

Definition at line 341 of file service_container.h.

Referenced by clear(), and resolve_internal().


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