using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using Core.RabbitMQBus.Common; using Core.RabbitMQBus.IocHelper; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; namespace Core.RabbitMQBus.EventBus { /// /// 订阅者注册缓存 /// public static class RegisterSubscriberCache { static ConcurrentDictionary SubscriberServiceMethodDictionary = new ConcurrentDictionary(); /// /// 注册订阅 /// /// 注入容器 /// 订阅者的程序集名称 /// 订阅者类的后缀名称 public static void RabbitMQRegisterSubscriber(this IServiceCollection service, string assemblyName, string subscribeClassEndsWithName) { if (string.IsNullOrEmpty(assemblyName)) throw new ArgumentNullException(nameof(assemblyName)); var assembly = RuntimeHelper.GetAssembly(assemblyName); if (assembly == null) { throw new DllNotFoundException($"the dll \"{assemblyName}\" not be found"); } //获取程序集中实现了ISubscribe接口的类型 var subscribeTypes = assembly.GetTypes().Where(t => t.GetTypeInfo().IsClass && typeof(ISubscribe).IsAssignableFrom(t.GetTypeInfo())); var serviceProvider = service.BuildServiceProvider(); var rabbitMqSubscriber = serviceProvider.GetService(); var subscribeTypeList = subscribeTypes.Where(s => s.GetMethods().Where(e => e.GetCustomAttribute(typeof(SubscribeAttribute)) != null).Any()).ToList(); foreach (var type in subscribeTypeList) { var subscribeType = type.GetInterfaces().FirstOrDefault(e => e.Name.EndsWith(subscribeClassEndsWithName)); var subscribeService = serviceProvider.GetService(subscribeType); var methodList = type.GetMethods().Where(e => e.GetCustomAttribute(typeof(SubscribeAttribute)) != null).ToList(); foreach (var method in methodList) { SubscriberServiceMethodInfo subscriberServiceMethod = new SubscriberServiceMethodInfo(); subscriberServiceMethod.SubscriberService = subscribeService; var subscribeAttribute = method.GetCustomAttribute(typeof(SubscribeAttribute)) as SubscribeAttribute; if (subscribeAttribute != null) { var methodParameters = method.GetParameters().FirstOrDefault(); var parameterType = methodParameters?.ParameterType; var queueName = subscribeAttribute.QueueName; subscriberServiceMethod.MethodInfo = method; subscriberServiceMethod.MethodParameterType = parameterType; SubscriberServiceMethodDictionary.GetOrAdd(queueName, subscriberServiceMethod); rabbitMqSubscriber.Subscriber(queueName); } } } } public static void RabbitMQControllerRegisterSubscriber(this IServiceCollection service, string assemblyName) { if (string.IsNullOrEmpty(assemblyName)) throw new ArgumentNullException(nameof(assemblyName)); var assembly = RuntimeHelper.GetAssembly(assemblyName); if (assembly == null) { throw new DllNotFoundException($"the dll \"{assemblyName}\" not be found"); } var assemblys = assembly.GetTypes().AsEnumerable() .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToList(); var serviceProvider = service.BuildServiceProvider(); var rabbitMqSubscriber = serviceProvider.GetService(); assemblys.ForEach(type => { var subscribeService = serviceProvider.GetService(type); var methodList = type.GetMethods().Where(e => e.GetCustomAttribute(typeof(SubscribeAttribute)) != null).ToList(); foreach (var method in methodList) { SubscriberServiceMethodInfo subscriberServiceMethod = new SubscriberServiceMethodInfo(); subscriberServiceMethod.SubscriberService = subscribeService; if (method.GetCustomAttribute(typeof(SubscribeAttribute)) is SubscribeAttribute subscribeAttribute) { var methodParameters = method.GetParameters().FirstOrDefault(); var parameterType = methodParameters?.ParameterType; var queueName = subscribeAttribute.QueueName; subscriberServiceMethod.MethodInfo = method; subscriberServiceMethod.MethodParameterType = parameterType; SubscriberServiceMethodDictionary.GetOrAdd(queueName, subscriberServiceMethod); rabbitMqSubscriber.Subscriber(queueName); } } }); } /// /// 根据队列名称获取订阅者的方法 /// /// /// public static SubscriberServiceMethodInfo GetSubscriberMethod(string queueName) { SubscriberServiceMethodDictionary.TryGetValue(queueName, out SubscriberServiceMethodInfo subscriberServiceMethod); return subscriberServiceMethod; } } public class SubscriberServiceMethodInfo { /// /// 方法 /// public MethodInfo MethodInfo { get; set; } /// /// 订阅者Service /// public object SubscriberService { get; set; } /// /// 参数类型 /// public Type MethodParameterType { get; set; } } }