Skip to content

feat(plc4net): add .NET 8 API and SPI foundation - #2771

Merged
sruehl merged 2 commits into
apache:developfrom
openIndu:feat/plc4net-spi3-runtime
Sep 25, 2026
Merged

sruehl merged 2 commits into
apache:developfrom
openIndu:feat/plc4net-spi3-runtime

Conversation

@TomNewChao

Copy link
Copy Markdown
Contributor

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:

  • Debug and Release: 114/114 tests passed; Release build had zero warnings.
  • Maven test, Apache RAT, and dotnet format checks passed.
  • The NuGet audit reported no vulnerable packages.

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.

@TomNewChao

Copy link
Copy Markdown
Contributor Author

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Medium severity

Open (8)
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.

Comment thread plc4net/Directory.Build.props Outdated
Comment thread plc4net/api/types/PlcValueType.cs Outdated
Comment thread plc4net/spi/drivers/messages/DefaultPlcReadRequestBuilder.cs
Comment thread plc4net/spi/drivers/messages/DefaultPlcWriteRequestBuilder.cs
Comment thread plc4net/spi/drivers/messages/DefaultPlcWriteRequestBuilder.cs Outdated
Comment thread plc4net/spi/model/values/PlcDATE_AND_LTIME.cs Outdated
Comment thread plc4net/spi/model/values/PlcLTIME_OF_DAY.cs
Comment thread plc4net/transports/test/TestTransportInstance.cs
@TomNewChao
TomNewChao force-pushed the feat/plc4net-spi3-runtime branch from 3be17b2 to bdf9656 Compare September 24, 2026 23:17
… 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
@TomNewChao
TomNewChao force-pushed the feat/plc4net-spi3-runtime branch from bdf9656 to 8379e30 Compare September 24, 2026 23:26
@TomNewChao

TomNewChao commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor Author

@sruehl @splatch Copilot review findings have been addressed with numeric safety validation, nullable type contracts, and Java parity fixes. Windows CI validation passed. Ready for GitHub Actions CI and maintainer review.

@sruehl
sruehl merged commit 676de7e into apache:develop Sep 25, 2026
4 checks passed
sruehl added a commit that referenced this pull request Sep 25, 2026
#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.
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.

3 participants