2020-05-27 16:03:38 +02:00
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2020-05-28 01:14:26 +02:00
|
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
2020-05-27 16:03:38 +02:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using zero.Core.Assemblies;
|
|
|
|
|
|
|
|
|
|
namespace zero.Core.Extensions
|
|
|
|
|
{
|
|
|
|
|
public static class ServiceCollectionExtensions
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds all found implementations based on the service type and assembly discovery rules
|
|
|
|
|
/// </summary>
|
2020-10-07 00:07:52 +02:00
|
|
|
public static void AddAll<TService>(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient, bool asSelf = false) => services.AddAll(typeof(TService), lifetime, asSelf);
|
2020-05-27 16:03:38 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds all found implementations based on the service type and assembly discovery rules
|
|
|
|
|
/// </summary>
|
2020-10-07 00:07:52 +02:00
|
|
|
public static void AddAll(this IServiceCollection services, Type serviceType, ServiceLifetime lifetime = ServiceLifetime.Transient, bool asSelf = false)
|
2020-05-27 16:03:38 +02:00
|
|
|
{
|
2020-05-28 00:36:52 +02:00
|
|
|
if (AssemblyDiscovery.Current == null)
|
2020-05-27 16:03:38 +02:00
|
|
|
{
|
|
|
|
|
throw new Exception("services.AddAll() can only be run after mvcBuilder.AddZero()");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add implementations with generic service types
|
|
|
|
|
if (serviceType.GetTypeInfo().IsGenericTypeDefinition)
|
|
|
|
|
{
|
2020-05-28 00:36:52 +02:00
|
|
|
IEnumerable<(Type, TypeInfo)> matches = AssemblyDiscovery.Current.GetAllClassTypes().SelectMany(type =>
|
2020-05-27 16:03:38 +02:00
|
|
|
{
|
2020-08-27 16:12:47 +02:00
|
|
|
var interfaces = type.GetInterfaces().Select(x => x.GetTypeInfo());
|
|
|
|
|
IEnumerable<Type> genericTypes = interfaces.Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == serviceType);
|
|
|
|
|
if (genericTypes.Any())
|
|
|
|
|
{
|
|
|
|
|
var genericTypeDefinitions = genericTypes.First();
|
|
|
|
|
}
|
2020-05-27 16:03:38 +02:00
|
|
|
return genericTypes.Select(x => (x, type));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
foreach ((Type, Type) match in matches)
|
|
|
|
|
{
|
2020-10-07 00:07:52 +02:00
|
|
|
services.Add(new ServiceDescriptor(asSelf ? match.Item2 : match.Item1, match.Item2, lifetime));
|
2020-05-27 16:03:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// add implementations with specific service types
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-28 00:36:52 +02:00
|
|
|
foreach (Type type in AssemblyDiscovery.Current.GetTypes(serviceType))
|
2020-05-27 16:03:38 +02:00
|
|
|
{
|
2020-10-07 00:07:52 +02:00
|
|
|
services.Add(new ServiceDescriptor(asSelf ? type : serviceType, type, lifetime));
|
2020-05-27 16:03:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds or overrides an implementation
|
|
|
|
|
/// </summary>
|
2020-05-28 01:14:26 +02:00
|
|
|
public static void Replace<TService, TImplementation>(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient)
|
2020-05-27 16:03:38 +02:00
|
|
|
where TService : class
|
|
|
|
|
where TImplementation : class, TService
|
|
|
|
|
{
|
2020-05-28 01:14:26 +02:00
|
|
|
services.RemoveAll<TService>();
|
2020-05-27 16:03:38 +02:00
|
|
|
services.Add(new ServiceDescriptor(typeof(TService), typeof(TImplementation), lifetime));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds or overrides an implementation
|
|
|
|
|
/// </summary>
|
2020-05-28 01:14:26 +02:00
|
|
|
public static void Replace<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory, ServiceLifetime lifetime = ServiceLifetime.Transient)
|
2020-05-27 16:03:38 +02:00
|
|
|
where TService : class
|
|
|
|
|
where TImplementation : class, TService
|
|
|
|
|
{
|
2020-05-28 01:14:26 +02:00
|
|
|
services.RemoveAll<TService>();
|
2020-05-27 16:03:38 +02:00
|
|
|
services.Add(new ServiceDescriptor(typeof(TService), implementationFactory, lifetime));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|