Skip to content

Migration to v5

Peter Gill edited this page Jun 7, 2026 · 1 revision

Migrating from Majorsilence Reporting (My-FyiReporting) version 4 to version 5 marks a significant shift from legacy .NET Framework dependencies to a modern, cross-platform architecture.

Architectural & Platform Changes

  • Target Framework Upgrade: The most foundational change is the move from .NET Framework (4.x) or early .NET Core to .NET 8.0 and newer.

  • Rendering Engine Options: Version 5 introduces SkiaSharp as an optional rendering backend alongside the legacy System.Drawing (GDI+) approach. Opting into SkiaSharp enables native, cross-platform rendering on Linux and macOS (recommended for containerized or non‑Windows hosts), while Windows workflows can continue using the default packages.

  • Linux Native Support: Unlike version 4, which often struggled with server-side rendering on non-Windows hosts, version 5 is fully optimized for containerized environments (like Docker) using SkiaSharp.

Dependency & Packaging Updates

  • Package Consolidation: New NuGet packages ending in .SkiaSharp (e.g., Majorsilence.Reporting.RdlEngine.SkiaSharp) replace the older version 4 libraries.
    • Linux/macOS (SkiaSharp, optional):
      • dotnet add package Majorsilence.Reporting.RdlCreator.SkiaSharp
      • dotnet add package Majorsilence.Reporting.RdlEngine.SkiaSharp
      • dotnet add package Majorsilence.Reporting.RdlCri.SkiaSharp
    • NuGet (Windows / default packages):
      • dotnet add package Majorsilence.Reporting.RdlCreator
      • dotnet add package Majorsilence.Reporting.RdlEngine
      • dotnet add package Majorsilence.Reporting.RdlCri
  • Dependency Cleanup: Removed many legacy dependencies that were tied to the older fyiReporting fork.

Feature & API Enhancements

  • Asynchronous Processing: Version 5 introduces widespread support for async/await patterns in report generation, improving performance in web-based applications.
  • Modern Database Providers: Enhanced support for modern versions of PostgreSQL and SQL Server, dropping support for older, EOL database drivers.
  • Improved Font Handling: Because SkiaSharp handles fonts differently than GDI+, version 5 requires explicit font installation (like ttf-mscorefonts-installer) on Linux to maintain visual parity with Windows-generated reports.

Component Availability

Component Version 4 Version 5
Engine GDI+ / Windows-centric SkiaSharp / Cross-platform
Designer Windows-only Windows-only (Requires .NET 8)
PDF Export Built-in SkiaSharp-based
Linux/macOS Limited/Experimental Fully Supported (Core Engine)

Breaking Changes

  1. Retarget projects to .NET 8.0 — v4-era .NET Framework/.NET Core targets are no longer supported.
  2. Package & namespace changes — many packages renamed to *.SkiaSharp or reorganized; update NuGet refs and using/import statements.
  3. Rendering backend differences — opting into SkiaSharp can change text measurement, layout, DPI and visual output vs GDI+; expect minor layout/spacing differences.
  4. Font handling and embedding — SkiaSharp requires explicit fonts on Linux/macOS and different embedding behavior; you must install system fonts (e.g., ttf-mscorefonts) and may need to adjust font fallbacks.
  5. API surface changes — several sync APIs were converted to async; callers may need async/await and signature changes.
  6. PDF and export behavior — PDF rendering now SkiaSharp-based; output, metrics, and embedded fonts can differ.
  7. Database drivers/providers updated — older, EOL providers dropped; connection strings or driver packages may need updates.
  8. Viewer/designer packaging — viewer and designer controls moved to separate packages and some platforms are now experimental; desktop integration code may require changes.
  9. Native runtime deps — SkiaSharp requires native libs on Linux/macOS (fontconfig, freetype, libpng, etc.); Docker images and hosts must include them.
  10. Threading/ownership semantics — SkiaSharp resources have stricter disposal and thread-affinity rules; update resource-management and concurrency patterns.
  11. Deprecated features/extensions — some legacy fyiReporting extensions and configuration keys were removed; verify custom extensions and config files.
  12. Build/CI changes — update build images/tooling to .NET 8 SDK and ensure native dependencies are installed for cross-platform CI.
  13. Root namespace changed to Majorsilence.Reporting

