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.
 
 
 

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