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; }
}
}