Files
UA-.NETStandard/Directory.Packages.props
Marc Schier dbc09b8e22 Adopt System.TimeProvider across the stack (fixes #2458) (#3829)
# 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.
2026-06-03 22:38:32 +02:00

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>