Slim Integration with Microsoft.Extensions.DependencyInjection (#20)

* Setup integration with Microsoft.Extensions.DependencyInjection

* Setup Slim integration project with Microsoft.Extensions.DependencyInjection
This commit is contained in:
2022-09-09 14:26:25 +02:00
committed by GitHub
parent b337497de5
commit e8adfa1acc
14 changed files with 487 additions and 4 deletions
@@ -0,0 +1,85 @@
using System;
using Microsoft.Extensions.DependencyInjection;
namespace Slim.Integration.ServiceCollection;
public static class ServiceCollectionExtensions
{
public static System.IServiceProvider BuildSlimServiceProvider(this Microsoft.Extensions.DependencyInjection.ServiceCollection serviceCollection)
{
var serviceManager = new ServiceManager();
foreach(var serviceDescriptor in serviceCollection)
{
switch (serviceDescriptor.Lifetime)
{
case ServiceLifetime.Singleton:
RegisterSingleton(serviceManager, serviceDescriptor);
break;
case ServiceLifetime.Scoped:
RegisterScoped(serviceManager, serviceDescriptor);
break;
case ServiceLifetime.Transient:
RegisterTransient(serviceManager, serviceDescriptor);
break;
default:
throw new InvalidOperationException($"Unexpected service lifetime {serviceDescriptor.Lifetime}.");
}
}
serviceManager.RegisterScoped<IServiceScopeFactory, ServiceScopeFactory>();
return serviceManager;
}
private static void RegisterSingleton(ServiceManager serviceManager, ServiceDescriptor serviceDescriptor)
{
if (serviceDescriptor.ImplementationInstance is null &&
serviceDescriptor.ImplementationFactory is not null)
{
serviceManager.RegisterSingleton(serviceDescriptor.ServiceType, sp => serviceDescriptor.ImplementationFactory(sp));
}
else if (serviceDescriptor.ImplementationFactory is null &&
serviceDescriptor.ImplementationInstance is not null)
{
serviceManager.RegisterSingleton(serviceDescriptor.ServiceType, sp => serviceDescriptor.ImplementationInstance);
}
else
{
serviceManager.RegisterSingleton(serviceDescriptor.ServiceType, serviceDescriptor.ImplementationType);
}
}
private static void RegisterScoped(ServiceManager serviceManager, ServiceDescriptor serviceDescriptor)
{
if (serviceDescriptor.ImplementationInstance is null &&
serviceDescriptor.ImplementationFactory is not null)
{
serviceManager.RegisterScoped(serviceDescriptor.ServiceType, sp => serviceDescriptor.ImplementationFactory(sp));
}
else if (serviceDescriptor.ImplementationFactory is null &&
serviceDescriptor.ImplementationInstance is not null)
{
serviceManager.RegisterScoped(serviceDescriptor.ServiceType, sp => serviceDescriptor.ImplementationInstance);
}
else
{
serviceManager.RegisterScoped(serviceDescriptor.ServiceType, serviceDescriptor.ImplementationType);
}
}
private static void RegisterTransient(ServiceManager serviceManager, ServiceDescriptor serviceDescriptor)
{
if (serviceDescriptor.ImplementationInstance is null &&
serviceDescriptor.ImplementationFactory is not null)
{
serviceManager.RegisterTransient(serviceDescriptor.ServiceType, sp => serviceDescriptor.ImplementationFactory(sp));
}
else if (serviceDescriptor.ImplementationFactory is null &&
serviceDescriptor.ImplementationInstance is not null)
{
serviceManager.RegisterTransient(serviceDescriptor.ServiceType, sp => serviceDescriptor.ImplementationInstance);
}
else
{
serviceManager.RegisterTransient(serviceDescriptor.ServiceType, serviceDescriptor.ImplementationType);
}
}
}
@@ -0,0 +1,17 @@
using System;
using Microsoft.Extensions.DependencyInjection;
namespace Slim.Integration.ServiceCollection;
public sealed class ServiceScope : IServiceScope
{
public System.IServiceProvider ServiceProvider { get; set; }
public void Dispose()
{
if (this.ServiceProvider is IDisposable disposable)
{
disposable.Dispose();
}
}
}
@@ -0,0 +1,20 @@
using Microsoft.Extensions.DependencyInjection;
namespace Slim.Integration.ServiceCollection;
public sealed class ServiceScopeFactory : IServiceScopeFactory
{
private readonly IServiceManager serviceManager;
public ServiceScopeFactory(
IServiceManager serviceManager)
{
this.serviceManager = serviceManager;
}
public IServiceScope CreateScope()
{
IServiceProvider scopedServiceManager = this.serviceManager.CreateScope();
return new ServiceScope { ServiceProvider = scopedServiceManager };
}
}
@@ -0,0 +1,76 @@
using System;
using System.ComponentModel.Design;
namespace Slim.Integration.ServiceContainer;
public class SlimServiceContainer : IServiceContainer
{
private readonly IServiceManager serviceManager;
public SlimServiceContainer()
{
this.serviceManager = new ServiceManager();
}
public SlimServiceContainer(IServiceManager serviceManager)
{
this.serviceManager = serviceManager;
}
public void AddService(Type serviceType, ServiceCreatorCallback callback)
{
this.serviceManager.RegisterSingleton(serviceType, sp => callback(this, serviceType));
}
public void AddService(Type serviceType, ServiceCreatorCallback callback, bool promote)
{
var manager = this.serviceManager;
if (promote is false)
{
this.AddService(serviceType, callback);
return;
}
while (manager is not null)
{
manager.RegisterSingleton(serviceType, sp => callback(this, serviceType));
manager = manager.ParentServiceManager;
}
}
public void AddService(Type serviceType, object serviceInstance)
{
this.serviceManager.RegisterSingleton(serviceType, sp => serviceInstance);
}
public void AddService(Type serviceType, object serviceInstance, bool promote)
{
var manager = this.serviceManager;
if (promote is false)
{
this.AddService(serviceType, serviceInstance);
return;
}
while (manager is not null)
{
manager.RegisterSingleton(serviceType, sp => serviceInstance);
manager = manager.ParentServiceManager;
}
}
public object GetService(Type serviceType)
{
return this.serviceManager.GetService(serviceType);
}
public void RemoveService(Type serviceType)
{
throw new NotSupportedException("Removing one service is not currently supported");
}
public void RemoveService(Type serviceType, bool promote)
{
throw new NotSupportedException("Removing one service is not currently supported");
}
}
+9 -1
View File
@@ -19,7 +19,15 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<PackageReference Include="Slim" Version="1.8.1" />
<PackageReference Include="Slim" Version="1.9.1" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
<None Include="..\README.md" Link="README.md" />
</ItemGroup>
</Project>