Skip to content

Commit

Permalink
Fix disposing for CryptoRandomizers; Added test for disposing
Browse files Browse the repository at this point in the history
  • Loading branch information
g0dzZz-coder committed Oct 18, 2022
1 parent 54ff0fc commit 86333c4
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 5 deletions.
19 changes: 18 additions & 1 deletion Random.Application.UnitTests/RandomServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ public void WhenRegisteringRandomizer_AndRandomizerForTypeIsAlreadyRegistered_Th
{
// Arrange.
var randomizerValueType = typeof(int);
var randomizer = Substitute.For<ITypedRandomizer<int>>();
var randomService = new RandomService();
var randomizer = Substitute.For<ITypedRandomizer<int>>();
randomService.RegisterRandomizer(randomizerValueType, randomizer);

// Act.
Expand All @@ -73,4 +73,21 @@ public void WhenRegisteringRandomizer_AndRandomizerForTypeIsAlreadyRegistered_Th
// Assert.
act.Should().Throw<RandomizerForTypeAlreadyRegisteredException>();
}

[Test]
public void WhenDisposingService_AndServiceContainRandomizers_ThenExceptionNotThrown()
{
// Arrange.
var randomService = new RandomService();
var randomizer = Substitute.For<ITypedRandomizer<int>>();
randomService.RegisterRandomizer(typeof(int), randomizer);
randomService.RegisterRandomizer(typeof(double), randomizer);
randomService.RegisterRandomizer(typeof(byte[]), randomizer);

// Act.
var act = () => randomService.Dispose();

// Assert.
act.Should().NotThrow();
}
}
44 changes: 42 additions & 2 deletions Random/Application/Services/RandomService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

namespace Depra.Random.Application.Services
{
/// <inheritdoc />
public sealed class RandomService : IRandomService
/// <inheritdoc cref="IRandomService" />
public sealed class RandomService : IRandomService, IDisposable
{
private readonly IDictionary<Type, IRandomizer> _randomizers;
private bool _disposed;

public IRandomizer GetRandomizer(Type valueType)
{
Expand Down Expand Up @@ -40,5 +41,44 @@ public void RegisterRandomizer(Type valueType, IRandomizer randomizer)

public RandomService(IDictionary<Type, IRandomizer> randomizers = null) =>
_randomizers = randomizers ?? new Dictionary<Type, IRandomizer>();

~RandomService() => Dispose(false);

/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Private implementation of Dispose pattern.
/// </summary>
/// <param name="disposing"></param>
private void Dispose(bool disposing)
{
if (_disposed)
{
return;
}

if (disposing)
{
DisposeRandomizers();
}

_disposed = true;
}

private void DisposeRandomizers()
{
foreach (var randomizer in _randomizers.Values)
{
if (randomizer is IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
}
53 changes: 51 additions & 2 deletions Random/Application/System/Collections/CryptoRandomizers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Depra.Random.Application.System.Mapping;
using Depra.Random.Application.System.Proxy;
using Depra.Random.Application.System.Randoms;
using Depra.Random.Domain.Randomizers;

Expand All @@ -13,7 +13,7 @@ namespace Depra.Random.Application.System.Collections
public sealed class CryptoRandomizers : IRandomizerCollection
{
private readonly SystemRandomizersMapper _randomizersMapper;

public CryptoRandomizers()
{
var random = new CryptoRandom();
Expand All @@ -26,5 +26,54 @@ public CryptoRandomizers()
public IRandomizer GetRandomizer(Type valueType) => _randomizersMapper.GetRandomizer(valueType);

public IEnumerable<IRandomizer> GetAllRandomizers() => _randomizersMapper.GetAllRandomizers();

private abstract class CryptoRandomProxy : IDisposable
{
private readonly CryptoRandom _cryptoRandom;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected CryptoRandom GetRandom() => _cryptoRandom;

protected CryptoRandomProxy(CryptoRandom cryptoRandom) => _cryptoRandom = cryptoRandom;

public void Dispose() => _cryptoRandom.Dispose();
}

private class IntRandomProxy : CryptoRandomProxy, INumberRandomizer<int>
{
private static readonly Type VALUE_TYPE = typeof(int);

public Type ValueType => VALUE_TYPE;

public int Next() => GetRandom().Next();

public int Next(int maxExclusive) => GetRandom().Next(maxExclusive);

public int Next(int minInclusive, int maxExclusive) => GetRandom().Next(minInclusive, maxExclusive);

public IntRandomProxy(CryptoRandom cryptoRandom) : base(cryptoRandom) { }
}

private class DoubleRandomProxy : CryptoRandomProxy, ITypedRandomizer<double>
{
private static readonly Type VALUE_TYPE = typeof(double);

public Type ValueType => VALUE_TYPE;

public double Next() => GetRandom().NextDouble();

public DoubleRandomProxy(CryptoRandom cryptoRandom) : base(cryptoRandom) { }
}

private class ByteArrayRandomProxy : CryptoRandomProxy, IArrayRandomizer<byte[]>
{
private static readonly Type VALUE_TYPE = typeof(byte[]);

public Type ValueType => VALUE_TYPE;

public void Next(byte[] buffer) => GetRandom().NextBytes(buffer);

public ByteArrayRandomProxy(CryptoRandom cryptoRandom) : base(cryptoRandom) { }
}
}
}
11 changes: 11 additions & 0 deletions Random/Application/System/Proxy/DisposableSystemRandomProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Depra.Random.Application.System.Proxy
{
internal abstract class DisposableSystemRandomProxy : SystemRandomProxy, IDisposable
{
public abstract void Dispose();

protected DisposableSystemRandomProxy(global::System.Random random) : base(random) { }
}
}

0 comments on commit 86333c4

Please sign in to comment.