using NCC;
using NCC.Dependency;
using NCC.DynamicApiController;
using NCC.Reflection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Microsoft.Extensions.DependencyInjection
{
///
/// 依赖注入拓展类
///
[SuppressSniffer]
public static class DependencyInjectionServiceCollectionExtensions
{
///
/// 添加依赖注入接口
///
/// 服务集合
/// 服务集合
public static IServiceCollection AddDependencyInjection(this IServiceCollection services)
{
// 添加外部程序集配置
services.AddConfigurableOptions();
services.AddInnerDependencyInjection();
return services;
}
///
/// 添加接口代理
///
/// 代理类
/// 被代理接口依赖
/// 服务集合
/// 服务集合
public static IServiceCollection AddScopedDispatchProxyForInterface(this IServiceCollection services)
where TDispatchProxy : AspectDispatchProxy, IDispatchProxy
where TIDispatchProxy : class
{
// 注册代理类
services.AddScoped();
// 代理依赖接口类型
var proxyType = typeof(TDispatchProxy);
var typeDependency = typeof(TIDispatchProxy);
// 获取所有的代理接口类型
var dispatchProxyInterfaceTypes = App.EffectiveTypes
.Where(u => typeDependency.IsAssignableFrom(u) && u.IsInterface && u != typeDependency);
// 注册代理类型
foreach (var interfaceType in dispatchProxyInterfaceTypes)
{
AddDispatchProxy(services, typeof(IScoped), default, proxyType, interfaceType, false);
}
return services;
}
///
/// 添加扫描注入
///
/// 服务集合
/// 服务集合
private static IServiceCollection AddInnerDependencyInjection(this IServiceCollection services)
{
// 查找所有需要依赖注入的类型
var injectTypes = App.EffectiveTypes
.Where(u => typeof(IPrivateDependency).IsAssignableFrom(u) && u.IsClass && !u.IsInterface && !u.IsAbstract)
.OrderBy(u => GetOrder(u));
var projectAssemblies = App.Assemblies;
var lifetimeInterfaces = new[] { typeof(ITransient), typeof(IScoped), typeof(ISingleton) };
// 执行依赖注入
foreach (var type in injectTypes)
{
// 获取注册方式
var injectionAttribute = !type.IsDefined(typeof(InjectionAttribute)) ? new InjectionAttribute() : type.GetCustomAttribute();
var interfaces = type.GetInterfaces();
// 获取所有能注册的接口
var canInjectInterfaces = interfaces.Where(u => !injectionAttribute.ExpectInterfaces.Contains(u)
&& u != typeof(IPrivateDependency)
&& u != typeof(IDynamicApiController)
&& !lifetimeInterfaces.Contains(u)
&& projectAssemblies.Contains(u.Assembly)
&& (
(!type.IsGenericType && !u.IsGenericType)
|| (type.IsGenericType && u.IsGenericType && type.GetGenericArguments().Length == u.GetGenericArguments().Length))
);
// 获取生存周期类型
var dependencyType = interfaces.Last(u => lifetimeInterfaces.Contains(u));
// 注册服务
RegisterService(services, dependencyType, type, injectionAttribute, canInjectInterfaces);
// 缓存类型注册
var typeNamed = injectionAttribute.Named ?? type.Name;
TypeNamedCollection.TryAdd(typeNamed, type);
}
// 注册外部配置服务
RegisterExternalServices(services);
// 注册命名服务(接口多实现)
RegisterNamedService(services);
RegisterNamedService(services);
RegisterNamedService(services);
return services;
}
///
/// 注册服务
///
/// 服务集合
///
/// 类型
/// 注入特性
/// 能被注册的接口
private static void RegisterService(IServiceCollection services, Type dependencyType, Type type, InjectionAttribute injectionAttribute, IEnumerable canInjectInterfaces)
{
// 注册自己
if (injectionAttribute.Pattern is InjectionPatterns.Self or InjectionPatterns.All or InjectionPatterns.SelfWithFirstInterface)
{
Register(services, dependencyType, type, injectionAttribute);
}
if (!canInjectInterfaces.Any()) return;
// 只注册第一个接口
if (injectionAttribute.Pattern is InjectionPatterns.FirstInterface or InjectionPatterns.SelfWithFirstInterface)
{
Register(services, dependencyType, type, injectionAttribute, canInjectInterfaces.Last());
}
// 注册多个接口
else if (injectionAttribute.Pattern is InjectionPatterns.ImplementedInterfaces or InjectionPatterns.All)
{
foreach (var inter in canInjectInterfaces)
{
Register(services, dependencyType, type, injectionAttribute, inter);
}
}
}
///
/// 注册类型
///
/// 服务
///
/// 类型
/// 注入特性
/// 接口
private static void Register(IServiceCollection services, Type dependencyType, Type type, InjectionAttribute injectionAttribute, Type inter = null)
{
// 修复泛型注册类型
var fixedType = FixedGenericType(type);
var fixedInter = inter == null ? null : FixedGenericType(inter);
switch (injectionAttribute.Action)
{
case InjectionActions.Add:
if (fixedInter == null) services.InnerAdd(dependencyType, fixedType);
else
{
services.InnerAdd(dependencyType, fixedInter, fixedType);
AddDispatchProxy(services, dependencyType, fixedType, injectionAttribute.Proxy, fixedInter, true);
}
break;
case InjectionActions.TryAdd:
if (fixedInter == null) services.InnerTryAdd(dependencyType, fixedType);
else services.InnerTryAdd(dependencyType, fixedInter, fixedType);
break;
default: break;
}
}
///
/// 创建服务代理
///
/// 服务集合
///
/// 拦截的类型
/// 代理类型
/// 代理接口
/// 是否有实现类
private static void AddDispatchProxy(IServiceCollection services, Type dependencyType, Type type, Type proxyType, Type inter, bool hasTarget = true)
{
proxyType ??= GlobalServiceProxyType;
if (proxyType == null || (type != null && type.IsDefined(typeof(SuppressProxyAttribute), true))) return;
// 注册代理类型
services.InnerAdd(dependencyType, typeof(AspectDispatchProxy), proxyType);
// 注册服务
services.InnerAdd(dependencyType, inter, provider =>
{
dynamic proxy = DispatchCreateMethod.MakeGenericMethod(inter, proxyType).Invoke(null, null);
proxy.Services = provider;
if (hasTarget)
{
proxy.Target = provider.GetService(type);
}
return proxy;
});
}
///
/// 注册命名服务(接口多实现)
///
///
///
private static void RegisterNamedService(IServiceCollection services)
where TDependency : IPrivateDependency
{
// 注册命名服务
services.InnerAdd(typeof(TDependency), provider =>
{
object ResolveService(string named, TDependency _)
{
var isRegister = TypeNamedCollection.TryGetValue(named, out var serviceType);
return isRegister ? provider.GetService(serviceType) : null;
}
return (Func)ResolveService;
});
}
///
/// 注册外部服务
///
///
private static void RegisterExternalServices(IServiceCollection services)
{
// 获取选项
var externalServices = App.GetConfig("DependencyInjectionSettings", true);
if (externalServices is { Definitions: not null })
{
// 排序
var extServices = externalServices.Definitions.OrderBy(u => u.Order);
foreach (var externalService in extServices)
{
var injectionAttribute = new InjectionAttribute
{
Action = externalService.Action,
Named = externalService.Named,
Order = externalService.Order,
Pattern = externalService.Pattern
};
// 加载代理拦截
if (!string.IsNullOrWhiteSpace(externalService.Proxy)) injectionAttribute.Proxy = GetProxyType(externalService.Proxy);
// 解析注册类型
var dependencyType = externalService.RegisterType switch
{
RegisterType.Transient => typeof(ITransient),
RegisterType.Scoped => typeof(IScoped),
RegisterType.Singleton => typeof(ISingleton),
_ => throw new InvalidOperationException("Unknown lifetime type.")
};
RegisterService(services, dependencyType,
GetProxyType(externalService.Service),
injectionAttribute,
new[] { GetProxyType(externalService.Interface) });
}
}
}
///
/// 修复泛型类型注册类型问题
///
/// 类型
///
private static Type FixedGenericType(Type type)
{
if (!type.IsGenericType) return type;
return Reflect.GetType(type.Assembly, $"{type.Namespace}.{type.Name}");
}
///
/// 获取 注册 排序
///
/// 排序类型
/// int
private static int GetOrder(Type type)
{
return !type.IsDefined(typeof(InjectionAttribute), true) ? 0 : type.GetCustomAttribute(true).Order;
}
///
/// 加载代理程序集
///
///
///
private static Type GetProxyType(string str)
{
var typeDefinitions = str.Split(";");
return Reflect.GetType(typeDefinitions[0], typeDefinitions[1]);
}
///
/// 类型名称集合
///
private static readonly ConcurrentDictionary TypeNamedCollection;
///
/// 创建代理方法
///
private static readonly MethodInfo DispatchCreateMethod;
///
/// 全局服务代理类型
///
private static readonly Type GlobalServiceProxyType;
///
/// 静态构造函数
///
static DependencyInjectionServiceCollectionExtensions()
{
// 获取全局代理类型
GlobalServiceProxyType = App.EffectiveTypes
.FirstOrDefault(u => typeof(AspectDispatchProxy).IsAssignableFrom(u) && typeof(IGlobalDispatchProxy).IsAssignableFrom(u) && u.IsClass && !u.IsInterface && !u.IsAbstract);
TypeNamedCollection = new ConcurrentDictionary();
DispatchCreateMethod = typeof(AspectDispatchProxy).GetMethod(nameof(AspectDispatchProxy.Create));
}
}
}