using Microsoft.Extensions.DependencyInjection.Extensions;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
namespace Microsoft.Extensions.DependencyInjection
{
///
/// 依赖注入拓展类
///
internal static class DependencyInjectionExtensions
{
///
/// 注册服务(如果服务存在,覆盖注册)
///
///
///
///
internal static IServiceCollection InnerAdd(this IServiceCollection collection, Type dependencyType, Type service)
{
Call(dependencyType, MethodBase.GetCurrentMethod()
, new object[] { collection, service });
return collection;
}
///
/// 注册服务(如果服务存在,覆盖注册)
///
///
///
///
///
internal static IServiceCollection InnerAdd(this IServiceCollection collection, Type dependencyType, Type service, Func implementationFactory)
{
Call(dependencyType, MethodBase.GetCurrentMethod()
, new object[] { collection, service, implementationFactory });
return collection;
}
///
/// 注册服务(如果服务存在,覆盖注册)
///
///
///
///
///
internal static IServiceCollection InnerAdd(this IServiceCollection collection, Type dependencyType, Type service, Type implementationType)
{
Call(dependencyType, MethodBase.GetCurrentMethod()
, new object[] { collection, service, implementationType });
return collection;
}
///
/// 注册服务(如果服务存在,覆盖注册)
///
///
///
///
///
internal static IServiceCollection InnerAdd(this IServiceCollection collection, Type dependencyType, Func implementationFactory)
where TService : class
{
Call(dependencyType, MethodBase.GetCurrentMethod()
, new object[] { collection, implementationFactory }
, new[] { typeof(TService) });
return collection;
}
///
/// 注册服务(如果服务存在,跳过注册)
///
///
///
///
internal static void InnerTryAdd(this IServiceCollection collection, Type dependencyType, Type service)
{
Call(dependencyType, MethodBase.GetCurrentMethod()
, new object[] { collection, service });
}
///
/// 注册服务(如果服务存在,跳过注册)
///
///
///
///
///
internal static void InnerTryAdd(this IServiceCollection collection, Type dependencyType, Type service, Type implementationType)
{
Call(dependencyType, MethodBase.GetCurrentMethod()
, new object[] { collection, service, implementationType });
}
///
/// 反射调用
///
/// dependencyType
///
///
///
private static void Call(Type dependencyType, MethodBase currentMethod, object[] args, Type[] genericArguments = default)
{
var tryWay = currentMethod.Name.StartsWith("InnerTry");
var methodName = $"{currentMethod.Name[5..]}{dependencyType.Name[1..]}";
// 获取方法签名(很笨的方式)
var methodSignature = currentMethod.ToString().Replace($"IServiceCollection Inner{(tryWay ? "Try" : string.Empty)}Add", $"IServiceCollection {methodName}")
.Replace("Microsoft.Extensions.DependencyInjection.IServiceCollection, System.Type", "Microsoft.Extensions.DependencyInjection.IServiceCollection");
// 调用静态方法
Invoke(tryWay ? typeof(ServiceCollectionDescriptorExtensions) : typeof(ServiceCollectionServiceExtensions)
, methodSignature
, genericArguments
, args);
}
///
/// 反射调用微软内部注册服务方法
///
///
///
///
///
private static void Invoke(Type type, string methodSignature, Type[] genericParameters, object[] args = null)
{
var isGeneric = genericParameters != null && genericParameters.Length > 0;
// 查找符合方法签名的方法
var method = type.GetMethods()
.Where(m => m.ToString().Equals(methodSignature))
.FirstOrDefault() ?? throw new InvalidOperationException($"Not found method: {methodSignature}.");
// 处理泛型
var realMethod = method?.IsGenericMethod == true ? method.MakeGenericMethod(genericParameters) : method;
realMethod?.Invoke(null, args ?? Array.Empty