From 38afb6e3fc29fbaec92e1aea823c35c43b63076b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 13:51:03 +0000 Subject: [PATCH 1/3] Initial plan From d57f28e66e850e708f78e12ae3dcd98358f6c0a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 13:59:17 +0000 Subject: [PATCH 2/3] Implement proper dispose pattern for InputFile component Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com> --- src/Components/Web/src/Forms/InputFile.cs | 14 +++++++++++++- src/Components/Web/src/PublicAPI.Unshipped.txt | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Components/Web/src/Forms/InputFile.cs b/src/Components/Web/src/Forms/InputFile.cs index 6f3000faf73f..673a2dd6a5e2 100644 --- a/src/Components/Web/src/Forms/InputFile.cs +++ b/src/Components/Web/src/Forms/InputFile.cs @@ -96,8 +96,20 @@ Task IInputFileJsCallbacks.NotifyChange(BrowserFile[] files) return OnChange.InvokeAsync(new InputFileChangeEventArgs(files)); } + /// + /// Releases the resources used by the component. + /// + /// if called within . + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _jsCallbacksRelay?.Dispose(); + } + } + void IDisposable.Dispose() { - _jsCallbacksRelay?.Dispose(); + Dispose(disposing: true); } } diff --git a/src/Components/Web/src/PublicAPI.Unshipped.txt b/src/Components/Web/src/PublicAPI.Unshipped.txt index eefd46d3c0a7..be938651444d 100644 --- a/src/Components/Web/src/PublicAPI.Unshipped.txt +++ b/src/Components/Web/src/PublicAPI.Unshipped.txt @@ -70,3 +70,4 @@ Microsoft.AspNetCore.Components.Web.Media.MediaSource.MediaSource(byte[]! data, Microsoft.AspNetCore.Components.Web.Media.MediaSource.MediaSource(System.IO.Stream! stream, string! mimeType, string! cacheKey) -> void Microsoft.AspNetCore.Components.Web.Media.MediaSource.MimeType.get -> string! Microsoft.AspNetCore.Components.Web.Media.MediaSource.Stream.get -> System.IO.Stream! +virtual Microsoft.AspNetCore.Components.Forms.InputFile.Dispose(bool disposing) -> void From 8f333c9d989723193f0c35c5b88e0527d88bd076 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 14:01:29 +0000 Subject: [PATCH 3/3] Add unit test for InputFile dispose pattern Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com> --- .../Web/test/Forms/InputFileTest.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/Components/Web/test/Forms/InputFileTest.cs diff --git a/src/Components/Web/test/Forms/InputFileTest.cs b/src/Components/Web/test/Forms/InputFileTest.cs new file mode 100644 index 000000000000..c29b0584551c --- /dev/null +++ b/src/Components/Web/test/Forms/InputFileTest.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.AspNetCore.Components.Forms; + +public class InputFileTest +{ + [Fact] + public void DerivedClass_CanOverrideDisposeMethod() + { + // Arrange + var disposed = false; + var derivedInputFile = new DerivedInputFile(() => disposed = true); + + // Act + ((IDisposable)derivedInputFile).Dispose(); + + // Assert + Assert.True(disposed, "Derived class Dispose(bool) method should be called"); + } + + private class DerivedInputFile : InputFile + { + private readonly Action _onDispose; + + public DerivedInputFile(Action onDispose) + { + _onDispose = onDispose; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _onDispose(); + } + base.Dispose(disposing); + } + } +}