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);
    }
    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);
    }
 public static BCryptAlgorithmHandle GetAlgorithmHandle(ref CachedAlgorithmInfo cachedAlgorithmInfo)
 {
     return(WeakReferenceHelpers.GetSharedInstance(ref cachedAlgorithmInfo._algorithmHandle, cachedAlgorithmInfo._factory));
 }