|
|
@@ -5,6 +5,7 @@ using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
using System.Reflection; |
|
|
|
using System.Text.RegularExpressions; |
|
|
|
using DotNetCore.CAP.Abstractions; |
|
|
|
using DotNetCore.CAP.Infrastructure; |
|
|
|
using Microsoft.Extensions.DependencyInjection; |
|
|
@@ -19,6 +20,8 @@ namespace DotNetCore.CAP.Internal |
|
|
|
{ |
|
|
|
private readonly CapOptions _capOptions; |
|
|
|
private readonly IServiceProvider _serviceProvider; |
|
|
|
private List<RegexExecuteDescriptor<ConsumerExecutorDescriptor>> _asteriskList; |
|
|
|
private List<RegexExecuteDescriptor<ConsumerExecutorDescriptor>> _poundList; |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// Creates a new <see cref="DefaultConsumerServiceSelector" />. |
|
|
@@ -29,17 +32,6 @@ namespace DotNetCore.CAP.Internal |
|
|
|
_capOptions = capOptions; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// Selects the best <see cref="ConsumerExecutorDescriptor" /> candidate from <paramref name="executeDescriptor" /> for |
|
|
|
/// the |
|
|
|
/// current message associated. |
|
|
|
/// </summary> |
|
|
|
public ConsumerExecutorDescriptor SelectBestCandidate(string key, |
|
|
|
IReadOnlyList<ConsumerExecutorDescriptor> executeDescriptor) |
|
|
|
{ |
|
|
|
return executeDescriptor.FirstOrDefault(x => x.Attribute.Name == key); |
|
|
|
} |
|
|
|
|
|
|
|
public IReadOnlyList<ConsumerExecutorDescriptor> SelectCandidates() |
|
|
|
{ |
|
|
|
var executorDescriptorList = new List<ConsumerExecutorDescriptor>(); |
|
|
@@ -51,6 +43,26 @@ namespace DotNetCore.CAP.Internal |
|
|
|
return executorDescriptorList; |
|
|
|
} |
|
|
|
|
|
|
|
public ConsumerExecutorDescriptor SelectBestCandidate(string key, IReadOnlyList<ConsumerExecutorDescriptor> executeDescriptor) |
|
|
|
{ |
|
|
|
var result = MatchUsingName(key, executeDescriptor); |
|
|
|
if (result != null) |
|
|
|
{ |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
//[*] match with regex, i.e. foo.*.abc |
|
|
|
result = MatchAsteriskUsingRegex(key, executeDescriptor); |
|
|
|
if (result != null) |
|
|
|
{ |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
//[#] match regex, i.e. foo.# |
|
|
|
result = MatchPoundUsingRegex(key, executeDescriptor); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
private IEnumerable<ConsumerExecutorDescriptor> FindConsumersFromInterfaceTypes( |
|
|
|
IServiceProvider provider) |
|
|
|
{ |
|
|
@@ -130,5 +142,65 @@ namespace DotNetCore.CAP.Internal |
|
|
|
|
|
|
|
return descriptor; |
|
|
|
} |
|
|
|
|
|
|
|
private ConsumerExecutorDescriptor MatchUsingName(string key, IReadOnlyList<ConsumerExecutorDescriptor> executeDescriptor) |
|
|
|
{ |
|
|
|
return executeDescriptor.FirstOrDefault(x => x.Attribute.Name == key); |
|
|
|
} |
|
|
|
|
|
|
|
private ConsumerExecutorDescriptor MatchAsteriskUsingRegex(string key, IReadOnlyList<ConsumerExecutorDescriptor> executeDescriptor) |
|
|
|
{ |
|
|
|
if (_asteriskList == null) |
|
|
|
{ |
|
|
|
_asteriskList = executeDescriptor |
|
|
|
.Where(x => x.Attribute.Name.IndexOf('*') >= 0) |
|
|
|
.Select(x => new RegexExecuteDescriptor<ConsumerExecutorDescriptor> |
|
|
|
{ |
|
|
|
Name = ("^" + x.Attribute.Name + "$").Replace("*", "[a-zA-Z]+").Replace(".", "\\."), |
|
|
|
Descriptor = x |
|
|
|
}).ToList(); |
|
|
|
} |
|
|
|
foreach (var red in _asteriskList) |
|
|
|
{ |
|
|
|
if (Regex.IsMatch(key, red.Name, RegexOptions.Singleline)) |
|
|
|
{ |
|
|
|
return red.Descriptor; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
private ConsumerExecutorDescriptor MatchPoundUsingRegex(string key, IReadOnlyList<ConsumerExecutorDescriptor> executeDescriptor) |
|
|
|
{ |
|
|
|
if (_poundList == null) |
|
|
|
{ |
|
|
|
_poundList = executeDescriptor |
|
|
|
.Where(x => x.Attribute.Name.IndexOf('#') >= 0) |
|
|
|
.Select(x => new RegexExecuteDescriptor<ConsumerExecutorDescriptor> |
|
|
|
{ |
|
|
|
Name = ("^" + x.Attribute.Name + "$").Replace("#", "[a-zA-Z\\.]+"), |
|
|
|
Descriptor = x |
|
|
|
}).ToList(); |
|
|
|
} |
|
|
|
|
|
|
|
foreach (var red in _poundList) |
|
|
|
{ |
|
|
|
if (Regex.IsMatch(key, red.Name, RegexOptions.Singleline)) |
|
|
|
{ |
|
|
|
return red.Descriptor; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private class RegexExecuteDescriptor<T> |
|
|
|
{ |
|
|
|
public string Name { get; set; } |
|
|
|
|
|
|
|
public T Descriptor { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
} |