109 lines
5.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Reflection;
using System.Threading.Channels;
using JiShe.CollectBus.Protocol.Interfaces;
using JiShe.CollectBus.Protocol.T37612012.AnalysisData;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.Modularity;
namespace JiShe.CollectBus.Protocol.T37612012
{
public class CollectBusProtocolT37612012Module : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddKeyedSingleton<IProtocolPlugin, T37612012ProtocolPlugin>(nameof(T37612012ProtocolPlugin));
context.Services.AddMemoryCache();
// TODO:先用之前的策略注册方式后续验证后采用LoadAnalysisStrategy
RegisterProtocolAnalysis(context.Services);
//LoadAnalysisStrategy(context.Services);
}
public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
Console.WriteLine($"{nameof(T37612012ProtocolPlugin)} OnApplicationInitializationAsync");
var standardProtocol = context.ServiceProvider.GetRequiredKeyedService<IProtocolPlugin>(nameof(T37612012ProtocolPlugin));
await standardProtocol.LoadAsync();
}
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
Console.WriteLine($"{nameof(T37612012ProtocolPlugin)} OnApplicationShutdown");
base.OnApplicationShutdown(context);
}
public void LoadAnalysisStrategy(IServiceCollection services)
{
services.AddTransient<AnalysisStrategyContext>();
var assembly = Assembly.GetExecutingAssembly();
var analysisStrategyTypes = assembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IAnalysisStrategy<>)));
foreach (var analysisStrategyType in analysisStrategyTypes)
{
var service = analysisStrategyType.GetInterfaces().First();
services.AddKeyedSingleton(service, analysisStrategyType.Name, analysisStrategyType);
}
}
public void RegisterProtocolAnalysis(IServiceCollection services)
{
// 扫描并注册所有策略
var strategyMetadata = new Dictionary<(string, 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.Any())
continue;
foreach (var analysisStrategyType in analysisStrategyTypes)
{
// 通过反射获取静态元数据
var strategyType = analysisStrategyType.Name;
var genericArgs = analysisStrategyType.GetInterface($"IAnalysisStrategy`1")!.GetGenericArguments();
var inputType = genericArgs[0];
// 注册策略实现
services.AddTransient(analysisStrategyType);
strategyMetadata[(strategyType, inputType)] = analysisStrategyType;
}
}
// 注册元数据字典
services.AddSingleton(strategyMetadata);
// 注册策略解析工厂
services.AddTransient<Func<string, Type, object?>>(provider => (name, inputType) =>
{
var metadata = provider.GetRequiredService<Dictionary<(string, Type), Type>>();
if (metadata.TryGetValue((name, inputType), out var strategyType))
{
return provider.GetRequiredService(strategyType);
}
else
{
var logger = provider.GetRequiredService<ILogger<AnalysisStrategyContext>>();
logger.LogWarning($"未能找到解析策略:{name}-{inputType}");
return null;
}
});
}
}
}