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
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);
+ }
+ }
+}