From 65f624a3552e6a7284398a14c6b96b31cd3ea75c Mon Sep 17 00:00:00 2001 From: Samuele Lorefice Date: Wed, 1 Oct 2025 19:03:53 +0200 Subject: [PATCH] Exposes `GetService(Type, obiect[]? args)` and it's safer variant `TryGetService()` to enable consumers to request a service without needing to do reflection work themselves. bumps version to 0.0.1.8-alpha --- Syrette/ServiceContainer.cs | 32 +++++++++++++++++++++++--------- Syrette/ServiceDescriptor.cs | 4 ++++ Syrette/Syrette.csproj | 2 +- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Syrette/ServiceContainer.cs b/Syrette/ServiceContainer.cs index 181930a..39ca0ab 100644 --- a/Syrette/ServiceContainer.cs +++ b/Syrette/ServiceContainer.cs @@ -153,12 +153,17 @@ public class ServiceContainer { }); return this; } - - // you can't call generic methods with an unknown type at compile time - // so we use reflection to call the generic GetService method with the provided type - // Basically we build the method GetService() at runtime and then call it. - // "Classic black magic sorcery" in reflection. - private object GetService(Type serviceType, object[]? args = null) { + + /// + /// Resolves and returns an instance of the requested service type. + /// + /// Type of the service that's being requested + /// arguments to pass to the constructor of the service + /// you can't call generic methods with an unknown type at compile time + /// so we use reflection to call the generic GetService{T} method with the provided + /// type Basically we build the method GetService{serviceType}() at runtime and then call it. + /// An object that is the instantiated service type + public object GetService(Type serviceType, object[]? args = null) { List arguments = [serviceType]; if (args != null) arguments.AddRange(args.ToList().Select(a => a.GetType())); @@ -170,11 +175,20 @@ public class ServiceContainer { return method.Invoke(this, args)!; } - private object? TryGetService(Type serviceType, object[]? args = null) { + /// + /// tries to resolve and return an instance of the requested service type. Returns null if it fails. + /// + /// Type of the service that's being requested + /// arguments to pass to the constructor of the service + /// you can't call generic methods with an unknown type at compile time + /// so we use reflection to call the generic GetService{T} method with the provided + /// type Basically we build the method GetService{serviceType}() at runtime and then call it. + /// An object that is the instantiated service type or null if not found + public object? TryGetService(Type serviceType, object[]? args = null) { try { return GetService(serviceType, args); } catch { - return null!; + return null; } } @@ -226,7 +240,7 @@ public class ServiceContainer { singletons[descriptor.ServiceType] = newSingleton!; return newSingleton; } - + private TInterface Instantiate(ServiceDescriptor descriptor, ConstructorInfo? ctor = null) { if (ctor == null && descriptor.ImplementationType.GetConstructors().Length > 1) throw new Exception($"Multiple constructors found for type {descriptor.ImplementationType}. Please provide a specific constructor."); diff --git a/Syrette/ServiceDescriptor.cs b/Syrette/ServiceDescriptor.cs index bb13483..8644b1b 100644 --- a/Syrette/ServiceDescriptor.cs +++ b/Syrette/ServiceDescriptor.cs @@ -25,6 +25,10 @@ public class ServiceDescriptor /// public List? Arguments { get; init; } + /// + /// Returns a string with the specific type of service, its implementation, and its lifetime. + /// + /// {implementation Name} as {Service Name} ({Lifetime}) public override string ToString() { return $"{ImplementationType.Name} as {ServiceType.Name} ({Lifetime})"; } diff --git a/Syrette/Syrette.csproj b/Syrette/Syrette.csproj index 91f27d8..3df761a 100644 --- a/Syrette/Syrette.csproj +++ b/Syrette/Syrette.csproj @@ -9,7 +9,7 @@ latest enable enable - 0.0.1.7-alpha + 0.0.1.8-alpha Syrette Lorefice Samuele Syrette is a minimalistic dependency injection library for C#. It aims to provide a simple and efficient way to achieve dependency injections in your applications without the overhead of larger frameworks.