|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Xunit;
namespace Microsoft.AspNetCore.Cryptography;
public class WeakReferenceHelpersTests
{
[Fact]
public void GetSharedInstance_ExistingWeakRefHasBeenGCed_CreatesNew()
{
// Arrange
WeakReference<MyDisposable> wrOriginal = new WeakReference<MyDisposable>(null);
WeakReference<MyDisposable> wr = wrOriginal;
MyDisposable newInstance = new MyDisposable();
// Act
var retVal = WeakReferenceHelpers.GetSharedInstance(ref wr, () => newInstance);
// Assert
Assert.NotNull(wr);
Assert.NotSame(wrOriginal, wr);
Assert.True(wr.TryGetTarget(out var target));
Assert.Same(newInstance, target);
Assert.Same(newInstance, retVal);
Assert.False(newInstance.HasBeenDisposed);
}
[Fact]
public void GetSharedInstance_ExistingWeakRefIsNull_CreatesNew()
{
// Arrange
WeakReference<MyDisposable> wr = null;
MyDisposable newInstance = new MyDisposable();
// Act
var retVal = WeakReferenceHelpers.GetSharedInstance(ref wr, () => newInstance);
// Assert
Assert.NotNull(wr);
Assert.True(wr.TryGetTarget(out var target));
Assert.Same(newInstance, target);
Assert.Same(newInstance, retVal);
Assert.False(newInstance.HasBeenDisposed);
}
[Fact]
public void GetSharedInstance_ExistingWeakRefIsNull_AnotherThreadCreatesInstanceWhileOurFactoryRuns_ReturnsExistingInstanceAndDisposesNewInstance()
{
// Arrange
WeakReference<MyDisposable> wr = null;
MyDisposable instanceThatWillBeCreatedFirst = new MyDisposable();
MyDisposable instanceThatWillBeCreatedSecond = new MyDisposable();
// Act
var retVal = WeakReferenceHelpers.GetSharedInstance(ref wr, () =>
{
// mimic another thread creating the instance while our factory is being invoked
WeakReferenceHelpers.GetSharedInstance(ref wr, () => instanceThatWillBeCreatedFirst);
return instanceThatWillBeCreatedSecond;
});
// Assert
Assert.NotNull(wr);
Assert.True(wr.TryGetTarget(out var target));
Assert.Same(instanceThatWillBeCreatedFirst, target);
Assert.Same(instanceThatWillBeCreatedFirst, retVal);
Assert.False(instanceThatWillBeCreatedFirst.HasBeenDisposed);
Assert.True(instanceThatWillBeCreatedSecond.HasBeenDisposed);
}
private sealed class MyDisposable : IDisposable
{
public bool HasBeenDisposed { get; private set; }
public void Dispose()
{
HasBeenDisposed = true;
}
}
}
|