2016-11-20 13:34:50 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2017-02-12 13:42:49 +00:00
|
|
|
|
using System.Text.RegularExpressions;
|
2016-11-20 13:34:50 +00:00
|
|
|
|
|
|
|
|
|
namespace Tapeti.Default
|
2016-11-16 22:11:05 +00:00
|
|
|
|
{
|
2017-01-31 11:01:08 +00:00
|
|
|
|
public class TypeNameRoutingKeyStrategy : IRoutingKeyStrategy
|
2016-11-16 22:11:05 +00:00
|
|
|
|
{
|
2017-02-12 13:42:49 +00:00
|
|
|
|
private const string SeparatorPattern = @"
|
|
|
|
|
(?<!^) # Not start
|
|
|
|
|
(
|
|
|
|
|
# Digit, not preceded by another digit
|
|
|
|
|
(?<!\d)\d
|
|
|
|
|
|
|
|
|
|
|
# Upper-case letter, followed by lower-case letter if
|
|
|
|
|
# preceded by another upper-case letter, e.g. 'G' in HTMLGuide
|
|
|
|
|
(?(?<=[A-Z])[A-Z](?=[a-z])|[A-Z])
|
|
|
|
|
)";
|
|
|
|
|
|
|
|
|
|
private static readonly Regex SeparatorRegex = new Regex(SeparatorPattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);
|
|
|
|
|
|
|
|
|
|
private static readonly ConcurrentDictionary<Type, string> RoutingKeyCache = new ConcurrentDictionary<Type, string>();
|
2016-11-20 13:34:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public string GetRoutingKey(Type messageType)
|
|
|
|
|
{
|
2017-02-12 13:42:49 +00:00
|
|
|
|
return RoutingKeyCache.GetOrAdd(messageType, BuildRoutingKey);
|
2016-11-20 13:34:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual string BuildRoutingKey(Type messageType)
|
|
|
|
|
{
|
|
|
|
|
// Split PascalCase into dot-separated parts. If the class name ends in "Message" leave that out.
|
2017-02-12 13:42:49 +00:00
|
|
|
|
var words = SplitPascalCase(messageType.Name);
|
|
|
|
|
if (words == null)
|
|
|
|
|
return "";
|
2016-11-20 13:34:50 +00:00
|
|
|
|
|
2017-02-12 13:42:49 +00:00
|
|
|
|
if (words.Count > 1 && words.Last().Equals("Message", StringComparison.InvariantCultureIgnoreCase))
|
2016-11-20 13:34:50 +00:00
|
|
|
|
words.RemoveAt(words.Count - 1);
|
|
|
|
|
|
|
|
|
|
return string.Join(".", words.Select(s => s.ToLower()));
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-12 13:42:49 +00:00
|
|
|
|
private static List<string> SplitPascalCase(string value)
|
2016-11-20 13:34:50 +00:00
|
|
|
|
{
|
2017-02-12 13:42:49 +00:00
|
|
|
|
var split = SeparatorRegex.Split(value);
|
|
|
|
|
if (split.Length == 0)
|
|
|
|
|
return null;
|
2016-11-20 13:34:50 +00:00
|
|
|
|
|
2017-02-12 13:42:49 +00:00
|
|
|
|
var result = new List<string>(split.Length - 1 / 2) { split[0] };
|
|
|
|
|
for (var i = 1; i < split.Length; i += 2)
|
|
|
|
|
result.Add(split[i] + split[i + 1]);
|
2016-11-20 13:34:50 +00:00
|
|
|
|
|
2017-02-12 13:42:49 +00:00
|
|
|
|
return result;
|
2016-11-20 13:34:50 +00:00
|
|
|
|
}
|
2016-11-16 22:11:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|