You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

177 lines
6.0 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. var parameters = method.GetParameters()
  102. .Select(parameter => new ParameterDescriptor
  103. {
  104. Name = parameter.Name,
  105. ParameterType = parameter.ParameterType,
  106. IsFromCap = parameter.GetCustomAttributes(typeof(FromCapAttribute)).Any()
  107. }).ToList();
  108. yield return new ConsumerExecutorDescriptor
  109. {
  110. Attribute = new CapSubscribeAttribute(attr.Name)
  111. {
  112. Group = attr.Group
  113. },
  114. Parameters = parameters,
  115. MethodInfo = method,
  116. ImplTypeInfo = typeInfo,
  117. TopicNamePrefix = _capOptions.TopicNamePrefix
  118. };
  119. }
  120. }
  121. }
  122. }
  123. public interface IMySubscribe { }
  124. public class MySubscribeAttribute : Attribute
  125. {
  126. public MySubscribeAttribute(string name)
  127. {
  128. Name = name;
  129. }
  130. public string Name { get; }
  131. public string Group { get; set; }
  132. }
  133. public class CustomInterfaceTypesClass : IMySubscribe
  134. {
  135. [MySubscribe("Candidates.Foo")]
  136. public Task GetFoo()
  137. {
  138. Console.WriteLine("GetFoo() method has been excuted.");
  139. return Task.CompletedTask;
  140. }
  141. [MySubscribe("Candidates.Foo2")]
  142. public void GetFoo2()
  143. {
  144. Console.WriteLine("GetFoo2() method has been excuted.");
  145. }
  146. public void DistracterMethod()
  147. {
  148. Console.WriteLine("DistracterMethod() method has been excuted.");
  149. }
  150. }
  151. }