您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

152 行
4.8 KiB

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