fix(client-ui): resolve Medium code-review finding (Client.UI-008)

Implement IDisposable on MainWindowViewModel to detach ConnectionStateChanged,
call Teardown() on the subscription/alarm VMs, and dispose _service so the OPC UA
session and SDK resources are released. Call Dispose() from MainWindow.OnClosing
alongside the existing SaveSettings() call.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-22 07:28:48 -04:00
parent bdc1f96b5b
commit c7f8a00635
2 changed files with 19 additions and 1 deletions

View File

@@ -10,7 +10,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.ViewModels;
/// <summary>
/// Main window ViewModel coordinating all panels.
/// </summary>
public partial class MainWindowViewModel : ObservableObject
public partial class MainWindowViewModel : ObservableObject, IDisposable
{
private readonly IUiDispatcher _dispatcher;
private readonly IOpcUaClientServiceFactory _factory;
@@ -411,6 +411,21 @@ public partial class MainWindowViewModel : ObservableObject
});
}
/// <summary>
/// Detaches the connection-state handler and disposes the OPC UA client service, releasing
/// the session, certificate validator, and any background reconnect resources.
/// </summary>
public void Dispose()
{
if (_service != null)
{
_service.ConnectionStateChanged -= OnConnectionStateChanged;
Subscriptions?.Teardown();
Alarms?.Teardown();
_service.Dispose();
}
}
private static string[]? ParseFailoverUrls(string? csv)
{
if (string.IsNullOrWhiteSpace(csv))

View File

@@ -140,7 +140,10 @@ public partial class MainWindow : Window
protected override void OnClosing(WindowClosingEventArgs e)
{
if (DataContext is MainWindowViewModel vm)
{
vm.SaveSettings();
vm.Dispose();
}
base.OnClosing(e);
}
}