Files
TheXamlGuy bc55c4649b tidy
2024-04-26 23:05:36 +01:00

81 lines
2.1 KiB
C#

using System.Collections;
using System.Collections.Concurrent;
using System.Reactive.Disposables;
namespace Toolkit.Foundation;
public class Disposer :
IDisposer
{
private readonly ConcurrentDictionary<object, CompositeDisposable> subjects = [];
public void Add(object subject,
params object[] objects)
{
CompositeDisposable disposables = subjects.GetOrAdd(subject, args => new CompositeDisposable());
foreach (IDisposable disposable in objects.OfType<IDisposable>())
{
disposables.Add(disposable);
}
foreach (object notDisposable in objects.Where(x => x is not IDisposable))
{
disposables.Add(Disposable.Create(() => FromNotDisposable(notDisposable)));
}
}
private void FromNotDisposable(object target)
{
if (target is IList collection && collection is { Count: > 0 })
{
foreach (object? item in collection)
{
FromNotDisposable(item);
}
}
if (target is IDisposable disposable)
{
disposable.Dispose();
}
if (target is not IDisposable)
{
Dispose(target);
}
}
public TDisposable Replace<TDisposable>(object subject,
IDisposable disposer,
TDisposable replacement)
where TDisposable :
IDisposable
{
CompositeDisposable disposables = subjects.GetOrAdd(subject, args => new CompositeDisposable());
if (disposer is not null)
{
disposables.Remove(disposer);
}
disposables.Add(replacement);
return replacement;
}
public void Remove(object subject,
IDisposable disposer)
{
CompositeDisposable disposables = subjects.GetOrAdd(subject, args => new CompositeDisposable());
if (disposer is not null)
{
disposables.Remove(disposer);
}
}
public void Dispose(object subject)
{
if (subjects.TryGetValue(subject, out CompositeDisposable? disposables))
{
disposables?.Dispose();
}
}
}