Skip to content

Fix all build warnings and bump the NuGet packages - #787

Merged
romanett merged 2 commits into
masterfrom
romanett/warnings-nuget-bump-d84266
Aug 26, 2026
Merged

Fix all build warnings and bump the NuGet packages#787
romanett merged 2 commits into
masterfrom
romanett/warnings-nuget-bump-d84266

Conversation

@romanett

Copy link
Copy Markdown
Contributor

Proposed changes

Two things: every NuGet package is bumped to its latest stable version, and the solution now builds with zero warnings in both Debug and Release across net48, netstandard2.1, net8.0 and net10.0. It started at 128 distinct warnings.

Package bumps

Package From To
Microsoft.EntityFrameworkCore.Design / .SqlServer 10.0.10 10.0.11
Microsoft.Extensions.Hosting / .Logging.Console / .Logging.Abstractions 10.0.10 10.0.11
Microsoft.NET.Test.Sdk 18.8.1 18.9.0
NUnit3TestAdapter 6.2.0 6.3.0
Roslynator.Analyzers / .Formatting.Analyzers 4.15.0 5.0.0
Microsoft.CodeAnalysis.NetAnalyzers 10.0.302 10.0.400

Everything else was already current — the fourteen OPC UA packages are on the newest build the opcua-preview feed publishes (2.0.0-preview.2), and Mono.Options, NUnit, NUnit.Analyzers, Serilog and the container tooling targets were already at their latest stable release.

EF Core, the Extensions packages and NetAnalyzers all have 11.0.0 previews and NUnit has a 5.0.0 beta, but the repository targets .NET 10 GA, so this stays on stable. Neither the Roslynator 5.0 major bump nor the newer NetAnalyzers introduced any new diagnostics.

Warning fixes

Most were real defects and are fixed in code:

  • CA2000 (45)ApplicationInstance is IAsyncDisposable only, so the sample entry points now dispose it in a finally (or with await using where Main is async). The two console hosts that outlive the method creating the instance keep it in a field and dispose it during shutdown. TestClient.ConnectAsync moved to try/finally and clears its locals once the client takes ownership.
  • CA2012 (10)ValueTask results were being read directly; they now go through AsTask().
  • CA1849TypeInfo.GetBuiltInTypeGetBuiltInTypeAsync.
  • SYSLIB0057new X509Certificate2(byte[])X509CertificateLoader.
  • CS0618Variant.ValueAsBoxedObject().
  • CA2213 — the GDS client form now disposes its LocalDiscoveryServerClient.
  • CA1508 — removed a null check that could never be true.
  • CA1003ApplicationRegistered now carries an EventArgs-derived type.
  • CS9191, CS0109, CA2249, CA1307, CS8632, CA1873 — fixed in place.

The CA1002 decision (worth a reviewer's attention)

49 sites reported "do not expose generic lists", and they needed a judgement call rather than a mechanical fix.

The 2.0 SDK replaced the old XxxCollection : List<T> service types with the immutable ArrayOf<T> — but it did not deprecate List<T>. Because ArrayOf<T> cannot be appended to, the SDK still hands a mutable List<T> to anything a callee is meant to fill; Opc.Ua.Server alone has 77 public signatures that do this. So the rule can't just be applied everywhere.

Checking all 49 individually: exactly oneMethodsNodeManager.OnStart — is a GenericMethodCalledEventHandler target whose shape the SDK fixes. It carries a SuppressMessage saying exactly that. The other 48 were the samples' own controls and helpers, and are now IList<T> — or IReadOnlyList<T> in the two browse helpers, because ClientBase.ValidateResponse takes IReadOnlyList<TRequest> — with .ToArrayOf() at the service boundaries.

IList<T> was chosen over Collection<T> because it is what the samples already used elsewhere (FilterDefinition.EventTypes was IList<NodeId> sitting next to a List<T> sibling) and what the SDK itself uses for these roles, and because callers passing a List<T> need no change.

The same pass also converted twelve files that had been carrying pre-existing CA1002 suppressions rather than warnings, so the codebase is now consistent. 25 suppressions removed, 1 added. The 22 that remain are all node manager members whose List<T> parameters were verified against Opc.Ua.Server by reflection and genuinely cannot be reshaped:

RootNotifiers                 : List<NodeState>
Read(nodesToValidate)         : List<NodeHandle>
Write(nodesToValidate)        : List<NodeHandle>
RemovePredefinedNode(refs)    : List<LocalReference>

.editorconfig is unchanged — no rule was silenced to reach zero warnings.

Related Issues

  • Fixes #

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Enhancement (non-breaking change which adds functionality)
  • Test enhancement (non-breaking change to increase test coverage)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected, requires version increase of Nuget packages)
  • Documentation Update (if none of the other choices apply)

The public signatures of sample controls and helpers changed from List<T> to IList<T>. Nothing outside this repository consumes them, and callers passing a List<T> are unaffected, so this is not marked a breaking change — but it is the part most worth reviewing.

