Liar's Dice 0.1
Loading...
Searching...
No Matches
service_container.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <concepts>
4#include <functional>
5#include <iostream>
6#include <memory>
7#include <stdexcept>
8#include <typeindex>
9#include <typeinfo>
10#include <unordered_map>
11
12namespace liarsdice::di {
13
14 // Service lifetime management
15 enum class ServiceLifetime {
16 Transient, // New instance every time
17 Singleton, // Single instance for application lifetime
18 Scoped // Single instance per scope (future use)
19 };
20
21 // Stream operator for ServiceLifetime (needed for Boost.Test)
23 switch (lifetime) {
24 case ServiceLifetime::Transient:
25 return os << "Transient";
26 case ServiceLifetime::Singleton:
27 return os << "Singleton";
28 case ServiceLifetime::Scoped:
29 return os << "Scoped";
30 default:
31 return os << "Unknown";
32 }
33 }
34
35 // Exception for DI container errors
37 public:
38 explicit ServiceContainerException(const std::string& message)
39 : std::runtime_error("ServiceContainer: " + message) {}
40 };
41
42 // Factory function type
43 template <typename T> using ServiceFactory = std::function<std::shared_ptr<T>()>;
44
45 // ServiceContainer implementation
47 public:
48 ServiceContainer() = default;
49 ~ServiceContainer() = default;
50
51 // Non-copyable, non-movable (singleton pattern)
56
57 // Register a service with factory function
58 template <typename TInterface, typename TImplementation>
60 static_assert(std::is_base_of_v<TInterface, TImplementation>,
61 "TImplementation must inherit from TInterface");
62
63 auto factory
64 = []() -> std::shared_ptr<TInterface> { return std::make_shared<TImplementation>(); };
65
66 register_factory<TInterface>(std::move(factory), lifetime);
67 }
68
69 // Register with custom factory
70 template <typename TInterface>
71 void register_factory(ServiceFactory<TInterface> factory,
73 auto type_id = std::type_index(typeid(TInterface));
74
75 ServiceInfo info;
76 info.lifetime = lifetime;
77 info.factory = [factory]() -> std::shared_ptr<void> {
78 return std::static_pointer_cast<void>(factory());
79 };
80
81 services_[type_id] = std::move(info);
82 }
83
84 // Register singleton instance
85 template <typename TInterface> void register_instance(std::shared_ptr<TInterface> instance) {
86 auto type_id = std::type_index(typeid(TInterface));
87
88 ServiceInfo info;
90 info.instance = std::static_pointer_cast<void>(instance);
91
92 services_[type_id] = std::move(info);
93 }
94
95 // Resolve service
96 template <typename T> std::shared_ptr<T> resolve() {
97 auto type_id = std::type_index(typeid(T));
98
99 auto it = services_.find(type_id);
100 if (it == services_.end()) {
101 throw ServiceContainerException("Service not registered: " + std::string(typeid(T).name()));
102 }
103
104 auto& info = it->second;
105
106 switch (info.lifetime) {
107 case ServiceLifetime::Singleton:
108 if (!info.instance && info.factory) {
109 info.instance = info.factory();
110 }
111 return std::static_pointer_cast<T>(info.instance);
112
113 case ServiceLifetime::Transient:
114 if (!info.factory) {
115 throw ServiceContainerException("No factory for transient service: "
116 + std::string(typeid(T).name()));
117 }
118 return std::static_pointer_cast<T>(info.factory());
119
120 case ServiceLifetime::Scoped:
121 // For now, treat as singleton (future enhancement)
122 if (!info.instance && info.factory) {
123 info.instance = info.factory();
124 }
125 return std::static_pointer_cast<T>(info.instance);
126 }
127
128 throw ServiceContainerException("Failed to resolve service: "
129 + std::string(typeid(T).name()));
130 }
131
132 // Check if service is registered
133 template <typename T> bool is_registered() const {
134 auto type_id = std::type_index(typeid(T));
135 return services_.find(type_id) != services_.end();
136 }
137
138 // Clear all services
139 void clear() { services_.clear(); }
140
141 // Get service count
142 size_t service_count() const { return services_.size(); }
143
144 private:
145 struct ServiceInfo {
148 mutable std::shared_ptr<void> instance; // mutable for lazy singleton creation
149 };
150
152 };
153
154 // Global container instance (singleton)
156
157// Convenience macros for dependency injection
158#define REGISTER_SERVICE(container, interface, implementation)
159 container.register_service<interface, implementation>()
160
161#define REGISTER_SINGLETON(container, interface, implementation)
162 container.register_service<interface, implementation>(ServiceLifetime::Singleton)
163
164#define RESOLVE_SERVICE(container, type) container.resolve<type>()
165
166} // namespace liarsdice::di
Definition service_container.hpp:36
ServiceContainerException(const std::string &message)
Definition service_container.hpp:38
Definition service_container.hpp:46
void register_factory(ServiceFactory< TInterface > factory, ServiceLifetime lifetime=ServiceLifetime::Transient)
Definition service_container.hpp:71
std::unordered_map< std::type_index, ServiceInfo > services_
Definition service_container.hpp:151
ServiceContainer(ServiceContainer &&)=delete
size_t service_count() const
Definition service_container.hpp:142
void clear()
Definition service_container.hpp:139
ServiceContainer(const ServiceContainer &)=delete
ServiceContainer & operator=(ServiceContainer &&)=delete
void register_instance(std::shared_ptr< TInterface > instance)
Definition service_container.hpp:85
ServiceContainer & operator=(const ServiceContainer &)=delete
std::shared_ptr< T > resolve()
Definition service_container.hpp:96
bool is_registered() const
Definition service_container.hpp:133
void register_service(ServiceLifetime lifetime=ServiceLifetime::Transient)
Definition service_container.hpp:59
Dependency injection framework.
Definition service_container.cpp:3
ServiceLifetime
Definition service_container.hpp:15
ServiceContainer & get_service_container()
Definition service_container.cpp:5
std::ostream & operator<<(std::ostream &os, ServiceLifetime lifetime)
Definition service_container.hpp:22
Definition service_container.hpp:145
std::function< std::shared_ptr< void >()> factory
Definition service_container.hpp:147
ServiceLifetime lifetime
Definition service_container.hpp:146
std::shared_ptr< void > instance
Definition service_container.hpp:148