From f9f3090a7ab4d92838ff2313af04ac4cf92a8f61 Mon Sep 17 00:00:00 2001 From: Chris Pulman Date: Thu, 14 Nov 2024 01:28:12 +0000 Subject: [PATCH 1/3] Feature Add DisposeWith Provide an extension to allow Disposables to be added to a collection of Disposables in a Fluent manner. --- .../Disposables/DisposableMixins.cs | 35 +++++++++++++++++++ .../Tests/Disposables/DisposableTests.cs | 13 +++++++ 2 files changed, 48 insertions(+) create mode 100644 Rx.NET/Source/src/System.Reactive/Disposables/DisposableMixins.cs diff --git a/Rx.NET/Source/src/System.Reactive/Disposables/DisposableMixins.cs b/Rx.NET/Source/src/System.Reactive/Disposables/DisposableMixins.cs new file mode 100644 index 000000000..e5b972f4e --- /dev/null +++ b/Rx.NET/Source/src/System.Reactive/Disposables/DisposableMixins.cs @@ -0,0 +1,35 @@ +// 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. + +using System.Collections.Generic; + +namespace System.Reactive.Disposables; + +/// +/// Extension methods associated with the IDisposable interface. +/// +public static class DisposableMixins +{ + /// + /// Ensures the provided disposable is disposed with the specified ICollection of IDisposable./>. + /// + /// The type of the disposable. + /// The disposable we are going to want to be disposed by the disposable collection. + /// The composite disposable. + /// + /// The disposable. + /// + /// compositeDisposable + public static T DisposeWith(this T item, ICollection disposableCollection) + where T : IDisposable + { + if (disposableCollection == null) + { + throw new ArgumentNullException(nameof(disposableCollection)); + } + + disposableCollection.Add(item); + return item; + } +} diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs index 2c6bee05d..6f27fb1c5 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs @@ -415,6 +415,19 @@ public void CompositeDisposable_Empty_GetEnumerator() 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() { From cccfded8c0669a1a994725735482a2adc160a68a Mon Sep 17 00:00:00 2001 From: Chris Pulman Date: Mon, 18 Nov 2024 23:59:08 +0000 Subject: [PATCH 2/3] Update API test --- .../Api/ApiApprovalTests.Core.verified.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs b/Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs index 6e3936ec8..3c802fff6 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs @@ -600,6 +600,11 @@ public static class Disposable public static System.IDisposable Create(System.Action dispose) { } public static System.IDisposable Create(TState state, System.Action dispose) { } } + public static class DisposableMixins + { + public static T DisposeWith(this T item, System.Collections.Generic.ICollection disposableCollection) + where T : System.IDisposable { } + } public interface ICancelable : System.IDisposable { bool IsDisposed { get; } From 15e6f2728db00f4bd318b1ec264ba856caa5a5df Mon Sep 17 00:00:00 2001 From: Chris Pulman Date: Tue, 25 Mar 2025 07:26:30 +0000 Subject: [PATCH 3/3] Update Namespace, extend CompositeDisposable --- .../Disposables/DisposableMixins.cs | 35 ----------------- .../Fluent/DisposableExtensions.cs | 38 +++++++++++++++++++ .../System.Reactive/System.Reactive.csproj | 2 +- .../Api/ApiApprovalTests.Core.verified.cs | 15 +++++--- .../Tests/Disposables/DisposableTests.cs | 1 + 5 files changed, 49 insertions(+), 42 deletions(-) delete mode 100644 Rx.NET/Source/src/System.Reactive/Disposables/DisposableMixins.cs create mode 100644 Rx.NET/Source/src/System.Reactive/Disposables/Fluent/DisposableExtensions.cs diff --git a/Rx.NET/Source/src/System.Reactive/Disposables/DisposableMixins.cs b/Rx.NET/Source/src/System.Reactive/Disposables/DisposableMixins.cs deleted file mode 100644 index e5b972f4e..000000000 --- a/Rx.NET/Source/src/System.Reactive/Disposables/DisposableMixins.cs +++ /dev/null @@ -1,35 +0,0 @@ -// 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. - -using System.Collections.Generic; - -namespace System.Reactive.Disposables; - -/// -/// Extension methods associated with the IDisposable interface. -/// -public static class DisposableMixins -{ - /// - /// Ensures the provided disposable is disposed with the specified ICollection of IDisposable./>. - /// - /// The type of the disposable. - /// The disposable we are going to want to be disposed by the disposable collection. - /// The composite disposable. - /// - /// The disposable. - /// - /// compositeDisposable - public static T DisposeWith(this T item, ICollection disposableCollection) - where T : IDisposable - { - if (disposableCollection == null) - { - throw new ArgumentNullException(nameof(disposableCollection)); - } - - disposableCollection.Add(item); - return item; - } -} diff --git a/Rx.NET/Source/src/System.Reactive/Disposables/Fluent/DisposableExtensions.cs b/Rx.NET/Source/src/System.Reactive/Disposables/Fluent/DisposableExtensions.cs new file mode 100644 index 000000000..2414c1075 --- /dev/null +++ b/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; + +/// +/// Extension methods associated with the IDisposable interface. +/// +public static class DisposableExtensions +{ + /// + /// Ensures the provided disposable is disposed with the specified . + /// + /// + /// The type of the disposable. + /// + /// + /// The disposable we are going to want to be disposed by the CompositeDisposable. + /// + /// + /// The to which will be added. + /// + /// + /// The disposable. + /// + public static T DisposeWith(this T item, CompositeDisposable compositeDisposable) + where T : IDisposable + { + if (compositeDisposable == null) + { + throw new ArgumentNullException(nameof(compositeDisposable)); + } + + compositeDisposable.Add(item); + return item; + } +} diff --git a/Rx.NET/Source/src/System.Reactive/System.Reactive.csproj b/Rx.NET/Source/src/System.Reactive/System.Reactive.csproj index f03416d01..c76625412 100644 --- a/Rx.NET/Source/src/System.Reactive/System.Reactive.csproj +++ b/Rx.NET/Source/src/System.Reactive/System.Reactive.csproj @@ -150,7 +150,7 @@ - + diff --git a/Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs b/Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs index 3c802fff6..43e5e6796 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Api/ApiApprovalTests.Core.verified.cs @@ -600,11 +600,6 @@ public static class Disposable public static System.IDisposable Create(System.Action dispose) { } public static System.IDisposable Create(TState state, System.Action dispose) { } } - public static class DisposableMixins - { - public static T DisposeWith(this T item, System.Collections.Generic.ICollection disposableCollection) - where T : System.IDisposable { } - } public interface ICancelable : System.IDisposable { bool IsDisposed { get; } @@ -666,6 +661,14 @@ public static System.Reactive.Disposables.ICancelable Create(params System.IDisp 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(this T item, System.Reactive.Disposables.CompositeDisposable compositeDisposable) + where T : System.IDisposable { } + } +} namespace System.Reactive.Joins { public abstract class Pattern { } @@ -3195,4 +3198,4 @@ public void Start(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { } public static System.Runtime.CompilerServices.TaskObservableMethodBuilder Create() { } } -} +} \ No newline at end of file diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs index 6f27fb1c5..787265e20 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Disposables/DisposableTests.cs @@ -8,6 +8,7 @@ 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;