Browse Source

Enhancement Add DisposeWith (#2178)

Provide an extension to allow Disposables to be added to a collection of Disposables in a Fluent manner.
Chris Pulman 1 month ago
parent
commit
fda1bbc7a1

+ 38 - 0
Rx.NET/Source/src/System.Reactive/Disposables/Fluent/DisposableExtensions.cs

@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT License.
+// See the LICENSE file in the project root for more information. 
+
+namespace System.Reactive.Disposables.Fluent;
+
+/// <summary>
+/// Extension methods associated with the IDisposable interface.
+/// </summary>
+public static class DisposableExtensions
+{
+    /// <summary>
+    /// Ensures the provided disposable is disposed with the specified <see cref="CompositeDisposable"/>.
+    /// </summary>
+    /// <typeparam name="T">
+    /// The type of the disposable.
+    /// </typeparam>
+    /// <param name="item">
+    /// The disposable we are going to want to be disposed by the CompositeDisposable.
+    /// </param>
+    /// <param name="compositeDisposable">
+    /// The <see cref="CompositeDisposable"/> to which <paramref name="item"/> will be added.
+    /// </param>
+    /// <returns>
+    /// The disposable.
+    /// </returns>
+    public static T DisposeWith<T>(this T item, CompositeDisposable compositeDisposable)
+        where T : IDisposable
+    {
+        if (compositeDisposable == null)
+        {
+            throw new ArgumentNullException(nameof(compositeDisposable));
+        }
+
+        compositeDisposable.Add(item);
+        return item;
+    }
+}

+ 1 - 1
Rx.NET/Source/src/System.Reactive/System.Reactive.csproj

@@ -154,7 +154,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <None Include="build\NuGet.Readme.md" Pack="true" PackagePath="\readme.md"/>
+    <None Include="build\NuGet.Readme.md" Pack="true" PackagePath="\readme.md" />
     <None Include="build\_._" PackagePath="build\net6.0;build\net6.0-windows10.0.19041" Pack="true" />
     <None Include="build\_._" PackagePath="buildTransitive\net6.0;buildTransitive\net6.0-windows10.0.19041" Pack="true" />
     <None Include="Linq\QbservableEx.NAry.cs">

+ 9 - 1
Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs

@@ -661,6 +661,14 @@ namespace System.Reactive.Disposables
         public static System.Reactive.Disposables.ICancelable Create(System.IDisposable disposable1, System.IDisposable disposable2) { }
     }
 }
+namespace System.Reactive.Disposables.Fluent
+{
+    public static class DisposableExtensions
+    {
+        public static T DisposeWith<T>(this T item, System.Reactive.Disposables.CompositeDisposable compositeDisposable)
+            where T : System.IDisposable { }
+    }
+}
 namespace System.Reactive.Joins
 {
     public abstract class Pattern { }
@@ -3190,4 +3198,4 @@ namespace System.Runtime.CompilerServices
             where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
         public static System.Runtime.CompilerServices.TaskObservableMethodBuilder<T> Create() { }
     }
-}
+}

+ 14 - 0
Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs

@@ -8,6 +8,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Reactive.Concurrency;
 using System.Reactive.Disposables;
+using System.Reactive.Disposables.Fluent;
 using System.Threading;
 using Microsoft.Reactive.Testing;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -415,6 +416,19 @@ namespace ReactiveTests.Tests
             Assert.False(composite.GetEnumerator().MoveNext());
         }
 
+        [TestMethod]
+        public void CompositeDisposable_DisposeWith()
+        {
+            var c = new CompositeDisposable();
+            var d = new BooleanDisposable();
+            d.DisposeWith(c);
+            Assert.True(c.Contains(d));
+
+            c.Dispose();
+            Assert.True(d.IsDisposed);
+            Assert.True(c.IsDisposed);
+        }
+
         [TestMethod]
         public void CompositeDisposable_NonCollection_Enumerable_Init()
         {