Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

168 строки
5.5 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Threading.Tasks;
  6. using DotNetCore.CAP.Internal;
  7. using Microsoft.Extensions.DependencyInjection;
  8. using Microsoft.Extensions.Options;
  9. using Xunit;
  10. namespace DotNetCore.CAP.Test
  11. {
  12. public class CustomConsumerSubscribeTest
  13. {
  14. private const string TopicNamePrefix = "topic";
  15. private const string GroupNamePrefix = "group";
  16. private readonly IServiceProvider _provider;
  17. public CustomConsumerSubscribeTest()
  18. {
  19. var services = new ServiceCollection();
  20. services.AddSingleton<IConsumerServiceSelector, MyConsumerServiceSelector>();
  21. services.AddTransient<IMySubscribe, CustomInterfaceTypesClass>();
  22. services.AddLogging();
  23. services.AddCap(x =>
  24. {
  25. x.TopicNamePrefix = TopicNamePrefix;
  26. x.GroupNamePrefix = GroupNamePrefix;
  27. });
  28. _provider = services.BuildServiceProvider();
  29. }
  30. [Fact]
  31. public void CanFindAllConsumerService()
  32. {
  33. var selector = _provider.GetRequiredService<IConsumerServiceSelector>();
  34. var candidates = selector.SelectCandidates();
  35. Assert.Equal(2, candidates.Count);
  36. }
  37. [Fact]
  38. public void CanFindSpecifiedTopic()
  39. {
  40. var selector = _provider.GetRequiredService<IConsumerServiceSelector>();
  41. var candidates = selector.SelectCandidates();
  42. var bestCandidates = selector.SelectBestCandidate($"{TopicNamePrefix}.Candidates.Foo", candidates);
  43. Assert.NotNull(bestCandidates);
  44. Assert.NotNull(bestCandidates.MethodInfo);
  45. Assert.StartsWith(GroupNamePrefix, bestCandidates.Attribute.Group);
  46. Assert.StartsWith(TopicNamePrefix, bestCandidates.TopicName);
  47. Assert.Equal(typeof(Task), bestCandidates.MethodInfo.ReturnType);
  48. }
  49. }
  50. public class MyConsumerServiceSelector : ConsumerServiceSelector
  51. {
  52. private readonly CapOptions _capOptions;
  53. public MyConsumerServiceSelector(IServiceProvider serviceProvider)
  54. : base(serviceProvider)
  55. {
  56. _capOptions = serviceProvider.GetService<IOptions<CapOptions>>().Value;
  57. }
  58. protected override IEnumerable<ConsumerExecutorDescriptor> FindConsumersFromInterfaceTypes(IServiceProvider provider)
  59. {
  60. var executorDescriptorList = new List<ConsumerExecutorDescriptor>();
  61. using (var scoped = provider.CreateScope())
  62. {
  63. var scopedProvider = scoped.ServiceProvider;
  64. var consumerServices = scopedProvider.GetServices<IMySubscribe>();
  65. foreach (var service in consumerServices)
  66. {
  67. var typeInfo = service.GetType().GetTypeInfo();
  68. if (!typeof(IMySubscribe).GetTypeInfo().IsAssignableFrom(typeInfo))
  69. {
  70. continue;
  71. }
  72. executorDescriptorList.AddRange(GetMyDescription(typeInfo));
  73. }
  74. return executorDescriptorList;
  75. }
  76. }
  77. private IEnumerable<ConsumerExecutorDescriptor> GetMyDescription(TypeInfo typeInfo)
  78. {
  79. foreach (var method in typeInfo.DeclaredMethods)
  80. {
  81. var topicAttr = method.GetCustomAttributes<MySubscribeAttribute>(true);
  82. var topicAttributes = topicAttr as IList<MySubscribeAttribute> ?? topicAttr.ToList();
  83. if (!topicAttributes.Any())
  84. {
  85. continue;
  86. }
  87. foreach (var attr in topicAttributes)
  88. {
  89. if (attr.Group == null)
  90. {
  91. attr.Group = _capOptions.DefaultGroupName + "." + _capOptions.Version;
  92. }
  93. else
  94. {
  95. attr.Group = attr.Group + "." + _capOptions.Version;
  96. }
  97. if (!string.IsNullOrEmpty(_capOptions.GroupNamePrefix))
  98. {
  99. attr.Group = $"{_capOptions.GroupNamePrefix}.{attr.Group}";
  100. }
  101. yield return new ConsumerExecutorDescriptor
  102. {
  103. Attribute = new CapSubscribeAttribute(attr.Name)
  104. {
  105. Group = attr.Group
  106. },
  107. MethodInfo = method,
  108. ImplTypeInfo = typeInfo,
  109. TopicNamePrefix = _capOptions.TopicNamePrefix
  110. };
  111. }
  112. }
  113. }
  114. }
  115. public interface IMySubscribe { }
  116. public class MySubscribeAttribute : Attribute
  117. {
  118. public MySubscribeAttribute(string name)
  119. {
  120. Name = name;
  121. }
  122. public string Name { get; }
  123. public string Group { get; set; }
  124. }
  125. public class CustomInterfaceTypesClass : IMySubscribe
  126. {
  127. [MySubscribe("Candidates.Foo")]
  128. public Task GetFoo()
  129. {
  130. Console.WriteLine("GetFoo() method has been excuted.");
  131. return Task.CompletedTask;
  132. }
  133. [MySubscribe("Candidates.Foo2")]
  134. public void GetFoo2()
  135. {
  136. Console.WriteLine("GetFoo2() method has been excuted.");
  137. }
  138. public void DistracterMethod()
  139. {
  140. Console.WriteLine("DistracterMethod() method has been excuted.");
  141. }
  142. }
  143. }