5#include <unordered_map>
11 enum class ServiceLifetime {
40 template <
typename Interface,
typename Implementation = Interface>
42 requires(std::is_base_of_v<Interface, Implementation>)
44 RegisterInstanceInternal(std::type_index(
typeid(Interface)), instance);
50 template <
typename Interface>
52 std::function<std::shared_ptr<Interface>()> factory,
53 ServiceLifetime lifetime = ServiceLifetime::Transient
55 RegisterFactoryInternal(
56 std::type_index(
typeid(Interface)),
57 [factory]() -> std::shared_ptr<void> {
return factory(); },
65 template <
typename Interface,
typename Implementation = Interface>
66 void RegisterType(ServiceLifetime lifetime = ServiceLifetime::Transient)
67 requires(std::is_base_of_v<Interface, Implementation> && std::is_default_constructible_v<Implementation>)
69 RegisterFactory<Interface>([]() {
return std::make_shared<Implementation>(); }, lifetime);
75 template <
typename Interface,
typename Implementation,
typename... Dependencies>
77 std::function<std::shared_ptr<Implementation>(Dependencies...)> constructor,
78 ServiceLifetime lifetime = ServiceLifetime::Transient
80 requires(std::is_base_of_v<Interface, Implementation>)
82 RegisterFactory<Interface>(
83 [
this, constructor]() -> std::shared_ptr<Interface> {
84 return constructor(Resolve<Dependencies>()...);
93 template <
typename Interface,
typename Implementation = Interface>
95 requires(std::is_base_of_v<Interface, Implementation>)
97 auto type = std::type_index(
typeid(Interface));
98 if (!IsRegisteredInternal(type)) {
99 RegisterInstanceInternal(type, instance);
106 template <
typename Interface>
108 std::function<std::shared_ptr<Interface>()> factory,
109 ServiceLifetime lifetime = ServiceLifetime::Transient
111 auto type = std::type_index(
typeid(Interface));
112 if (!IsRegisteredInternal(type)) {
113 RegisterFactoryInternal(
115 [factory]() -> std::shared_ptr<void> {
return factory(); },
124 template <
typename Interface,
typename Implementation = Interface>
126 requires(std::is_base_of_v<Interface, Implementation> && std::is_default_constructible_v<Implementation>)
128 RegisterFactoryIfMissing<Interface>(
129 []() {
return std::make_shared<Implementation>(); },
137 template <
typename Interface,
typename Implementation,
typename... Dependencies>
139 std::function<std::shared_ptr<Implementation>(Dependencies...)> constructor,
140 ServiceLifetime lifetime = ServiceLifetime::Transient
142 requires(std::is_base_of_v<Interface, Implementation>)
144 RegisterFactoryIfMissing<Interface>(
145 [
this, constructor]() -> std::shared_ptr<Interface> {
146 return constructor(Resolve<Dependencies>()...);
159 template <
typename Interface>
160 [[nodiscard]] std::shared_ptr<Interface>
Resolve()
const {
161 return std::static_pointer_cast<Interface>(
162 ResolveInternal(std::type_index(
typeid(Interface)))
169 template <
typename Interface>
170 [[nodiscard]] std::shared_ptr<Interface>
TryResolve() const noexcept {
171 auto result = TryResolveInternal(std::type_index(
typeid(Interface)));
172 return result ? std::static_pointer_cast<Interface>(result) :
nullptr;
178 template <
typename Interface>
180 return IsRegisteredInternal(std::type_index(
typeid(Interface)));
215 template <
typename Interface,
typename Implementation = Interface>
217 _locator.RegisterType<Interface, Implementation>(ServiceLifetime::Singleton);
221 template <
typename Interface>
222 ServiceBuilder& AddSingleton(std::shared_ptr<Interface> instance) {
223 _locator.RegisterInstance<Interface>(std::move(instance));
227 template <
typename Interface,
typename Implementation = Interface>
229 _locator.RegisterType<Interface, Implementation>(ServiceLifetime::Transient);
233 template <
typename Interface>
234 ServiceBuilder& AddFactory(std::function<std::shared_ptr<Interface>()> factory) {
235 _locator.RegisterFactory<Interface>(std::move(factory));
247 void RegisterInstanceInternal(std::type_index type, std::shared_ptr<void> instance);
248 void RegisterFactoryInternal(
249 std::type_index type,
250 std::function<std::shared_ptr<void>()> factory,
251 ServiceLifetime lifetime
253 [[nodiscard]] std::shared_ptr<void> ResolveInternal(std::type_index type)
const;
254 [[nodiscard]] std::shared_ptr<void> TryResolveInternal(std::type_index type)
const noexcept;
255 [[nodiscard]]
bool IsRegisteredInternal(std::type_index type)
const;
258 PLUGIFY_ACCESS :
struct Impl;
259 PLUGIFY_NO_DLL_EXPORT_WARNING(std::unique_ptr<Impl> _impl;)
DI Container / Service Locator with PIMPL.
void EndScope()
End current scope.
void RegisterFactory(std::function< std::shared_ptr< Interface >()> factory, ServiceLifetime lifetime=ServiceLifetime::Transient)
Register a factory function.
void RegisterWithDependencies(std::function< std::shared_ptr< Implementation >(Dependencies...)> constructor, ServiceLifetime lifetime=ServiceLifetime::Transient)
Register with dependency injection.
std::shared_ptr< Interface > TryResolve() const noexcept
Try to resolve a service (returns nullptr if not found)
std::shared_ptr< Interface > Resolve() const
Resolve a service.
void RegisterInstanceIfMissing(std::shared_ptr< Implementation > instance)
Register a concrete instance if missing (singleton)
void RegisterTypeIfMissing(ServiceLifetime lifetime=ServiceLifetime::Transient)
Register a type with automatic construction.
void RegisterWithDependenciesIfMissing(std::function< std::shared_ptr< Implementation >(Dependencies...)> constructor, ServiceLifetime lifetime=ServiceLifetime::Transient)
Register with dependency injection.
bool IsRegistered() const
Check if a service is registered.
void RegisterFactoryIfMissing(std::function< std::shared_ptr< Interface >()> factory, ServiceLifetime lifetime=ServiceLifetime::Transient)
Register a factory function.
void BeginScope()
Create a new scope (for scoped services)
size_t Count() const
Get the number of registered services.
void RegisterType(ServiceLifetime lifetime=ServiceLifetime::Transient)
Register a type with automatic construction.
void Clear()
Clear all registrations.
void RegisterInstance(std::shared_ptr< Implementation > instance)
Register a concrete instance (singleton)