mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-24 11:01:55 +08:00
# Description Adopt [`System.TimeProvider`](https://learn.microsoft.com/dotnet/api/system.timeprovider) across the stack so that every place that creates timers, runs duration math, or schedules periodic work is mockable, deterministic in tests, and immune to wall-clock changes. The migration touches Core, Core.Types, Server, Client, PubSub, Configuration, Gds (server + client), Lds, and the Quickstarts/Console reference apps. Per-component changes follow the same pattern: 1. Add a `private readonly TimeProvider m_timeProvider;` field. 2. Accept a nullable `TimeProvider? timeProvider = null` as the **last** constructor parameter (new overload; legacy constructor stays for binary compatibility and delegates with `timeProvider: null`). 3. Initialise the field with `m_timeProvider = timeProvider ??= TimeProvider.System;`. 4. Replace `new Timer(...)`, `Stopwatch`, `HiResClock.*`, `DateTime.UtcNow`-based duration math, and `Task.Delay(delay, ct)` in timing loops with the matching `m_timeProvider` API (`CreateTimer`, `GetTimestamp` / `GetElapsedTime`, `GetUtcNow().UtcDateTime`, `Task.Delay(delay, m_timeProvider, ct)`). 5. Wire the provider through DI: `AddOpcUaServerBuilder` / `AddOpcUaClientBuilder` register `TimeProvider.System` via `TryAddSingleton<TimeProvider>()` so tests can swap in `Microsoft.Extensions.Time.Testing.FakeTimeProvider`. `HiResClock` itself is kept (so the `ApplicationConfiguration.DisableHiResClock` schema flag still round-trips), but **every public member** is now `[Obsolete]` with a single shared message pointing to the new migration-guide section. The few internal call sites that still need to set/read `HiResClock` are wrapped with `#pragma warning disable CS0618`. ### Highlights per component - **Core / Stack** — `Opc.Ua.Core`, `Opc.Ua.Core.Types`, channel pipeline (`UaSCBinaryClientChannel`, `ChannelToken`, `UaSCBinaryChannel`), `ApplicationConfiguration`, certificate validators, `JwksIssuerKeyResolver`, `TimeProviderExtensions` polyfills (`GetTimestampMilliseconds`, `GetTickCount`, `CancellationTokenSource(timeout, timeProvider)`, `Task.Delay(delay, provider, ct)` polyfill for older TFMs). - **Server** — session lockout, subscription pipeline (publish/sample/keep-alive/lifetime), `MonitoredItemQueue`, alarm sampling rate, `IntervalRunner`, server diagnostics, configuration state machines, hosted services. - **Client** — `Session`, managed/V2 subscription engines, reconnect handlers, channel keep-alive, periodic publishing, complex-type discovery polling. - **PubSub** — `IntervalRunner` pipeline, message-receive timers, MQTT/UDP keep-alive, publishers/readers. - **Gds / Lds** — `LdsServer`, `LinqApplicationsDatabase` expiry housekeeping, GDS clients (push, pull), `DirectoryCertificateStore`, `ConnectionStateMachine`, classic subscription engine. - **Quickstarts / Console samples** — `SampleNodeManager`, `ReferenceNodeManager`, `AlarmNodeManager`, `BoilerState`, `MemoryBufferState`, `PublishedValuesWrites`. Samples resolve via `(Server as ITimeProviderProvider)?.TimeProvider ?? TimeProvider.System` so existing ctor signatures stay binary-compatible. - **Tests** — `Opc.Ua.PubSub.Tests` adds `IntervalRunnerTests`; existing `SubscriptionTests`, `UaPublisherTests`, and `TestDataSystem` move off `HiResClock`. Added `Microsoft.Extensions.TimeProvider.Testing` package for `FakeTimeProvider` (project-load warning surfaces on net48/net472 only — runtime is .NET 8+). ### Migration guide New section [**Time and Timer abstraction (`TimeProvider`)**](Docs/MigrationGuide.md#time-and-timer-abstraction-timeprovider) documents: - The canonical replacement table (`HiResClock.UtcNow` → `timeProvider.GetUtcNow().UtcDateTime`, `HiResClock.TickCount64` → `timeProvider.GetTimestamp()`, `new Timer` → `timeProvider.CreateTimer`, `Task.Delay(delay, ct)` → `Task.Delay(delay, timeProvider, ct)`, …). - The `TimeProvider? timeProvider = null` + `??=` constructor pattern. - DI wiring and how to swap in `FakeTimeProvider` in tests. - Before/after snippets for `HiResClock.TickCount64`, `HiResClock.UtcNow`, and `new Timer(...)`. ## Related Issues - Fixes #2458 ## Checklist - [x] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [x] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added all necessary documentation. - [x] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [ ] I have addressed **all** PR feedback received.
83 lines
5.9 KiB
XML
83 lines
5.9 KiB
XML
<Project>
|
|
<PropertyGroup>
|
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
|
</PropertyGroup>
|
|
<ItemGroup>
|
|
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
|
|
<PackageVersion Include="BitFaster.Caching" Version="2.6.0" />
|
|
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.6.2" />
|
|
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
|
|
<PackageVersion Include="DotNext" Version="5.26.3" />
|
|
<PackageVersion Include="EmbedIO" Version="3.5.2" />
|
|
<PackageVersion Include="Makaretu.Dns.Multicast" Version="0.27.0" />
|
|
<PackageVersion Include="Microsoft.AspNetCore.Http" Version="2.3.10" />
|
|
<PackageVersion Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.3.10" />
|
|
<PackageVersion Include="Microsoft.AspNetCore.Server.Kestrel.Core" Version="2.3.10" />
|
|
<PackageVersion Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.3.10" />
|
|
<PackageVersion Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" Version="2.3.10" />
|
|
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="6.0.0" />
|
|
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.0" />
|
|
<PackageVersion Include="Microsoft.Bcl.TimeProvider" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="4.14.0" />
|
|
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" />
|
|
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.3.0" />
|
|
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Diagnostics" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.8" />
|
|
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.6.0" />
|
|
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
|
|
<PackageVersion Include="ModelContextProtocol" Version="1.3.0" />
|
|
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="1.3.0" />
|
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.6.0" />
|
|
<PackageVersion Include="Microsoft.SourceLink.AzureRepos.Git" Version="10.0.102" />
|
|
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.102" />
|
|
<PackageVersion Include="System.CommandLine" Version="2.0.8" />
|
|
<PackageVersion Include="Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers" Version="18.7.37220.1" />
|
|
<PackageVersion Include="Moq" Version="4.20.72" />
|
|
<PackageVersion Include="TUnit" Version="1.48.6" />
|
|
<PackageVersion Include="MQTTnet" Version="5.1.0.1559" />
|
|
<PackageVersion Include="Nerdbank.GitVersioning" Version="3.9.50" />
|
|
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
|
|
<PackageVersion Include="NUnit" Version="4.6.1" />
|
|
<PackageVersion Include="NUnit.Analyzers" Version="4.14.0" />
|
|
<PackageVersion Include="NUnit.Console" Version="3.22.0" />
|
|
<PackageVersion Include="NUnit3TestAdapter" Version="6.2.0" />
|
|
<PackageVersion Include="ObjectLayoutInspector" Version="0.2.0" />
|
|
<PackageVersion Include="PolySharp" Version="1.16.0" />
|
|
<PackageVersion Include="Roslynator.Analyzers" Version="4.15.0" />
|
|
<PackageVersion Include="Roslynator.Formatting.Analyzers" Version="4.15.0" />
|
|
<PackageVersion Include="SharpFuzz" Version="2.2.0" />
|
|
<PackageVersion Include="Serilog" Version="4.3.1" />
|
|
<PackageVersion Include="Serilog.Expressions" Version="5.0.0" />
|
|
<PackageVersion Include="Serilog.Extensions.Logging" Version="10.0.0" />
|
|
<PackageVersion Include="Serilog.Sinks.Console" Version="6.1.1" />
|
|
<PackageVersion Include="Serilog.Sinks.Debug" Version="3.0.0" />
|
|
<PackageVersion Include="Serilog.Sinks.File" Version="7.0.0" />
|
|
<PackageVersion Include="SourceGenerator.Foundations" Version="2.0.14" />
|
|
<PackageVersion Include="System.Buffers" Version="4.6.1" />
|
|
<PackageVersion Include="System.Composition.AttributedModel" Version="10.0.8" />
|
|
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.2" />
|
|
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="10.0.8" />
|
|
<PackageVersion Include="System.Memory" Version="4.6.3" />
|
|
<PackageVersion Include="System.Formats.Asn1" Version="10.0.8" />
|
|
<PackageVersion Include="System.IO.Compression" Version="4.3.0" />
|
|
<PackageVersion Include="System.Net.NetworkInformation" Version="4.3.0" />
|
|
<PackageVersion Include="System.Collections.Immutable" Version="10.0.8" />
|
|
<PackageVersion Include="System.Reflection.Metadata" Version="10.0.6" />
|
|
<PackageVersion Include="System.Text.Json" Version="10.0.8" />
|
|
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
|
|
<PackageVersion Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
|
|
<PackageVersion Include="System.Security.Cryptography.Cng" Version="5.0.0" />
|
|
<PackageVersion Include="System.Threading.Channels" Version="10.0.8" />
|
|
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.6.3" />
|
|
</ItemGroup>
|
|
</Project> |