Compare commits
6 Commits
v0.0.1.3-a
...
v0.0.1.5-a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9fbb4b851 | ||
|
|
3df2f50765 | ||
|
|
d20788de33 | ||
|
|
b8f2ddad5a | ||
| 86513ec6c6 | |||
|
|
debedc837e |
@@ -26,4 +26,6 @@ jobs:
|
|||||||
- name: Pack nugets
|
- name: Pack nugets
|
||||||
run: dotnet pack Syrette -c Release --no-build --output . --include-symbols --include-source -p:SymbolPackageFormat=snupkg
|
run: dotnet pack Syrette -c Release --no-build --output . --include-symbols --include-source -p:SymbolPackageFormat=snupkg
|
||||||
- name: Push to NuGet
|
- name: Push to NuGet
|
||||||
run: dotnet nuget push "*.nupkg" --api-key ${{secrets.NUGETAPIKEY}} --source https://api.nuget.org/v3/index.json
|
run: dotnet nuget push "*.nupkg" --api-key ${{secrets.NUGETAPIKEY}} --skip-duplicate --source https://api.nuget.org/v3/index.json
|
||||||
|
- name: Push to Gitea
|
||||||
|
run: dotnet nuget push "*.nupkg" --api-key ${{secrets.NUGETGITEA}} --skip-duplicate --source https://git.r3d.codes/api/packages/REDCODE/nuget/index.json
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ class Service : IService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AnotherService : IService {
|
||||||
|
public void Log(string message) {
|
||||||
|
Console.WriteLine($"[AnotherService] {message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface IOtherService {
|
interface IOtherService {
|
||||||
public Guid Id { get; }
|
public Guid Id { get; }
|
||||||
|
|
||||||
@@ -47,6 +53,7 @@ static class Program {
|
|||||||
static void Main(string[] args) {
|
static void Main(string[] args) {
|
||||||
var container = new ServiceContainer()
|
var container = new ServiceContainer()
|
||||||
.AddSingleton<IService, Service>()
|
.AddSingleton<IService, Service>()
|
||||||
|
.AddTransient<IService, AnotherService>()
|
||||||
.AddTransient<IOtherService, GuidService>()
|
.AddTransient<IOtherService, GuidService>()
|
||||||
.AddTransient<GuidDependantService, GuidDependantService>();
|
.AddTransient<GuidDependantService, GuidDependantService>();
|
||||||
|
|
||||||
@@ -55,5 +62,6 @@ static class Program {
|
|||||||
container.GetService<IOtherService>().ShowId();
|
container.GetService<IOtherService>().ShowId();
|
||||||
container.GetService<GuidDependantService>().LogWithId("Hello, sent from the dependency.");
|
container.GetService<GuidDependantService>().LogWithId("Hello, sent from the dependency.");
|
||||||
container.GetService<IService>().Log("Goodbye, Dependency Injection!");
|
container.GetService<IService>().Log("Goodbye, Dependency Injection!");
|
||||||
|
var res = container.GetServices<IService>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,24 +14,47 @@ public class ServiceContainer {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TServices"></typeparam>
|
/// <typeparam name="TServices"></typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public List<Type> GetServices<TServices>() =>
|
public List<Type> GetServiceTypes<TServices>() =>
|
||||||
descriptors.Where(d => d.ServiceType == typeof(TServices))
|
descriptors.Where(d => d.ServiceType == typeof(TServices))
|
||||||
.Select(d => d.ImplementationType).ToList();
|
.Select(d => d.ImplementationType).ToList();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all registered services for a given service type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TService"></typeparam>
|
||||||
|
public List<TService> GetServices<TService>() where TService : class =>
|
||||||
|
descriptors.Where(d => d.ServiceType == typeof(TService))
|
||||||
|
.Select(d => (TService)GetService(d.ImplementationType)).ToList();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a singleton service with its implementation.
|
/// Registers a singleton service with its implementation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TInterface">Interface the service is implementing</typeparam>
|
/// <typeparam name="TInterface">Interface the service is implementing</typeparam>
|
||||||
/// <typeparam name="TImplementation">Implementation type of the service</typeparam>
|
/// <typeparam name="TImplementation">Implementation type of the service</typeparam>
|
||||||
public ServiceContainer AddSingleton<TInterface, TImplementation>()
|
public ServiceContainer AddSingleton<TInterface, TImplementation>()
|
||||||
|
where TInterface : class
|
||||||
where TImplementation : class, TInterface {
|
where TImplementation : class, TInterface {
|
||||||
descriptors.Add(new ServiceDescriptor {
|
descriptors.Add(new () {
|
||||||
ServiceType = typeof(TInterface),
|
ServiceType = typeof(TInterface),
|
||||||
ImplementationType = typeof(TImplementation),
|
ImplementationType = typeof(TImplementation),
|
||||||
Lifetime = ServiceLifetime.Lifetime
|
Lifetime = ServiceLifetime.Lifetime
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a singleton service where the service type is the same as the implementation type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TClass">Class type of the service</typeparam>
|
||||||
|
public ServiceContainer AddSingleton<TClass>()
|
||||||
|
where TClass : class {
|
||||||
|
descriptors.Add(new () {
|
||||||
|
ServiceType = typeof(TClass),
|
||||||
|
ImplementationType = typeof(TClass),
|
||||||
|
Lifetime = ServiceLifetime.Lifetime
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a transient service with its implementation.
|
/// Registers a transient service with its implementation.
|
||||||
@@ -39,8 +62,9 @@ public class ServiceContainer {
|
|||||||
/// <typeparam name="TInterface">Interface the service is implementing</typeparam>
|
/// <typeparam name="TInterface">Interface the service is implementing</typeparam>
|
||||||
/// <typeparam name="TImplementation">Implementation type of the service</typeparam>
|
/// <typeparam name="TImplementation">Implementation type of the service</typeparam>
|
||||||
public ServiceContainer AddTransient<TInterface, TImplementation>()
|
public ServiceContainer AddTransient<TInterface, TImplementation>()
|
||||||
|
where TInterface : class
|
||||||
where TImplementation : class, TInterface {
|
where TImplementation : class, TInterface {
|
||||||
descriptors.Add(new ServiceDescriptor {
|
descriptors.Add(new () {
|
||||||
ServiceType = typeof(TInterface),
|
ServiceType = typeof(TInterface),
|
||||||
ImplementationType = typeof(TImplementation),
|
ImplementationType = typeof(TImplementation),
|
||||||
Lifetime = ServiceLifetime.Transient
|
Lifetime = ServiceLifetime.Transient
|
||||||
@@ -48,6 +72,20 @@ public class ServiceContainer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a transient service where the service type is the same as the implementation type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TClass">Class type of the service</typeparam>
|
||||||
|
public ServiceContainer AddTransient<TClass>()
|
||||||
|
where TClass : class {
|
||||||
|
descriptors.Add(new () {
|
||||||
|
ServiceType = typeof(TClass),
|
||||||
|
ImplementationType = typeof(TClass),
|
||||||
|
Lifetime = ServiceLifetime.Transient
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// you can't call generic methods with an unknown type at compile time
|
// 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
|
// 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.
|
// Basically we build the method GetService<serviceType>() at runtime and then call it.
|
||||||
@@ -62,12 +100,12 @@ public class ServiceContainer {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves and returns an instance of the requested service type.
|
/// Resolves and returns an instance of the requested service type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TInterface">Interface type of the service being requested</typeparam>
|
/// <typeparam name="TService">Interface type of the service being requested</typeparam>
|
||||||
/// <returns>Resolved service instance</returns>
|
/// <returns>Resolved service instance</returns>
|
||||||
public TInterface GetService<TInterface>() {
|
public TService GetService<TService>() {
|
||||||
var descriptor = descriptors.FirstOrDefault(d => d.ServiceType == typeof(TInterface));
|
var descriptor = descriptors.FirstOrDefault(d => d.ServiceType == typeof(TService) || d.ImplementationType == typeof(TService));
|
||||||
|
|
||||||
if (descriptor == null) throw new Exception($"Service of type {typeof(TInterface)} not registered.");
|
if (descriptor == null) throw new Exception($"Service of type {typeof(TService)} not registered.");
|
||||||
|
|
||||||
var ctors = descriptor.ImplementationType.GetConstructors();
|
var ctors = descriptor.ImplementationType.GetConstructors();
|
||||||
int max = -1;
|
int max = -1;
|
||||||
@@ -85,19 +123,19 @@ public class ServiceContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bestCtor == null)
|
if (bestCtor == null)
|
||||||
throw new Exception($"Cannot create service of type {typeof(TInterface)}. No suitable constructor found.");
|
throw new Exception($"Cannot create service of type {typeof(TService)}. No suitable constructor found.");
|
||||||
|
|
||||||
// Transient: create a new instance each time
|
// Transient: create a new instance each time
|
||||||
if (descriptor.Lifetime != ServiceLifetime.Lifetime) {
|
if (descriptor.Lifetime != ServiceLifetime.Lifetime) {
|
||||||
var service = Instantiate<TInterface>(descriptor, bestCtor);
|
var service = Instantiate<TService>(descriptor, bestCtor);
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton: return existing instance
|
// Singleton: return existing instance
|
||||||
if (singletons.TryGetValue(descriptor.ServiceType, out object? singleton)) return (TInterface)singleton;
|
if (singletons.TryGetValue(descriptor.ServiceType, out object? singleton)) return (TService)singleton;
|
||||||
|
|
||||||
// or create a new one if not yet created.
|
// or create a new one if not yet created.
|
||||||
var newSingleton = Instantiate<TInterface>(descriptor);
|
var newSingleton = Instantiate<TService>(descriptor);
|
||||||
singletons[descriptor.ServiceType] = newSingleton!;
|
singletons[descriptor.ServiceType] = newSingleton!;
|
||||||
return newSingleton;
|
return newSingleton;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.3-alpha</Version>
|
<Version>0.0.1.5-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