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.
All checks were successful
Nuget Pkg Build / build (push) Successful in 1m11s
All checks were successful
Nuget Pkg Build / build (push) Successful in 1m11s
bumps version to 0.0.1.8-alpha
This commit is contained in:
@@ -153,12 +153,17 @@ public class ServiceContainer {
|
|||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// you can't call generic methods with an unknown type at compile time
|
/// <summary>
|
||||||
// so we use reflection to call the generic GetService<T> method with the provided type
|
/// Resolves and returns an instance of the requested service type.
|
||||||
// Basically we build the method GetService<serviceType>() at runtime and then call it.
|
/// </summary>
|
||||||
// "Classic black magic sorcery" in reflection.
|
/// <param name="serviceType">Type of the service that's being requested</param>
|
||||||
private object GetService(Type serviceType, object[]? args = null) {
|
/// <param name="args">arguments to pass to the constructor of the service</param>
|
||||||
|
/// <remarks> 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.</remarks>
|
||||||
|
/// <returns>An object that is the instantiated service type</returns>
|
||||||
|
public object GetService(Type serviceType, object[]? args = null) {
|
||||||
List<Type> arguments = [serviceType];
|
List<Type> arguments = [serviceType];
|
||||||
|
|
||||||
if (args != null) arguments.AddRange(args.ToList().Select(a => a.GetType()));
|
if (args != null) arguments.AddRange(args.ToList().Select(a => a.GetType()));
|
||||||
@@ -170,11 +175,20 @@ public class ServiceContainer {
|
|||||||
return method.Invoke(this, args)!;
|
return method.Invoke(this, args)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
private object? TryGetService(Type serviceType, object[]? args = null) {
|
/// <summary>
|
||||||
|
/// tries to resolve and return an instance of the requested service type. Returns null if it fails.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="serviceType">Type of the service that's being requested</param>
|
||||||
|
/// <param name="args">arguments to pass to the constructor of the service</param>
|
||||||
|
/// <remarks> 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.</remarks>
|
||||||
|
/// <returns>An object that is the instantiated service type or null if not found</returns>
|
||||||
|
public object? TryGetService(Type serviceType, object[]? args = null) {
|
||||||
try {
|
try {
|
||||||
return GetService(serviceType, args);
|
return GetService(serviceType, args);
|
||||||
} catch {
|
} catch {
|
||||||
return null!;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +240,7 @@ public class ServiceContainer {
|
|||||||
singletons[descriptor.ServiceType] = newSingleton!;
|
singletons[descriptor.ServiceType] = newSingleton!;
|
||||||
return newSingleton;
|
return newSingleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TInterface Instantiate<TInterface>(ServiceDescriptor descriptor, ConstructorInfo? ctor = null) {
|
private TInterface Instantiate<TInterface>(ServiceDescriptor descriptor, ConstructorInfo? ctor = null) {
|
||||||
if (ctor == null && descriptor.ImplementationType.GetConstructors().Length > 1)
|
if (ctor == null && descriptor.ImplementationType.GetConstructors().Length > 1)
|
||||||
throw new Exception($"Multiple constructors found for type {descriptor.ImplementationType}. Please provide a specific constructor.");
|
throw new Exception($"Multiple constructors found for type {descriptor.ImplementationType}. Please provide a specific constructor.");
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ public class ServiceDescriptor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<object>? Arguments { get; init; }
|
public List<object>? Arguments { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a string with the specific type of service, its implementation, and its lifetime.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>{implementation Name} as {Service Name} ({Lifetime})</returns>
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return $"{ImplementationType.Name} as {ServiceType.Name} ({Lifetime})";
|
return $"{ImplementationType.Name} as {ServiceType.Name} ({Lifetime})";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Version>0.0.1.7-alpha</Version>
|
<Version>0.0.1.8-alpha</Version>
|
||||||
<Title>Syrette </Title>
|
<Title>Syrette </Title>
|
||||||
<Authors>Lorefice Samuele</Authors>
|
<Authors>Lorefice Samuele</Authors>
|
||||||
<Description>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.</Description>
|
<Description>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.</Description>
|
||||||
|
|||||||
Reference in New Issue
Block a user