93 lines
4.0 KiB
C#
93 lines
4.0 KiB
C#
using JiShe.CollectBus.Kafka.Internal;
|
|
using JiShe.CollectBus.Protocol.AnalysisData;
|
|
using JiShe.CollectBus.Protocol.Contracts;
|
|
using JiShe.CollectBus.Protocol.Contracts.Abstracts;
|
|
using JiShe.CollectBus.Protocol.Contracts.Interfaces;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
using Microsoft.Extensions.Logging;
|
|
using Serilog.Core;
|
|
using System.Reflection;
|
|
using TouchSocket.Core;
|
|
using Volo.Abp;
|
|
using Volo.Abp.Modularity;
|
|
|
|
namespace JiShe.CollectBus.Protocol
|
|
{
|
|
public class JiSheCollectBusProtocolModule : AbpModule
|
|
{
|
|
public override void ConfigureServices(ServiceConfigurationContext context)
|
|
{
|
|
context.Services.AddKeyedSingleton<IProtocolPlugin, StandardProtocolPlugin>(nameof(StandardProtocolPlugin));
|
|
RegisterProtocolAnalysis(context.Services);
|
|
}
|
|
|
|
public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
|
|
{
|
|
var standardProtocol = context.ServiceProvider.GetRequiredKeyedService<IProtocolPlugin>(nameof(StandardProtocolPlugin));
|
|
await standardProtocol.AddAsync();
|
|
}
|
|
|
|
public void RegisterProtocolAnalysis(IServiceCollection services)
|
|
{
|
|
// 扫描并注册所有策略
|
|
var strategyMetadata = new Dictionary<(string, Type, Type), Type>();
|
|
services.AddTransient<AnalysisStrategyContext>();
|
|
|
|
// 批量注册
|
|
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
|
if (string.IsNullOrWhiteSpace(assemblyPath))
|
|
{
|
|
return;
|
|
}
|
|
var dllFiles = Directory.GetFiles(Path.Combine(assemblyPath, "Plugins") , "*.dll");
|
|
foreach (var file in dllFiles)
|
|
{
|
|
// 跳过已加载的程序集
|
|
var assemblyName = AssemblyName.GetAssemblyName(file);
|
|
var existingAssembly = AppDomain.CurrentDomain.GetAssemblies()
|
|
.FirstOrDefault(a => a.GetName().FullName == assemblyName.FullName);
|
|
var assembly = existingAssembly ?? Assembly.LoadFrom(file);
|
|
// 实现IAnalysisStrategy接口
|
|
var analysisStrategyTypes = assembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IAnalysisStrategy<,>)));
|
|
if (analysisStrategyTypes.Count() == 0)
|
|
continue;
|
|
foreach (var analysisStrategyType in analysisStrategyTypes)
|
|
{
|
|
// 通过反射获取静态元数据
|
|
var strategyType = analysisStrategyType.Name;
|
|
var genericArgs = analysisStrategyType.GetInterface("IAnalysisStrategy`2")!.GetGenericArguments();
|
|
var inputType = genericArgs[0];
|
|
var resultType = genericArgs[1];
|
|
// 注册策略实现
|
|
services.AddTransient(analysisStrategyType);
|
|
strategyMetadata[(strategyType, inputType, resultType)] = analysisStrategyType;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
// 注册元数据字典
|
|
services.AddSingleton(strategyMetadata);
|
|
|
|
// 注册策略解析工厂
|
|
services.AddTransient<Func<string, Type, Type, object?>>(provider => (name, inputType, resultType) =>
|
|
{
|
|
var metadata = provider.GetRequiredService<Dictionary<(string, Type, Type), Type>>();
|
|
if (metadata.TryGetValue((name, inputType, resultType), out var strategyType))
|
|
{
|
|
return provider.GetRequiredService(strategyType);
|
|
}
|
|
else
|
|
{
|
|
var logger= provider.GetRequiredService<ILogger<AnalysisStrategyContext>>();
|
|
logger.LogWarning($"未能找到解析策略:{name}-{inputType}-{resultType}");
|
|
return null;
|
|
}
|
|
});
|
|
|
|
|
|
}
|
|
}
|
|
}
|