Checklist

  • I have read the CONTRIBUTING doc.
  • I have signed the CLA.
  • I ran tests locally with my changes, all passed.
  • I fixed all failing tests in the CI pipelines.
  • I fixed all introduced issues with CodeQL and LGTM.
  • I have added tests that prove my fix is effective or that my feature works and increased code coverage.
  • I have added necessary documentation (if appropriate).
  • Any dependent changes have been merged and published in downstream modules.

Further comments

All 247 tests pass: 143 configuration, 88 server smoke, 16 client smoke.

One note for anyone reproducing that locally: the tiers must be run one project at a time. dotnet test on the whole solution runs SampleServers.Tests and SampleClients.Tests concurrently, and because the samples bind fixed ports they collide — which shows up as a spurious BadNoCommunication / AddressAlreadyInUse failure. .azurepipelines/test.yml already warns that the job must not share an agent, but not that the projects race each other inside one run.

🤖 Generated with Claude Code

romanett and others added 2 commits August 26, 2026 21:58
  Microsoft.EntityFrameworkCore.Design       10.0.10  -> 10.0.11
  Microsoft.EntityFrameworkCore.SqlServer    10.0.10  -> 10.0.11
  Microsoft.Extensions.Hosting               10.0.10  -> 10.0.11
  Microsoft.Extensions.Logging.Abstractions  10.0.10  -> 10.0.11
  Microsoft.Extensions.Logging.Console       10.0.10  -> 10.0.11
  Microsoft.NET.Test.Sdk                     18.8.1   -> 18.9.0
  NUnit3TestAdapter                          6.2.0    -> 6.3.0
  Roslynator.Analyzers                       4.15.0   -> 5.0.0
  Roslynator.Formatting.Analyzers            4.15.0   -> 5.0.0
  Microsoft.CodeAnalysis.NetAnalyzers        10.0.302 -> 10.0.400

Everything else was already current: the fourteen OPC UA packages are on the
newest build the opcua-preview feed publishes (2.0.0-preview.2), and Mono.Options,
NUnit, NUnit.Analyzers, Serilog and the container tooling targets were all already
at their latest stable release.

EF Core, the Extensions packages and NetAnalyzers have 11.0.0 previews and NUnit
has a 5.0.0 beta, but the repository targets .NET 10 GA, so this stays on stable.

Neither the Roslynator 5.0 major bump nor the newer NetAnalyzers introduced any
new diagnostics.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The solution built with 128 distinct warnings across net48, netstandard2.1,
net8.0 and net10.0. It now builds clean in both Debug and Release.

Real defects, fixed in code:

  CA2000 (45)  ApplicationInstance is IAsyncDisposable only, so the sample
               entry points now dispose it in a finally (or with `await using`
               where Main is async). The two console hosts that outlive the
               method that creates the instance keep it in a field and dispose
               it during shutdown. TestClient.ConnectAsync moved to try/finally
               and clears its locals once the client takes ownership.
  CA2012 (10)  ValueTask results were read directly; they now go through AsTask().
  CA1849 (2)   TypeInfo.GetBuiltInType replaced by GetBuiltInTypeAsync.
  SYSLIB0057   X509Certificate2(byte[]) replaced by X509CertificateLoader.
  CS0618 (2)   Variant.Value replaced by AsBoxedObject().
  CA2213       The GDS client form now disposes its LocalDiscoveryServerClient.
  CA1508       Removed a null check that could never be true.
  CA1003       ApplicationRegistered now carries an EventArgs-derived type.
  CS9191, CS0109, CA2249, CA1307, CS8632 and CA1873 fixed in place.

CA1002 (49 sites) needed a decision. The 2.0 SDK replaced the old
XxxCollection : List<T> service types with the immutable ArrayOf<T>, but it
still hands mutable List<T> to anything a callee is meant to fill, so the rule
cannot simply be applied everywhere. Checking each site: exactly one -
MethodsNodeManager.OnStart - is a GenericMethodCalledEventHandler target whose
shape the SDK fixes, and it carries a SuppressMessage saying so. The other 48
were the samples' own controls and helpers, and are now IList<T> (or
IReadOnlyList<T> where ClientBase.ValidateResponse requires it), with
.ToArrayOf() at the service boundaries. IList<T> matches what the samples
already used elsewhere - FilterDefinition.EventTypes was IList<NodeId> next to
a List<T> sibling - and what the SDK itself uses for these roles.

The same pass converted twelve files that had been carrying CA1002
suppressions rather than warnings, for consistency. Twenty-five suppressions
were removed and one added; the twenty-two that remain are all on node manager
members whose List<T> parameters were verified against Opc.Ua.Server by
reflection (RootNotifiers, Read, Write, RemovePredefinedNode and the
HistoryRead/Update/Delete family) and cannot be reshaped.

.editorconfig is unchanged: no rule was silenced to reach zero warnings.

Verified: Debug and Release both build with no errors and no warnings, and all
247 tests pass (143 configuration, 88 server smoke, 16 client smoke) when the
tiers are run one at a time, since the samples bind fixed ports.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@romanett
romanett merged commit 4be541d into master Aug 26, 2026
1 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant