OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer 2.0.0-preview.4

Prefix Reserved
This is a prerelease version of OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer.

Requires NuGet 2.12 or higher.

dotnet add package OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer --version 2.0.0-preview.4
                    
NuGet\Install-Package OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer -Version 2.0.0-preview.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer" Version="2.0.0-preview.4">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer" Version="2.0.0-preview.4" />
                    
Directory.Packages.props
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer --version 2.0.0-preview.4
                    
#r "nuget: OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer, 2.0.0-preview.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer@2.0.0-preview.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer&version=2.0.0-preview.4&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer&version=2.0.0-preview.4&prerelease
                    
Install as a Cake Tool

OPC UA migration analyzers, code fixers, source generator, and compatibility shim

What you get

A single NuGet install (OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer) that ships three Roslyn components + a runtime shim to help migrate from OPC UA .NET Standard 1.5.378 to 2.0:

  • a Roslyn analyzer + code-fixer set (26 implemented rules through UA0030, excluding UA0013, UA0016, UA0017, and the shim-only UA0029) that flags the automatable patterns covered by the 2.0 migration guide and, where safe, applies the fix automatically;
  • a Roslyn source generator (Opc.Ua.MigrationAnalyzer.Generator.dll) that emits per-consumer public sealed [Obsolete] class <Name>Collection : List<TElement> shims for every <Type>Collection wrapper the consumer references but that 2.0 removed — including model-compiled <UserType>Collection patterns, not just the built-in ones. Element types renamed across the 1.5.378 → 2.0 boundary (DateTimeDateTimeUtc, GuidUuid, byte[]ByteString) are pinned through a small override table; the legacy XmlElementCollection interpretation is pinned to System.Xml.XmlElement to disambiguate it from Opc.Ua.XmlElement. Everything else resolves from consumer source declarations, then from exact System.<Type> or Opc.Ua.<Type> metadata names; and
  • a compatibility shim assembly (Opc.Ua.MigrationAnalyzer.Core.dll) that re-supplies the obsolete extension surface 2.0 moved or removed, so most consumer projects still compile after the upgrade.

The generator emits public shim types so legacy <Type>Collection usage can continue compiling while you migrate incrementally. Keep treating each [Obsolete] + UA0002 site as a migration step to List<T> / ArrayOf<T>.

How to migrate

  1. Add the 2.0 OPC UA packages and the MigrationAnalyzer package to your consumer project. The package is public on nuget.org; the floating version resolves the latest published 2.0.0-preview.N release:

    <PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer" Version="2.0.0-preview.*" PrivateAssets="all" />
    
  2. Run dotnet build. Your code should compile: the shim covers the [Obsolete] extension surface that 2.0 moved or removed; the source generator covers <Type>Collection wrappers; what remains are warnings rather than errors.

  3. Walk through the UA00xx analyzer warnings in the IDE and apply the offered auto-fixes. A handful (UA0001, UA0011, UA0015, UA0018, UA0021) are Info-level and need a manual review. The warning-level UA0023UA0028 and UA0030 are also diagnostic-only. A single generator diagnostic (MIG01) fires when the generator can't resolve a unique element type from consumer source or exact System.<Type> / Opc.Ua.<Type> metadata names. Migrate the site manually or define the legacy wrapper explicitly. Calls to shimmed SecurityPolicies statics surface as CS0618 messages tagged UA0029; no analyzer reports that marker, so migrate those calls manually.

  4. Once the project is warning-free, remove the OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer package reference. You are on clean 2.0 with no shim dependency.

Rules

ID Default Replaces
UA0001 Info Utils.Trace / Utils.LogX
UA0002 Warning Removed <Type>Collection wrappers
UA0003 Warning x == null on now-struct built-in types
UA0004 Warning ?. on now-struct built-in types
UA0005 Warning byte[] where ByteString is now expected
UA0006 Warning new Variant(object\|DateTime\|Guid\|byte[])
UA0007 Warning new NodeId(string) / new ExpandedNodeId(string)
UA0008 Warning Session.Call(..., params object[]) argument wrapping
UA0009 Warning [DataContract]/[DataMember] on configuration extensions
UA0010 Warning using/Dispose on CertificateIdentifier, UserIdentity, IUserIdentityTokenHandler
UA0011 Info Sync IUserIdentityTokenHandler.Encrypt/Decrypt/Sign/Verify
UA0012 Warning CertificateFactory.* static helpers
UA0014 Warning DataValue.IsGood(dv) static helper
UA0015 Info Sync / APM members on GDS / LDS clients
UA0018 Info CertificateIdentifier.Certificate getter
UA0019 Warning new DataValue(StatusCode[, ts])
UA0020 Warning EncodeableFactory.GlobalFactory / Create()
UA0021 Info CertificateValidator / CertificateValidationEventArgs (structural rename in 2.0)
UA0022 Warning ApplicationConfiguration.CertificateValidator / ServerBase.CertificateValidator (renamed in 2.0 to .CertificateManager)
UA0023 Warning Legacy PubSub top-level types and UaPubSubApplication.Create*
UA0024 Warning Exposed server, session, and subscription diagnostics locks
UA0025 Warning ILocalNode.DataLock / Node.DataLock
UA0026 Warning BaseVariableValue.Lock
UA0027 Warning NodeBrowser.DataLock
UA0028 Warning ApplicationConfiguration.PropertiesLock
UA0029 Shim/manual marker only: SecurityPolicies lookup and cryptography statics moved to ISecurityPolicyRegistry; no analyzer currently reports this ID
UA0030 Warning Server ISubscription publish-pipeline members and SessionPublishQueue became internal

What the shim provides

Opc.Ua.MigrationAnalyzer.Core.dll is delivered as a regular reference assembly and re-exposes the 1.5.378 surface in two flavors:

  • Moved obsolete extensions the 2.0 libraries no longer carry inline: NodeId / Variant / DataValue null-check helpers, Session sync helpers, Subscription sync helpers, ApplicationInstance helpers, ServerBase.Start / Stop, TransportChannel APM (BeginX / EndX), ChannelBase static factory methods, and similar surface.
  • New shims for genuinely-removed members:
    • EncodeableFactory.GlobalFactory
    • CertificateIdentifier.Certificate (throws NotSupportedException)
    • sync wrappers for IUserIdentityTokenHandler.{Encrypt,Decrypt,Sign,Verify}
    • sync + APM wrappers for the GDS / LDS client APIs.
    • SecurityPolicies lookup and cryptography statics marked for manual ISecurityPolicyRegistry migration (UA0029; surfaced as CS0618, not an analyzer diagnostic).

What the shim does NOT cover

These changes are source-level only; no extension method can paper over them. Use the listed analyzer fix.

  • == null / != null on now-struct types — use the UA0003 fixer.
  • ?. member access on now-struct types — use the UA0004 fixer.
  • using var x = new CertificateIdentifier(...) — use the UA0010 fixer to drop the using / Dispose call.
  • [DataContract] / [DataMember] on configuration extension classes — use the UA0009 fixer.
  • Removed <Type>Collection wrappers such as Int32Collection, NodeIdCollection, etc. — use the UA0002 fixer to rewrite to List<T>, then manually use ArrayOf<T> at applicable API boundaries.

Sync-over-async caveat

The sync shims (for example handler.Encrypt(bytes), gdsClient.RegisterApplication(...), the Session / Subscription sync helpers) wrap their *Async counterparts via Task.Run(() => …Async(...)).GetAwaiter().GetResult(). This is intended as a migration aid only: it keeps legacy call sites compiling while you port them to async/await. Do not leave these calls on production hot paths — follow the UA0011 / UA0015 guidance and switch to the async APIs.

TreatWarningsAsErrors recipe

If your project sets <TreatWarningsAsErrors>true</TreatWarningsAsErrors> and you cannot relax it during the migration window, exclude the migration diagnostics from the failure set:

<PropertyGroup>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  <NoWarn>$(NoWarn);CS0612;CS0618;MIG01;UA0001;UA0002;UA0003;UA0004;UA0005;UA0006;UA0007;UA0008;UA0009;UA0010;UA0011;UA0012;UA0014;UA0015;UA0018;UA0019;UA0020;UA0021;UA0022;UA0023;UA0024;UA0025;UA0026;UA0027;UA0028;UA0030</NoWarn>
</PropertyGroup>

Remove each entry as you finish fixing the corresponding rule, and drop the whole block once the MigrationAnalyzer package is removed.

Packaging note

The package ships three Roslyn component DLLs under analyzers/dotnet/roslyn<major>.<minor>/cs/. The .NET SDK loads that folder when its compiler supports the Roslyn API and ignores it otherwise, so an older host cleanly skips the analyzer rather than failing to load it:

Roslyn API Minimum host
4.14 Visual Studio 2022 17.14 / .NET SDK 9.0.300+
5.0 Visual Studio 2026 18.0 / .NET 10 SDK

.NET SDK 9.0.100 and 9.0.200 carry Roslyn 4.12 and 4.13 respectively; neither can load the package's oldest analyzer payload.

Always use the latest available .NET SDK servicing release in the supported 9.x or 10.x band; servicing releases contain the security fixes needed for production.

  • Opc.Ua.MigrationAnalyzer.dll — the analyzer assembly. References only Microsoft.CodeAnalysis.CSharp so it loads cleanly in csc.exe's analyzer host (which ships only Microsoft.CodeAnalysis.dll + CSharp.dll, not Workspaces). All DiagnosticAnalyzer types live here.
  • Opc.Ua.MigrationAnalyzer.CodeFixer.dll — the code-fix assembly. References Microsoft.CodeAnalysis.CSharp.Workspaces and hosts all CodeFixProvider types. Loaded only by Workspaces-aware hosts (Visual Studio / dotnet format).
  • Opc.Ua.MigrationAnalyzer.Generator.dll — the source generator that emits the <Type>Collection shims.

The analyzer / code-fix split is necessary because shipping a single DLL that references Workspaces silently fails to load in csc.exe at command-line build time — csc loads the assembly but JIT-resolution of Workspaces types fails (DLL not in bincore), and the analyzer host swallows the load failure, producing zero diagnostics. Splitting keeps the analyzer host happy while preserving full IDE/dotnet format code-fix functionality.

RS1038 (suggesting separation) is the Roslyn rule that recommends this layout; it is satisfied implicitly by the two-DLL design.

Suppression recipes

To suppress an individual rule for a single line:

#pragma warning disable UA0008 // Wrap Session.Call arguments with Variant.From
session.Call(objectId, methodId, "legacy");
#pragma warning restore UA0008

To set a project-wide severity, add to your .editorconfig:

[*.cs]
dotnet_diagnostic.UA0001.severity = none      # silence UA0001 entirely
dotnet_diagnostic.UA0008.severity = error     # treat UA0008 as an error
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
.NET Framework net472 is compatible.  net48 is compatible.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0-preview.4 65 9/2/2026
2.0.0-preview.3 74 8/28/2026
2.0.0-preview.2 66 8/24/2026