-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Problem Statement
H5 only supports .NET Standard 2.0 APIs for transpilation to JavaScript. To share DataProvider code with Dashboard.Web, we must downgrade DataProvider to use ONLY netstandard2.0 APIs when targeting that framework.
Current State
- DataProvider targets net9.0 with .NET 9.0 dependencies
- System.Text.Json 9.0, Npgsql 9.0, etc. require .NET 6.0+ APIs
- Generated code uses modern C# features and .NET APIs
Implementation Strategy: Partial Class File Separation
DO NOT litter code with `#if` conditionals! Instead, use partial classes with separate implementation files.
CORRECT Pattern:
Main code (common logic only, or minimal):
// DatabaseHelper.cs
public static partial class DatabaseHelper
{
// Common methods that work on all platforms
public static string ValidateConnection(string connStr) => !string.IsNullOrEmpty(connStr);
}NetStandard 2.0 implementation:
// DatabaseHelper.NetStandard2_0.cs
#if NETSTANDARD2_0
public static partial class DatabaseHelper
{
public static string SerializeData(object obj)
=> Newtonsoft.Json.JsonConvert.SerializeObject(obj);
public static T DeserializeData<T>(string json)
=> Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json);
}
#endifModern .NET implementation:
// DatabaseHelper.Modern.cs
#if !NETSTANDARD2_0
public static partial class DatabaseHelper
{
public static string SerializeData(object obj)
=> System.Text.Json.JsonSerializer.Serialize(obj);
public static T DeserializeData<T>(string json)
=> System.Text.Json.JsonSerializer.Deserialize<T>(json);
}
#endifKey Principle:
- Main code contains common logic that works on ALL platforms
- Platform-specific methods are implemented DIRECTLY in their respective partial files
- The
#ifensures only ONE implementation compiles per target framework - NO abstract/interface-style declarations - each partial file has COMPLETE method implementations
Required Changes
-
Multi-target Configuration
<TargetFrameworks>netstandard2.0;net8.0;net9.0</TargetFrameworks>
-
Conditional Dependencies
<PackageReference Include="System.Text.Json" Version="9.0.0" Condition="'$(TargetFramework)' != 'netstandard2.0'" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
-
Partial Class File Organization
- Main file: Common logic that works everywhere
- Platform files: Complete method implementations (NOT declarations)
ClassName.NetStandard2_0.cs- wrapped in#if NETSTANDARD2_0ClassName.Modern.cs- wrapped in#if !NETSTANDARD2_0
-
Generated Code Constraints
- Generated .g.cs files must ONLY use netstandard2.0 APIs
- No conditional compilation in generated code
- Use lowest common denominator APIs in templates
-
File Naming Convention
SomeClass.cs- Common logic (platform-agnostic)SomeClass.NetStandard2_0.cs- NetStandard 2.0 implementationSomeClass.Modern.cs- .NET 8/9 implementation
Files to Modify
Directory.Build.props- Multi-targeting configDataProvider/DataProvider/DataProvider.csprojLql/Lql/Lql.csprojSync/Sync/Sync.csproj- Split any files using .NET 6+ APIs into partial classes
- Update code generation templates
Success Criteria
- DataProvider builds for netstandard2.0, net8.0, net9.0
- Main code files contain ZERO
#ifconditionals - Platform-specific implementations in separate partial files
- Generated .g.cs code compiles in Dashboard.Web (H5/netstandard2.0)
- H5 can transpile generated records to JavaScript
- All tests pass on net8.0 and net9.0
Example File Structure
DataProvider/
├─ DatabaseEffects.cs # Common logic
├─ DatabaseEffects.NetStandard2_0.cs # NS2.0 methods (#if NETSTANDARD2_0)
└─ DatabaseEffects.Modern.cs # Modern methods (#if !NETSTANDARD2_0)
Mutually Exclusive With
- Path A (Issue [Decision Needed] Path A: Investigate upgrading H5 to support .NET Standard 2.1 APIs #22): Upgrade H5 to support netstandard2.1 APIs