feat(plc4net): add .NET 8 API and SPI foundation - #2771
Conversation
|
Hi @splatch, the .NET Platform Compatibility and Dependency Review workflows for this PR are awaiting maintainer approval. Could you approve them when convenient? I would also appreciate a review of the public API/SPI contracts once CI has run. I will address any failures or feedback. Thanks. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Public response, cancellation, value-type, request immutability, temporal validation, and shutdown contracts contain unresolved correctness issues.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 8
Open (8)
Enable nullable warnings and correct nullable API contracts · New Use unsigned .NET types for unsigned PLC values · New Snapshot request tags when building · New Prevent built requests sharing mutable builder state · New Preserve multi-value writes and reject empty values · New Validate and normalize nanoseconds-of-second values · New Validate raw time-of-day constructor input · New Exit wait loop promptly when connection closes · New
What changed in this PR
Replaces the legacy PLC4Net API/SPI with a .NET 8 foundation, including value codecs, request/response infrastructure, transport abstractions, tests, packaging, and cross-platform CI.
Changes:
- Migrates and expands the public API, SPI runtime, value model, and codec infrastructure.
- Adds an in-memory transport and focused API/SPI lifecycle tests.
- Integrates .NET builds and tests into Maven and GitHub Actions.
| File | Description |
|---|---|
.github/workflows/dotnet-platform.yml |
Adds cross-platform .NET CI. |
plc4net/Directory.Build.props |
Centralizes .NET 8 and packaging settings. |
plc4net/PACKAGE.md |
Documents package contents and status. |
plc4net/api/IPlcConnection.cs |
Defines the connection API. |
plc4net/api/IPlcDriver.cs |
Defines the driver API. |
plc4net/api/PlcDriverManager.cs |
Adds the driver registry. |
plc4net/api/api.csproj |
Replaces the API project definition. |
plc4net/api/api/IPlcConnection.cs |
Removes the legacy duplicate. |
plc4net/api/api/IPlcDriver.cs |
Removes the legacy duplicate. |
plc4net/api/api/types/PlcValueType.cs |
Removes the legacy duplicate. |
plc4net/api/authentication/IPlcAuthentication.cs |
Adds authentication abstraction. |
plc4net/api/authentication/PlcUsernamePasswordAuthentication.cs |
Adds username/password authentication. |
plc4net/api/exceptions/PlcConnectionException.cs |
Modernizes connection exceptions. |
plc4net/api/exceptions/PlcException.cs |
Modernizes the base exception. |
plc4net/api/exceptions/PlcInvalidFieldException.cs |
Modernizes field exceptions. |
plc4net/api/extensions/Plc4NetServiceExtensions.cs |
Adds driver registration helpers. |
plc4net/api/messages/IPlcMessage.cs |
Updates the base message contract. |
plc4net/api/messages/IPlcReadRequest.cs |
Defines read requests. |
plc4net/api/messages/IPlcReadRequestBuilder.cs |
Updates read-request construction. |
plc4net/api/messages/IPlcReadResponse.cs |
Defines read responses. |
plc4net/api/messages/IPlcRequest.cs |
Adds executable request contracts. |
plc4net/api/messages/IPlcRequestBuilder.cs |
Adds the generic builder contract. |
plc4net/api/messages/IPlcResponse.cs |
Updates the response contract. |
plc4net/api/messages/IPlcSubscriptionEventArgs.cs |
Adds subscription event metadata. |
plc4net/api/messages/IPlcSubscriptionRequest.cs |
Updates subscription requests. |
plc4net/api/messages/IPlcSubscriptionRequestBuilder.cs |
Updates subscription builders. |
plc4net/api/messages/IPlcSubscriptionResponse.cs |
Updates subscription responses. |
plc4net/api/messages/IPlcTagRequest.cs |
Replaces field requests with tags. |
plc4net/api/messages/IPlcTagResponse.cs |
Replaces field responses with tags. |
plc4net/api/messages/IPlcUnsubscriptionRequest.cs |
Updates unsubscription requests. |
plc4net/api/messages/IPlcUnsubscriptionRequestBuilder.cs |
Updates unsubscription builders. |
plc4net/api/messages/IPlcUnsubscriptionResponse.cs |
Updates unsubscription responses. |
plc4net/api/messages/IPlcWriteRequest.cs |
Updates write requests. |
plc4net/api/messages/IPlcWriteRequestBuilder.cs |
Updates write-request construction. |
plc4net/api/messages/IPlcWriteResponse.cs |
Defines write responses. |
plc4net/api/metadata/DefaultPlcConnectionMetadata.cs |
Adds default capability metadata. |
plc4net/api/metadata/IPlcConnectionMetadata.cs |
Defines connection capabilities. |
plc4net/api/model/IPlcSubscriptionHandle.cs |
Adds subscription handles. |
plc4net/api/model/IPlcTag.cs |
Adds the tag abstraction. |
plc4net/api/types/PlcResponseCode.cs |
Extends response codes. |
plc4net/api/types/PlcValueType.cs |
Adds PLC value descriptors. |
plc4net/api/value/IPlcValue.cs |
Extends temporal value access. |
plc4net/plc4net.sln |
Rebuilds the solution structure. |
plc4net/pom.xml |
Adds Maven-driven .NET tests. |
plc4net/spi/drivers/ConnectionBase.cs |
Adds shared connection lifecycle handling. |
plc4net/spi/drivers/ConnectionString.cs |
Adds connection-string parsing. |
plc4net/spi/drivers/DriverBase.cs |
Adds transport selection and connection setup. |
plc4net/spi/drivers/MessageCodecBase.cs |
Adds polling message framing. |
plc4net/spi/drivers/ScanExtensions.cs |
Adds driver assembly scanning. |
plc4net/spi/drivers/functions/PlcReader.cs |
Defines driver read execution. |
plc4net/spi/drivers/functions/PlcWriter.cs |
Defines driver write execution. |
plc4net/spi/drivers/messages/DefaultPlcReadRequest.cs |
Implements read requests. |
plc4net/spi/drivers/messages/DefaultPlcReadRequestBuilder.cs |
Implements read builders. |
plc4net/spi/drivers/messages/DefaultPlcReadResponse.cs |
Implements read responses. |
plc4net/spi/drivers/messages/DefaultPlcWriteRequest.cs |
Implements write requests. |
plc4net/spi/drivers/messages/DefaultPlcWriteRequestBuilder.cs |
Implements write builders. |
plc4net/spi/drivers/messages/DefaultPlcWriteResponse.cs |
Implements write responses. |
plc4net/spi/drivers/messages/items/DefaultPlcResponseItem.cs |
Implements response items. |
plc4net/spi/drivers/messages/items/DefaultPlcTagErrorItem.cs |
Adds tag-level errors. |
plc4net/spi/drivers/messages/items/DefaultPlcTagItem.cs |
Implements tag items. |
plc4net/spi/drivers/messages/items/DefaultPlcTagValueItem.cs |
Implements tag/value items. |
plc4net/spi/drivers/messages/items/PlcResponseItem.cs |
Defines response items. |
plc4net/spi/drivers/messages/items/PlcTagItem.cs |
Defines tag items. |
plc4net/spi/drivers/messages/items/PlcTagValueItem.cs |
Defines tag/value items. |
plc4net/spi/drivers/tags/PlcTagHandler.cs |
Defines protocol tag parsing. |
plc4net/spi/generation/BitReader.cs |
Adds MSB-first bit decoding. |
plc4net/spi/generation/BitWriter.cs |
Adds MSB-first bit encoding. |
plc4net/spi/generation/ByteOrder.cs |
Cleans byte-order support. |
plc4net/spi/generation/EvaluationHelper.cs |
Reformats generation helpers. |
plc4net/spi/generation/ParseException.cs |
Adds throwable parse errors. |
plc4net/spi/generation/ReadBuffer.cs |
Replaces generated-data decoding. |
plc4net/spi/generation/WriteBuffer.cs |
Replaces generated-data encoding. |
plc4net/spi/model/values/PlcBOOL.cs |
Implements Boolean values. |
plc4net/spi/model/values/PlcBYTE.cs |
Implements byte bit strings. |
plc4net/spi/model/values/PlcBitString.cs |
Adds shared bit-string behavior. |
plc4net/spi/model/values/PlcCHAR.cs |
Implements character values. |
plc4net/spi/model/values/PlcDATE.cs |
Implements calendar dates. |
plc4net/spi/model/values/PlcDATE_AND_LTIME.cs |
Implements nanosecond date-times. |
plc4net/spi/model/values/PlcDATE_AND_TIME.cs |
Implements date-times. |
plc4net/spi/model/values/PlcDINT.cs |
Implements signed 32-bit values. |
plc4net/spi/model/values/PlcDWORD.cs |
Implements 32-bit bit strings. |
plc4net/spi/model/values/PlcINT.cs |
Implements signed 16-bit values. |
plc4net/spi/model/values/PlcLINT.cs |
Implements signed 64-bit values. |
plc4net/spi/model/values/PlcLREAL.cs |
Implements double values. |
plc4net/spi/model/values/PlcLTIME.cs |
Implements nanosecond durations. |
plc4net/spi/model/values/PlcLTIME_OF_DAY.cs |
Implements nanosecond times of day. |
plc4net/spi/model/values/PlcLWORD.cs |
Implements 64-bit bit strings. |
plc4net/spi/model/values/PlcList.cs |
Implements list values. |
plc4net/spi/model/values/PlcNULL.cs |
Implements null values. |
plc4net/spi/model/values/PlcREAL.cs |
Implements float values. |
plc4net/spi/model/values/PlcRawByteArray.cs |
Implements raw byte values. |
plc4net/spi/model/values/PlcSINT.cs |
Implements signed 8-bit values. |
plc4net/spi/model/values/PlcSTRING.cs |
Implements string values. |
plc4net/spi/model/values/PlcSimpleNumericValueAdapter.cs |
Adds numeric conversions. |
plc4net/spi/model/values/PlcSimpleValueAdapter.cs |
Fixes simple-value dispatch. |
plc4net/spi/model/values/PlcStruct.cs |
Implements structured values. |
plc4net/spi/model/values/PlcTIME.cs |
Implements durations. |
plc4net/spi/model/values/PlcTIME_OF_DAY.cs |
Implements times of day. |
plc4net/spi/model/values/PlcUDINT.cs |
Implements unsigned 32-bit values. |
plc4net/spi/model/values/PlcUINT.cs |
Implements unsigned 16-bit values. |
plc4net/spi/model/values/PlcULINT.cs |
Implements unsigned 64-bit values. |
plc4net/spi/model/values/PlcUSINT.cs |
Implements unsigned 8-bit values. |
plc4net/spi/model/values/PlcValueAdapter.cs |
Updates base value conversions. |
plc4net/spi/model/values/PlcWCHAR.cs |
Implements wide characters. |
plc4net/spi/model/values/PlcWORD.cs |
Implements 16-bit bit strings. |
plc4net/spi/model/values/PlcWSTRING.cs |
Implements wide strings. |
plc4net/spi/spi.csproj |
Retargets and packages the SPI. |
plc4net/spi/spi/generation/ReadBuffer.cs |
Removes legacy buffer implementation. |
plc4net/spi/spi/generation/WriteBuffer.cs |
Removes legacy buffer implementation. |
plc4net/spi/spi/model/values/PlcDWORD.cs |
Removes legacy duplicate value. |
plc4net/spi/spi/model/values/PlcLWORD.cs |
Removes legacy duplicate value. |
plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs |
Removes legacy numeric adapter. |
plc4net/spi/spi/model/values/PlcStruct.cs |
Removes legacy struct implementation. |
plc4net/spi/transports/BaseTransportInstance.cs |
Adds common transport lifecycle behavior. |
plc4net/spi/transports/ITransport.cs |
Defines transport factories and registry. |
plc4net/spi/transports/ITransportInstance.cs |
Defines transport-instance contracts. |
plc4net/spi/transports/RingBuffer.cs |
Adds buffered transport storage. |
plc4net/spi/transports/TransportException.cs |
Adds transport failures. |
plc4net/test/spi-test/drivers/ConnectionStringTests.cs |
Tests connection-string parsing. |
plc4net/test/spi-test/drivers/DriverBaseTests.cs |
Tests connection lifecycle behavior. |
plc4net/test/spi-test/drivers/MessageCodecBaseTests.cs |
Tests framing and resynchronization. |
plc4net/test/spi-test/drivers/MessagesTests.cs |
Tests request/response behavior. |
plc4net/test/spi-test/drivers/PlcDriverManagerTests.cs |
Tests driver registration. |
plc4net/test/spi-test/generation/BufferTests.cs |
Tests bit and value codecs. |
plc4net/test/spi-test/model/values/PlcValueTests.cs |
Tests value-model dispatch. |
plc4net/test/spi-test/spi-test.csproj |
Adds the SPI test project. |
plc4net/test/spi-test/transports/RingBufferTests.cs |
Tests ring-buffer boundaries. |
plc4net/test/spi-test/transports/TestTransportTests.cs |
Tests in-memory transport behavior. |
plc4net/transports/test/TestTransport.cs |
Adds the test transport factory. |
plc4net/transports/test/TestTransportConfiguration.cs |
Adds test transport configuration. |
plc4net/transports/test/TestTransportInstance.cs |
Implements the in-memory transport. |
plc4net/transports/test/test.csproj |
Retargets and packages the test transport. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
3be17b2 to
bdf9656
Compare
… safety Consolidates three related fixes into a single commit: 1. Enable nullable analysis (Directory.Build.props) and correct nullable contracts - Switches from 'annotations' to 'enable' for full null-safety checking - Annotates feature-gated builders, transports, authentication as nullable - Makes PlcValueAdapter reference-type accessors throw instead of returning null 2. Align DefaultDotNetType table to native .NET storage types - WORD/DWORD/LWORD: short/int/long → ushort/uint/ulong (unsigned) - USINT/UINT/UDINT: ushort/uint/ulong → byte/ushort/uint (unsigned) - WCHAR: short → char (actual storage) - DATE/LDATE: DateTime → DateOnly (actual storage) - TIME_OF_DAY/LTIME_OF_DAY: TimeSpan → TimeOnly (actual storage) 3. Add numeric bounds validation for temporal fields - PlcLTIME.GetDuration(): check nanoseconds overflow - PlcDATE_AND_LTIME: validate nanosecondsOfSecond in [0, 999_999_999] - PlcDATE_AND_LTIME.OfSegments(): validate nanoseconds parameter - PlcLTIME_OF_DAY: guard against overflow on large values Tests: 138/138 passing Build: 0 errors, 0 warnings
bdf9656 to
8379e30
Compare
#2771 regenerated the solution file and dropped its license header, which fails the root apache-rat license-check. The .NET workflow does not run it, so the break only surfaced on the next commit touching the other languages.

This is the next slice of #2656, following #2761.
It replaces the remaining net452 API and SPI projects with .NET 8 versions, adds an in-memory test transport and focused SPI tests, and adds cross-platform CI plus a Maven test phase. Protocol drivers and production transports will follow in separate PRs.
Verification:
Please focus review on the public API/SPI contracts and the request, response, and transport lifecycles. Subscription interfaces are declared but not implemented yet, and the transport contract is polling based. Feedback on these contracts is welcome before the driver PRs land.