API surface changes

This section is meant to provide breaking changes examples

Root namespace changes

Majorsilence.Reporting change example

// version 4 namespace
fyiReporting.RdlViewer.RdlViewer rdlViewer1;

// version 5 namespace
Majorsilence.Reporting.RdlViewer.RdlViewer rdlViewer1;

API surface changes — several sync APIs were converted to async; callers may need async/await and signature changes.

mainly some methods are now async and some properties have been removed and replaced with an equivalent async method.

DataSet.SetData — v4 sync → v5 async

version 4

rdlView.Report.DataSets["Data"].SetData(dataTable);

version 5, async

var rpt = await rdlView.Report();
await rpt.DataSets["Data"].SetData(dataTable);

DataSet.SetSource — v4 sync → v5 async

version 4

rdlView.Report.DataSets["Data"].SetSource("SELECT id, name FROM products");

version 5, async

var rpt = await rdlView.Report();
rpt.DataSets["Data"].SetSource("SELECT id, name FROM products");
await rdlView.Rebuild();

Report Viewer Breaking changes (v4 -> v5)

  • Namespace/type renamed:
    • fyiReporting.RdlViewer.RdlViewer -> Majorsilence.Reporting.RdlViewer.RdlViewer
    • Update using directives and NuGet/package references.
  • Synchronous API removed -> asynchronous API:
    • SourceFile (property) -> SetSourceFile(Uri) async method (await required).
    • Report (property) -> Report() async method returning Task (await Report()).
    • Rebuild() -> async Rebuild() (await required).
  • Call-site changes required:
    • Make callers async (async methods, async Main, or block with .GetAwaiter().GetResult()).
    • Await SetSourceFile, await Report(), then access DataSets and SetData, then await Rebuild().
    • Update all call sites, tests, and any code that relied on the old synchronous behavior.

version 4

var dt = new System.Data.DataTable();
var rdlViewer1 = new fyiReporting.RdlViewer.RdlViewer();
string filepath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SampleApp2-TestReport.rdl");
rdlViewer1.SourceFile = new Uri(filepath);
rdlViewer1.Report.DataSets["Data"].SetData(dt);
rdlViewer1.Rebuild();

version 5, async

var dt = new System.Data.DataTable();
var rdlViewer1 = new Majorsilence.Reporting.RdlViewer.RdlViewer();
string filepath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SampleApp2-TestReport.rdl");
await rdlViewer1.SetSourceFile(new Uri(filepath));
await (await rdlViewer1.Report()).DataSets["Data"].SetData(dt);
await rdlViewer1.Rebuild();

Report Engine Export to PDF Breaking changes (v4 -> v5)

  • v5 made Parse(), RunGetData(...) and RunRender(...) asynchronous. You must await them and make the calling method async (propagate Task return or use async Task).

version 4

var reportSource = System.IO.File.ReadAllText(sourcefile.AbsolutePath);
var rdlp = new RDLParser(reportSource);
var rpt = rdlp.Parse();
rpt.RunGetData(null);
var sg = new Majorsilence.Reporting.Rdl.OneFileStreamGen(savePath, true);
rpt.RunRender(sg,  OutputPresentationType.PDF);

version 5, async

var reportSource = await System.IO.File.ReadAllTextAsync(sourcefile.AbsolutePath);
var rdlp = new RDLParser(reportSource);
var rpt = await rdlp.Parse();
await rpt.RunGetData(null);
var sg = new Majorsilence.Reporting.Rdl.OneFileStreamGen(savePath, true);
await rpt.RunRender(sg,  OutputPresentationType.PDF);

Clone this wiki locally