Added Disposer
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Reactive.Disposables;
|
||||
|
||||
namespace Toolkit.Framework.Foundation;
|
||||
|
||||
public class Disposer : IDisposer
|
||||
{
|
||||
private readonly ConditionalWeakTable<object, CompositeDisposable> subjects = new();
|
||||
|
||||
public void Add(object subject, params object[] objects)
|
||||
{
|
||||
CompositeDisposable disposables = subjects.GetOrCreateValue(subject);
|
||||
foreach (IDisposable disposable in objects.OfType<IDisposable>())
|
||||
{
|
||||
disposables.Add(disposable);
|
||||
}
|
||||
}
|
||||
|
||||
public TDisposable Replace<TDisposable>(object subject, IDisposable disposer, TDisposable replacement) where TDisposable : IDisposable
|
||||
{
|
||||
CompositeDisposable disposables = subjects.GetOrCreateValue(subject);
|
||||
if (disposer is not null)
|
||||
{
|
||||
disposables.Remove(disposer);
|
||||
}
|
||||
|
||||
disposables.Add(replacement);
|
||||
return replacement;
|
||||
}
|
||||
public void Remove(object subject, IDisposable disposer)
|
||||
{
|
||||
CompositeDisposable disposables = subjects.GetOrCreateValue(subject);
|
||||
if (disposer is not null)
|
||||
{
|
||||
disposables.Remove(disposer);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose(object subject)
|
||||
{
|
||||
if (subjects.TryGetValue(subject, out CompositeDisposable disposables))
|
||||
{
|
||||
disposables.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Toolkit.Framework.Foundation;
|
||||
|
||||
public interface IDisposer
|
||||
{
|
||||
void Add(object subject, params object[] objects);
|
||||
|
||||
void Remove(object subject, IDisposable disposer);
|
||||
|
||||
void Dispose(object subject);
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Toolkit.Framework.Foundation;
|
||||
|
||||
public class Mediator : IMediator
|
||||
{
|
||||
private readonly IServiceProvider factory;
|
||||
private readonly ConcurrentDictionary<Type, HashSet<dynamic>> subscriptions = new();
|
||||
|
||||
private readonly ConditionalWeakTable<Type, dynamic> handlers = new();
|
||||
|
||||
public Mediator(IServiceProvider factory)
|
||||
{
|
||||
@@ -16,10 +17,13 @@ public class Mediator : IMediator
|
||||
public ValueTask Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification
|
||||
{
|
||||
List<INotificationHandler<TNotification>> handlers = factory.GetServices<INotificationHandler<TNotification>>().ToList();
|
||||
|
||||
foreach (dynamic handler in subscriptions[typeof(TNotification)])
|
||||
|
||||
foreach (KeyValuePair<Type, dynamic> handler in this.handlers)
|
||||
{
|
||||
handlers.Add(handler);
|
||||
if (handler.Key == typeof(TNotification))
|
||||
{
|
||||
handlers.Add(handler.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (handlers.Count == 0)
|
||||
@@ -114,9 +118,9 @@ public class Mediator : IMediator
|
||||
return default;
|
||||
}
|
||||
|
||||
public void Subscribe(object subscriber)
|
||||
public void Subscribe(object subject)
|
||||
{
|
||||
Type[] interfaceTypes = subscriber.GetType().GetInterfaces();
|
||||
Type[] interfaceTypes = subject.GetType().GetInterfaces();
|
||||
foreach (Type interfaceType in interfaceTypes.Where(x => x.IsGenericType))
|
||||
{
|
||||
if (interfaceType.GetGenericTypeDefinition() == typeof(INotificationHandler<>))
|
||||
@@ -124,12 +128,7 @@ public class Mediator : IMediator
|
||||
if (interfaceType.GetGenericArguments() is { Length: 1 } arguments)
|
||||
{
|
||||
Type notificationType = arguments[0];
|
||||
|
||||
subscriptions.AddOrUpdate(notificationType, new HashSet<dynamic> { subscriber }, (type, hashSet) =>
|
||||
{
|
||||
hashSet.Add(subscriber);
|
||||
return hashSet;
|
||||
});
|
||||
handlers.Add(notificationType, subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user