更新客户端渲染,更新了壳

This commit is contained in:
QWQLwToo
2026-07-06 23:05:40 +08:00
parent e7dd87bf7e
commit 31d778710b
1311 changed files with 172662 additions and 1582 deletions
@@ -0,0 +1,208 @@
# ADR-001: Multi-Target Framework Support
## Status
Accepted
## Context
The WPF UI library needs to support a wide range of .NET implementations to maximize compatibility with existing projects while leveraging modern .NET features where available.
### Supported Frameworks
- **.NET 10, 9, 8** - Modern .NET with Windows-specific APIs
- **.NET Framework 4.8.1, 4.7.2, 4.6.2** - Legacy enterprise applications
- **.NET Standard 2.0, 2.1** - Abstractions library only (maximizes compatibility)
## Decision
### Core Library (Wpf.Ui)
Target frameworks: `net10.0-windows;net9.0-windows;net8.0-windows;net481;net472;net462`
**Rationale:**
- Windows-specific project requires `-windows` TFM suffix for .NET 5+
- .NET Framework support ensures compatibility with legacy WPF applications
- Multi-version .NET support provides upgrade path for consumers
### Abstractions Library (Wpf.Ui.Abstractions)
Target frameworks: `net10.0;net9.0;net8.0;net462;netstandard2.1;netstandard2.0`
**Rationale:**
- No WPF dependencies allows broader compatibility
- .NET Standard 2.0 enables use in class libraries shared between .NET Framework and .NET Core/5+
- AOT-compatible (aot_compatible: true) for modern deployment scenarios
### DI Integration (Wpf.Ui.DependencyInjection)
Target frameworks: Same as Abstractions
**Rationale:**
- Depends only on Microsoft.Extensions.DependencyInjection.Abstractions (version 3.1.0 for broad compatibility)
- No WPF dependencies
- Enables DI integration in non-WPF contexts (e.g., background services)
## Central Package Management
All package versions are managed in `Directory.Packages.props`:
```xml
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<!-- Package versions defined here -->
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.242" />
<PackageVersion Include="System.Memory" Version="4.6.3" />
</ItemGroup>
</Project>
```
Individual projects reference packages without version attributes:
```xml
<PackageReference Include="Microsoft.Windows.CsWin32" />
```
**Benefits:**
- Single source of truth for package versions
- Prevents version conflicts across projects
- Simplifies dependency updates
## Conditional Compilation
### Framework Detection
```csharp
#if NET5_0_OR_GREATER
// Modern .NET APIs (Environment.OSVersion)
#else
// .NET Framework fallback (registry)
#endif
#if NET6_0_OR_GREATER
// DisposeAsync for CancellationTokenRegistration
#endif
#if NET8_0_OR_GREATER
// Latest .NET 8+ features
#endif
```
### Framework-Specific Dependencies
```xml
<!-- Only for .NET Framework 4.6.2 -->
<PackageReference Include="System.ValueTuple" Condition="'$(TargetFramework)' == 'net462'" />
<!-- Only for .NET Core/5+ (not .NET Framework 4.6.2) -->
<PackageReference Include="System.Drawing.Common" Condition="'$(TargetFramework)' != 'net462'" />
```
## PolySharp Integration
**Package:** PolySharp (build-time source generator)
Provides polyfills for newer C# features on older target frameworks:
- C# 11+ features on .NET 6/7/8
- C# 12+ features on older .NET versions
**Configuration:**
```xml
<ItemGroup>
<CompilerVisibleProperty Include="PolySharpExcludeGeneratedTypes" />
</ItemGroup>
<PropertyGroup>
<!-- Exclude specific polyfills if needed -->
<PolySharpExcludeGeneratedTypes>
System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute;
System.Diagnostics.CodeAnalysis.UnscopedRefAttribute
</PolySharpExcludeGeneratedTypes>
</PropertyGroup>
```
**Benefits:**
- Use modern C# syntax across all target frameworks
- Init-only properties on .NET Framework
- Required members support
- CallerArgumentExpression on older frameworks
## Language Version
Set to C# 14.0 across all projects:
```xml
<LangVersion>14.0</LangVersion>
```
> **Note:** `Wpf.Ui.csproj` overrides this to `<LangVersion>preview</LangVersion>` to enable C# preview features.
**Combined with PolySharp**, this enables:
- Latest C# language features
- Polyfills generated at compile-time for older frameworks
- No runtime dependencies
## Enforcement
### MUST Follow
1. **All package versions in `Directory.Packages.props` only** — Central Package Management is the single source of truth for NuGet versions
2. **Use `-windows` TFM suffix** for projects with WPF dependencies (e.g., `net10.0-windows`, not `net10.0`)
3. **Use `netstandard2.0`/`netstandard2.1`** for abstraction-only packages that have no WPF or Windows dependency
4. **Guard framework-specific code with `#if NET{X}_0_OR_GREATER` directives** — never use runtime version checks for compile-time API differences
5. **Use PolySharp for C# polyfills** — never hand-write polyfill classes for language features (e.g., `IsExternalInit`, `CallerArgumentExpression`)
6. **Set `LangVersion` in `Directory.Build.props`** — override in individual `.csproj` only when justified (currently only `Wpf.Ui.csproj` overrides to `preview`)
### MUST NOT Do
1. **Never add `Version` attribute to `PackageReference`** in `.csproj` files — all versions must be in `Directory.Packages.props`
2. **Never add a new TFM without updating all projects** that share the same TFM set — all projects in a TFM group must stay in sync
3. **Never use `#if` with specific patch versions** (e.g., `NET8_0_10`) — only use `_OR_GREATER` suffixed symbols
4. **Never remove a TFM from a shipping package** without a major version bump — removing a TFM is a breaking change for consumers on that framework
### Verification
- **CPM enforcement:** `<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>` in `Directory.Build.props` causes build errors if `Version` is specified in `.csproj`
- **TFM validation:** Build compiles all target frameworks on every `dotnet build` — missing APIs surface as compile errors immediately
- **PolySharp coverage:** PolySharp source generator runs at build time and provides polyfills automatically; manual polyfills would cause duplicate symbol errors
## Consequences
### Positive
- **Broad Compatibility:** Supports applications from .NET Framework 4.6.2 through .NET 10
- **Modern Development:** C# 14 preview features via PolySharp
- **Simplified Maintenance:** Central package management
- **Clear Upgrade Path:** Consumers can upgrade .NET version without changing library
- **AOT Ready:** Abstractions library supports AOT scenarios
### Negative
- **Increased Build Complexity:** Each commit builds 6+ framework variants
- **Larger Package Size:** Multi-target packages include assemblies for all frameworks
- **Conditional Compilation:** Requires `#if` directives for framework-specific code
- **Testing Burden:** Features should be tested on multiple framework versions
## Implementation Details
### Directory.Build.props
Central build properties defined once:
```xml
<PropertyGroup>
<Version>4.2.0</Version>
<LangVersion>14.0</LangVersion>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
```
### Conditional Property Groups
```xml
<PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
<DefineConstants>$(DefineConstants);NET8_0_OR_GREATER</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
<DefineConstants>$(DefineConstants);BELOW_NET8</DefineConstants>
</PropertyGroup>
```
## References
- [.NET Multi-Targeting Documentation](https://docs.microsoft.com/dotnet/standard/frameworks)
- [Central Package Management](https://docs.microsoft.com/nuget/consume-packages/central-package-management)
- [PolySharp GitHub](https://github.com/Sergio0694/PolySharp)
- [TFM Compatibility](https://docs.microsoft.com/dotnet/standard/frameworks#net-5-os-specific-tfms)