Created
April 16, 2023 01:22
-
-
Save ejsmith/d8fb84a9b1f07194650b848b95c91bf8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Foundatio.Queues; | |
using System.Collections.Concurrent; | |
using Microsoft.Extensions.DependencyInjection; | |
namespace Contacts.Domain.Services; | |
public interface INamedRegistrationFactory<T> where T : class { | |
/// <summary> | |
/// Get instance by name | |
/// </summary> | |
/// <param name="name">Instance name</param> | |
/// <returns>The instance associated with the specified name</returns> | |
T GetByName(string name); | |
/// <summary> | |
/// Get instance by group. Multiple names can belong to a single group / instance. | |
/// </summary> | |
/// <param name="group">Group name</param> | |
/// <returns>The instance associated with the group name</returns> | |
T GetByGroup(string group); | |
/// <summary> | |
/// Get the name of the group by the instance name. Multiple names can belong to a single group. | |
/// </summary> | |
/// <param name="name">Instance name</param> | |
/// <returns>The group name</returns> | |
string GetGroupName(string name); | |
/// <summary> | |
/// The default non-named instance | |
/// </summary> | |
T Default { get; } | |
/// <summary> | |
/// Get all instances registered in this factory. | |
/// </summary> | |
/// <returns>Dictionary of group name and instance</returns> | |
IDictionary<string, T> GetAll(); | |
} | |
public interface INamedQueueFactory<T> : INamedRegistrationFactory<IQueue<T>> where T : class { } | |
public abstract class NamedRegistrationFactory<T> : INamedRegistrationFactory<T> where T : class { | |
private readonly ConcurrentDictionary<string, T> _instances = new ConcurrentDictionary<string, T>(StringComparer.OrdinalIgnoreCase); | |
protected readonly IServiceProvider _serviceProvider; | |
private readonly Dictionary<string, string> _groupToNameMap = new Dictionary<string, string> { { String.Empty, String.Empty } }; | |
public NamedRegistrationFactory(IServiceProvider serviceProvider, string groupToNameMap) { | |
_serviceProvider = serviceProvider; | |
if (String.IsNullOrEmpty(groupToNameMap)) | |
return; | |
ParseGroupToNameMap(groupToNameMap); | |
} | |
public T GetByName(string name) { | |
return GetByGroup(GetGroupName(name)); | |
} | |
public T Default => GetByGroup(String.Empty); | |
public T GetByGroup(string group) { | |
if (group == null) | |
group = String.Empty; | |
return _instances.GetOrAdd(group, key => CreateInstance(group)); | |
} | |
public string GetGroupName(string name) { | |
string groupName = String.Empty; | |
if (!String.IsNullOrEmpty(name) && _groupToNameMap.ContainsKey(name)) | |
groupName = _groupToNameMap[name]; | |
return groupName; | |
} | |
public IDictionary<string, T> GetAll() { | |
return _groupToNameMap.Values.Distinct().Select(groupName => new KeyValuePair<string, T>(groupName, GetByGroup(groupName))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); | |
} | |
protected abstract T CreateInstance(string groupName); | |
private void ParseGroupToNameMap(string connectionString) { | |
var groups = connectionString.Split(';') | |
.Where(kvp => kvp.Contains('=')) | |
.Select(kvp => kvp.Split(new[] { '=' }, 2)) | |
.ToDictionary(kvp => kvp[0].Trim(), kvp => kvp[1].Trim(), StringComparer.InvariantCultureIgnoreCase); | |
foreach (var group in groups) { | |
string[] keys = group.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); | |
foreach (var key in keys) | |
_groupToNameMap.Add(key, group.Key); | |
} | |
} | |
} | |
public class InMemoryNamedQueueFactory<T> : NamedRegistrationFactory<IQueue<T>>, INamedQueueFactory<T> where T : class { | |
public InMemoryNamedQueueFactory(IServiceProvider serviceProvider, string queueNamesConfig) : base(serviceProvider, queueNamesConfig) { } | |
protected override IQueue<T> CreateInstance(string groupName) { | |
var behaviors = _serviceProvider.GetServices<IQueueBehavior<T>>().ToList(); | |
return new InMemoryQueue<T>(new InMemoryQueueOptions<T> { | |
Behaviors = behaviors, | |
WorkItemTimeout = TimeSpan.FromHours(1) | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment