Files
UA-.NETStandard/Applications/ConsoleReferenceClient/ConsoleReferenceClient.csproj
T
Marc Schier 34ed5716c0 Add structure-backed OptionSet DataType support in ComplexTypeSystem (#3672)
Concrete sub-types of the abstract OptionSet DataType (i=12755, e.g. AccessRights, CarExtras, OptionSetBase) were silently skipped by ComplexTypeSystem.LoadBaseStructureDataTypesAsync when only an EnumDefinition or OptionSetValues property was available. This change registers them with a new runtime class Opc.Ua.Encoders.OptionSet that reuses the generated Opc.Ua.OptionSet wire format (Value/ValidBits ByteStrings) and self-registers via IEncodeableType.

Key changes:

- New Stack/Opc.Ua/Types/OptionSet.cs with EnumDefinition-driven bit accessors (by name and index), GetSetFieldNames helper, and a fixed ByteLength derived from the highest declared bit per OPC UA Part 3 paragraph 8.40 / 3.2.8. SetBit throws ArgumentOutOfRangeException outside that range and always materializes Value/ValidBits to the fixed length.

- New AddOptionSetType entry point on IComplexTypeBuilder (source-breaking addition for custom implementations); DefaultComplexTypeBuilder implements it. The Reflection.Emit ComplexTypeBuilder throws NotSupportedException.

- ComplexTypeSystem detects OptionSet descendants via a HasSubtype walk and resolves the EnumDefinition from DataTypeDefinition or the OptionSetValues property fallback before the old skip path.

- Removed stale V1.04 OptionSet limitation remark from ComplexTypeSystem.

- 10 unit tests in Tests/Opc.Ua.Client.Tests/ComplexTypes/DefaultOptionSetTests.cs covering factory registration, bit accessors, binary round-trip via ExtensionObject, hand-crafted Part 6 wire format, Clone/CreateInstance semantics, and the ByteLength invariant.

- Live-verified against opc.tcp://DESKTOP-BGFJS91:48010 (UA C++ SDK demo): AccessRights/CarExtras/OptionSetBase now appear in the registered custom-type list; no skip-log entries; LoadAsync(throwOnError:true) returns true.

- Docs/ComplexTypes.md Known Limitations reworded; Docs/MigrationGuide.md gains an OptionSet DataType support subsection.

UInteger-backed OptionSet DataTypes remain intentionally opaque (carried as their unsigned integer in a Variant).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 21:16:55 +02:00

39 lines
1.9 KiB
XML

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(AppTargetFrameWorks)</TargetFrameworks>
<AssemblyName>ConsoleReferenceClient</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>ConsoleReferenceClient</PackageId>
<Company>OPC Foundation</Company>
<Description>.NET Console Reference Client</Description>
<Copyright>Copyright © 2004-2024 OPC Foundation, Inc</Copyright>
<RootNamespace>Quickstarts.ConsoleReferenceClient</RootNamespace>
<PublishAot Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net10.0'))">true</PublishAot>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\ConsoleReferenceServer\ConsoleUtils.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="Microsoft.Extensions.Configuration" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<PackageReference Include="System.CommandLine" />
<PackageReference Include="Serilog" />
<PackageReference Include="Serilog.Extensions.Logging" />
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="Serilog.Sinks.File" />
<PackageReference Include="Serilog.Sinks.Debug" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Stack\Opc.Ua.Core\Opc.Ua.Core.csproj" />
<ProjectReference Include="..\..\Libraries\Opc.Ua.Configuration\Opc.Ua.Configuration.csproj" />
<ProjectReference Include="..\..\Libraries\Opc.Ua.Client\Opc.Ua.Client.csproj" />
<ProjectReference Include="..\..\Libraries\Opc.Ua.Client.ComplexTypes\Opc.Ua.Client.ComplexTypes.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Quickstarts.ReferenceClient.Config.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>