Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
di.cppm
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
16module;
17
18#include <any>
19#include <functional>
20#include <memory>
21#include <mutex>
22#include <string>
23#include <typeindex>
24#include <typeinfo>
25#include <unordered_map>
26
27export module kcenon.common:di;
28
29export namespace kcenon::common::di {
30
31// ============================================================================
32// Service Container Interface
33// ============================================================================
34
40public:
41 virtual ~IServiceContainer() = default;
42
46 template<typename Interface, typename Factory>
47 void register_factory(Factory&& factory);
48
52 template<typename Interface>
53 void register_singleton(std::shared_ptr<Interface> instance);
54
58 template<typename Interface>
59 std::shared_ptr<Interface> resolve();
60
64 template<typename Interface>
65 bool has() const;
66
67protected:
68 virtual void register_impl(std::type_index type, std::any factory) = 0;
69 virtual void register_singleton_impl(std::type_index type, std::any instance) = 0;
70 virtual std::any resolve_impl(std::type_index type) = 0;
71 virtual bool has_impl(std::type_index type) const = 0;
72};
73
74template<typename Interface, typename Factory>
75void IServiceContainer::register_factory(Factory&& factory) {
76 register_impl(std::type_index(typeid(Interface)),
77 std::function<std::shared_ptr<Interface>()>(std::forward<Factory>(factory)));
78}
79
80template<typename Interface>
81void IServiceContainer::register_singleton(std::shared_ptr<Interface> instance) {
82 register_singleton_impl(std::type_index(typeid(Interface)), std::any(instance));
83}
84
85template<typename Interface>
86std::shared_ptr<Interface> IServiceContainer::resolve() {
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}
100
101template<typename Interface>
103 return has_impl(std::type_index(typeid(Interface)));
104}
105
106// ============================================================================
107// Service Container Implementation
108// ============================================================================
109
115public:
116 ServiceContainer() = default;
117
118protected:
119 void register_impl(std::type_index type, std::any factory) override {
120 std::lock_guard<std::mutex> lock(mutex_);
121 factories_[type] = std::move(factory);
122 }
123
124 void register_singleton_impl(std::type_index type, std::any instance) override {
125 std::lock_guard<std::mutex> lock(mutex_);
126 singletons_[type] = std::move(instance);
127 }
128
129 std::any resolve_impl(std::type_index type) override {
130 std::lock_guard<std::mutex> lock(mutex_);
131
132 // Check singletons first
133 auto singleton_it = singletons_.find(type);
134 if (singleton_it != singletons_.end()) {
135 return singleton_it->second;
136 }
137
138 // Check factories
139 auto factory_it = factories_.find(type);
140 if (factory_it != factories_.end()) {
141 return factory_it->second;
142 }
143
144 return std::any{};
145 }
146
147 bool has_impl(std::type_index type) const override {
148 std::lock_guard<std::mutex> lock(mutex_);
149 return singletons_.count(type) > 0 || factories_.count(type) > 0;
150 }
151
152private:
153 mutable std::mutex mutex_;
154 std::unordered_map<std::type_index, std::any> factories_;
155 std::unordered_map<std::type_index, std::any> singletons_;
156};
157
158// ============================================================================
159// Bootstrapper Interface
160// ============================================================================
161
167public:
168 virtual ~IBootstrapper() = default;
169
174 virtual bool initialize() = 0;
175
179 virtual void shutdown() = 0;
180
184 virtual bool is_initialized() const = 0;
185};
186
187} // namespace kcenon::common::di
Interface for system bootstrapping.
Definition di.cppm:166
virtual bool is_initialized() const =0
Check if the system is initialized.
virtual bool initialize()=0
Initialize the system.
virtual void shutdown()=0
Shutdown the system.
Abstract interface for dependency injection containers.
Definition di.cppm:39
bool has() const
Check if a service is registered.
Definition di.cppm:102
virtual std::any resolve_impl(std::type_index type)=0
Result< std::shared_ptr< TInterface > > resolve()
Resolve a service by its interface type.
virtual void register_singleton_impl(std::type_index type, std::any instance)=0
virtual void register_impl(std::type_index type, std::any factory)=0
virtual bool has_impl(std::type_index type) const =0
VoidResult register_factory(TFactory &&factory, service_lifetime lifetime=service_lifetime::singleton)
Register a factory function for creating service instances.
void register_singleton(std::shared_ptr< Interface > instance)
Register a singleton instance.
Definition di.cppm:81
Simple thread-safe service container implementation.
Definition di.cppm:114
void register_singleton_impl(std::type_index type, std::any instance) override
Definition di.cppm:124
std::any resolve_impl(std::type_index type) override
Definition di.cppm:129
bool has_impl(std::type_index type) const override
Definition di.cppm:147
void register_impl(std::type_index type, std::any factory) override
Definition di.cppm:119
std::unordered_map< std::type_index, std::any > singletons_
Definition di.cppm:155
std::unordered_map< std::type_index, std::any > factories_
Definition di.cppm:154