r/dotnet • • 6h ago

Promotion LexiSharp 1.0.0 - A composable information retrieval toolkit for .NET

12 Upvotes

I've released LexiSharp 1.0.0, a composable information retrieval toolkit for .NET.

The goal is to make retrieval pipelines inspectable and comparable rather than treating search as a black box.

It brings together:

  • Inverted indexing and BM25 variants

  • Dense and sparse retrieval

  • Hybrid search with RRF

  • Reranking and query processing

  • PostgreSQL integrations

  • SearchTrace for understanding ranking decisions

It also includes an evaluation harness covering BEIR retrieval benchmarks and text classification experiments, with reproducible runs and regression checks.

MIT licensed, .NET 10.

GitHub: https://github.com/manuc66/LexiSharp

Docs and interactive demo: https://manuc66.github.io/LexiSharp/

Feedback from people working on search, IR or .NET is very welcome.

Full disclosure: LexiSharp was built with substantial AI assistance. I designed the project, guided the implementation and built the evaluation setup.


r/dotnet • • 7h ago

Promotion NetWasm.UI v0.10: NuGet/.NET Standard packages, prerendering, [Reactive] properties and a smaller runtime for C# WebAssembly UI

14 Upvotes

We've just released 0.10 of NetWasm.UI with a lot of improvements, some of them from feedback on my 0.5 post here. Thank you!

For anyone who missed it: NetWasm.UI is a UI framework for the browser built on NetWasm, which compiles C# ahead of time to WebAssembly. It works like Solid/Svelte rather than Blazor: components build their DOM once, and signals update exactly the nodes that changed. There's no reflection, and .nwui templates are compiled by a source generator.

What's new since 0.5:

  • NuGet and .NET Standard packages (0.10). With NetWasm 0.14, every project gets the framework built in (LINQ, System.Text.Json, HttpClient, regex, XML and more), and you can reference NuGet packages that target .NET Standard. No more special NetWasm.System.* packages. The demo app's Wasm also dropped from 92 to 88 KB Brotli.

  • [Reactive] properties (0.6). This was suggested in the comments last time (issue #1). You can now write a plain property instead of signal.Value:

[Reactive] public partial int Count { get; set; }

Button(OnClick(() => Count++), "+1")
Text(() => Count)

The source generator puts a Signal<int> behind it, and CountSignal gives you the signal itself if you need it. It works in C# classes and in .nwui code blocks. Explicit Signal<T> still works.

  • Prerendering (0.8). dotnet publish can render the first screen into the HTML, so visitors see content before the Wasm has loaded. It's opt-in with <NetWasmUIPrerender>true</NetWasmUIPrerender>. For now it's a snapshot and not hydration: links work right away, and the app takes over when it starts. Hydration is next.

  • Faster startup (0.7). Publish adds preload tags for the module chain and the Wasm. That removes about seven serial round-trips, and the Counter sample renders ~1.2 s sooner on a 150 ms RTT connection.

  • Smaller and faster runtime (0.9). Upgraded to NetWasm 0.13 with its new NetWasmGC collector. The demo app's Wasm went from 108 to 92 KB Brotli, and allocation-heavy work is up to 2× faster. Thanks to u/zionsati (the NetWasm author) for contributing the per-row optimizations.

  • C# 15 works if you have the .NET 11 SDK installed.

Numbers now (js-framework-benchmark-style runs; method and caveats are in the repo):

  • The whole demo app (router, forms, todos, nested components) is ~135 KB Brotli, Wasm + JS (was ~157 KB at 0.5).

  • It's level with or faster than React in every case, and 0.8–1.5× SolidJS's time.

  • Compared with Blazor WebAssembly (interpreter): 3–20× faster, ~18× smaller download, ~9× faster startup.

Live demo and docs: https://matengo.github.io/NetWasm.UI/ (the site is built with NetWasm.UI and now prerendered)

Try it:

dotnet new install NwUi.Templates
dotnet new netwasm-ui -o MyApp
cd MyApp
dotnet nwui-dev

To upgrade an existing app, set "NetWasm.Sdk": "0.14.2" in global.json and remove any NetWasm.System.* package references. The CHANGELOG lists the rest.

Limitations:

  • No reflection, by design: NetWasm compiles a closed world, which is part of why the output is so small. .NET Standard packages build, but code that finds members at run time (Newtonsoft.Json, reflection-based DI) throws when it runs. System.Text.Json works with source-generated contexts.

  • Hot reload (today it's live reload, ~3 s, and it keeps state)

  • It's 0.x, so the API can change. Breaking changes are listed in the CHANGELOG.

On the roadmap:

  • Hydration (prerendered pages are replaced, not reused yet)

  • IntelliSense in .nwui files (the VS Code extension only does syntax highlighting so far)

  • Exploring typed C# web workers: call a worker like a normal C# class and bind its result to a Signal<T>.

Repo: matengo/NetWasm.UI: UI framework for NetWasm

What would you need before trying it on a real project, and what would you like to see after hydration? :)


r/dotnet • • 4h ago

Promotion KillerPdf.Engine 1.9.3: a from-scratch PDF 2.0 engine for .NET 10 now reads EPUB and DjVu, does ICC color management and printer proofing, and is fully managed

5 Upvotes

A while back I posted about KillerPdf.Engine, the PDF engine I built from scratch for KillerPDF, my Windows PDF editor. It's grown a lot since then, so here's an update.

The short version is that it's an independent .NET 10 library with no PDFium, no native PDF dependency and no wrapped C++. It reads, renders, extracts text, searches, edits, redacts, fills forms (XFA included), signs and validates timestamps, encrypts with passwords or certificates, runs OCR, exports to Office, HTML, Markdown and JSON, optimizes, preflights, imposes, measures and compares. The desktop app runs entirely on it, and PDFium, Docnet.Core and PdfPig are all gone from KillerPDF as of 1.9.

New since I last posted

  • Native EPUB and DjVu. EpubDocument, DjvuDocument, and PdfReadSnapshot.OpenEpub / OpenDjvu give you metadata, text, outlines, links and page rendering, plus explicit conversion to PDF. Both are still marked in development.

  • ICC color management and printer proofing. That covers all four rendering intents, black-point compensation, paper and black simulation, and gamut checks. Untagged CMYK goes through a working CMYK profile.

  • Float32 rendering that keeps source precision through transparency groups, blending, gradients and images.

  • A new anti-aliasing rasterizer for paths and text.

  • Image placement editing that preserves shared resources, and keeps the original JPEG bytes where it can.

  • Encryption you can carry through an edit. Edit a protected document as plain bytes and still keep its passwords, recipients, permissions and /ID.

Numbers

514 source files, about 167,000 lines of C#, 13,052 tests on Windows and Linux, and a 47,024-file corpus run before every release, covering real-world, standards, malformed and deliberately hostile PDFs.

dotnet add package KillerPdf.Engine

It's GPL-3.0, so check that against your project before you pull it in.

Repo and docs: https://github.com/SteveTheKiller/KillerPDF/tree/main/engine

I'm happy to answer questions about the parser, the renderer, or what PDF 2.0 is actually like to implement. Short answer: the spec is long, and real-world files ignore most of it, lol.


r/dotnet • • 3h ago

C#'s rules for top-level statements turned out to be a great fit for a reactive notebook, so I built one

2 Upvotes

r/dotnet • • 2h ago

Promotion AbraxasDB - A .NET native local object storage engine for data

Thumbnail reddit.com
1 Upvotes

r/dotnet • • 1d ago

Promotion GitHub - io7/FreePDF: MIT-licensed continuation of PDFsharp and MigraDoc for .NET

Thumbnail
github.com
85 Upvotes

r/dotnet • • 1d ago

zip ExtractToFile change in .Net 11

52 Upvotes

Not a question, more like a report, maybe useful for some, maybe some have feedback.

From what I can tell it is an undocumented breaking change in .Net 11, that happens under what is probably rare conditions.

Background

I have a windows service running under LocalService account, and a subfolder in CommonApplicationData with added permission FullControl for LocalService.

A client application also needs full access to some files in this folder, so I added permission FullControl for AuthenticatedUserSid as well.

Permissions is set with Wix installer on the CommonApplicationData subfolder (and inherited by files inside the folder).

Operations

The service syncs data via cloud service, it does so by zipping files and upload to cloud. When restoring it downloads from cloud and unzips.

Zip/unzip is done with ZipFile class and CreateEntryFromFile/ExtractToFile zip extensions.

The zip file itself is placed in same folder, service creates it with ZipFile.Open(create) or File.Create and transfer data stream to/from cloud.

Problem

This has worked fine until I upgraded to .Net 11, now I find that ExtractToFile sets ACL for only LocalService for each extracted file, and no inherited permissions. The zip file itself that service also creates still has all inherited folder permissions.

Even administrator can't access the extracted files, but can extract the zip manually, thus replacing these files (take ownership) and inherited permissions are then restored also.

Cause

I looked into the source code for ExtractToFile zip extension and there is a change, until .Net 10 the extraction happened in-place directly to the destination file, while in .Net 11 if file is to be overwritten the extraction goes to temporary file in temporary folder (GetTempFileName), then moved to destination. According to my research this changes how ACL is applied, extraction in-place adds inherited ACL, while extraction in temp folder followed by File.Move does not. I understand the reason for the change is to only replace file if extraction succeeds.

Solution

I found two different ways to solve this by adding code to service that update ACL for each file after extract:

  • Add explicit ACL (GetAccessControl, add rules, SetAccessControl).

  • Restore ACL inheritance (GetAccessControl, SetAccessRuleProtection(false), SetAccessControl).


r/dotnet • • 1d ago

Promotion Summary of Uno Platform announcements at .NET Conf

61 Upvotes

A brief summary of Uno Platform announcements during .NET Conf

Uno Platform:

  • .NET 11 support

  • 2x faster, 5x smaller, with core ops up to 38x faster

  • Unified rendering: SkiaSharp 4 (default) + new WebGPU backend

  • 100s of new UI controls from MAUI ecosystem - on all targets

  • Extending .NET MAUI to Web/Linux

  • Build cross-platform UIs in pure C# with Microsoft.UI.Reactor

  • Apple TV support (to accompany mobile, desktop, web, android TV, watches etc)

  • New RichTextBlock & RichEditBox - now x-plat!!

  • Deeper WinUI coverage

Uno Platform Studio

  • Desktop application for Windows/Mac/Linux, to accompany Browser

  • Companion mobile app for iOS and Android

  • Theme Builder

Full release notes

Uno Platform 7.0: 2x faster, 5x smaller, built for the agentic era


r/dotnet • • 1d ago

Question .NET 11 and RISC-V

24 Upvotes

Did RISC-V support actually make it into .NET 11? I know it was present in one of the previews, but I haven't seen any mention of it at dotnet-conf or in any articles.


r/dotnet • • 3h ago

Promotion Wrote an agent skill so AI coding tools stop hallucinating API's for my WPF UIKIT.

0 Upvotes

I have been building and maintaining UI-Framework a small declarative C# framework and WPF on .NET 10 (MIT). The project was based on my love for swiftui.

Full Disclosure i did use ai tools to help me build it.

After my first initial releases i attempted to use my lib with other tools and it quickly became annoying. The frustration came in when using tools like Claude code or Cursor with a small niche lib, the ais quickly started spitting out code that looked right but either the API's didn't exist or for example they kept treating VStack/Hstack like css flexbox. Creating state<T> inside a Body leading to so any change would then cause a rebuild leaving stable keys off list rows and making up methods that did not exist.

This led me to write an agent skill that exposes the real contract (skills/ui-framework/SKILL.md, install steps in docs/agent-skill.md):

  • VStack/HStack size to their content. They aren't flexbox.

  • Keep State<T> out of Body().

  • Give list rows stable .Id() keys so identity survives updates and reorders.

  • Check signatures against the installed package version instead of guessing.

Repo: https://github.com/signalnotnoise/ui-framework Install: dotnet add package SignalNotNoise.UI.Wpf --vesion 1.0

For those maintaining lib, are you utilizing this method.


r/dotnet • • 14h ago

Sharphy: An open-source MCP server giving AI agents (Cursor/Claude) deep .NET CLR memory forensics & CIL decompilation

0 Upvotes

Hey r/dotnet! 👋

Most AI coding assistants (Cursor, Claude Code, Windsurf) are great at writing code, but when it comes to investigating post-mortem crash dumps, unravelling thread deadlocks, or inspecting compiled .NET assemblies, they hit a wall. An LLM agent can't open WinDbg, run !dumpheap, or launch dnSpy.

To solve this, we created Sharphy: an open-source, native Model Context Protocol (MCP) server that transforms AI coding agents into deep .NET runtime diagnosticians, memory forensic analysts, and binary architects.

🔍 What Sharphy lets your AI Agent do directly in chat:

  1. Analyze Crash Dumps (.dmp): Heuristic analysis via Microsoft.Diagnostics.Runtime (ClrMD) to detect ThreadPool starvation, sync-over-async blocking, and high-memory retainers.

  2. Deadlock Detection (Wait-For Graph): Analyzes thread monitor contention and maps circular wait cycles with exact source line attribution.

  3. Decompile CIL into Clean C#: Embedded ILSpy engine decompiles methods on the fly into idiomatic modern C# without touching GUI tools.

  4. Unified CIL Bytecode Diffing: Compares two assembly versions at the ECMA-335 metadata level and outputs unified line-by-line CIL instruction diffs (--- Baseline vs +++ Updated).

  5. Zero-Touch IL Patching: Allows the AI agent to surgically patch opcodes (e.g. replacing validation with NOP/Ret/Ldnull) inside collectible AssemblyLoadContext without locking files on disk.

⚡ Quick Start (Cursor / Claude Code):

Add this to your MCP configuration (~/.cursor/mcp.json or claude_desktop_config.json):

{
  "mcpServers": {
    "sharphy": {
      "command": "dnx",
      "args": ["Sharphy.Cli", "mcp", "start"]
    }
  }
}

Or install as a global CLI tool:

dotnet tool install -g Sharphy.Cli
sharphy mcp start

📊 Performance & Invariants:

  • Multi-targeting across .NET 8.0, .NET 9.0, and .NET 10.0.

  • P99 MCP Latency: < 70ms under concurrency.

  • Zero-leak collectible AssemblyLoadContext (isCollectible: true).

  • Validated against 1,000 req/sec extreme tsunami flood stress.

(Links to GitHub, NuGet, and Documentation are in the first comment below!)

Feedback, PRs, and discussion are very welcome!


r/dotnet • • 1d ago

What's the most exciting thing from .NET Conf 2026 for you?

46 Upvotes

It looks like all the videos have already been uploaded to the .NET Conf 2026 playlist.

Which new feature are you most excited about and looking forward to using? It could be a language feature, a runtime improvement, a new library, or something else.

The obvious candidates are union types, runtime async, and perhaps JIT improvements. But maybe you've found something less obvious that caught your attention, such as Microsoft.Extensions.AI, MCP, or something else?


r/dotnet • • 1d ago

Promotion TenantGuard 1.0: finding tenant isolation mistakes in EF Core

3 Upvotes

Hey everyone! Wanted to share something that I've been working on the side. I've released TenantGuard 1.0.0, an open-source set of packages for EF Core 10 and 11, licensed under Apache-2.0.

It adds checks around applications that use query filters for tenant isolation. Those filters handle query scoping, but a new entity can be missing its filter, a query can bypass one, and tracked writes need their own tenant checks.

For example, if another tenant's entity gets attached to the context, the query filter alone won't prevent an update or delete through SaveChanges.

TenantGuard checks for these problems in a few places:

  • At build time, Roslyn analyzers (TG001–TG005) flag filter bypasses without a stated reason, including IgnoreQueryFilters() and ABP's IDataFilter.Disable<IMultiTenant>(). They also check raw SQL through EF Core, Dapper and ADO.NET for missing tenant-column comparisons.

  • At startup, 14 model rules check for missing filters, filters that accidentally hold a fixed tenant value, missing tenant indexes, and unique indexes that span tenants.

  • During SaveChanges, the write guard checks tracked inserts, updates and deletes against the current tenant. It also rejects tenant reassignment. Version 1.0 adds checks for owned entities through their owner, including changes such as order.Shipping.Street.

  • In tests, the isolation probe seeds a row per tenant and checks reads, Find, updates, deletes and Include. Each check appears as a separate xUnit v3 or TUnit test.

Here's the configuration for the write guard and startup validation:

builder.Services.AddDbContext<AppDbContext>(options => options
    .UseSqlServer(connectionString)
    .UseTenantGuard(tg => tg.CurrentTenant(ctx => ((AppDbContext)ctx).TenantId)));

builder.Services.AddTenantGuardStartupValidation<AppDbContext>();

It works with custom query filters and reads Finbuckle.MultiTenant's IsMultiTenant() configuration without extra setup. The dotnet tenantguard validate command can also check the model in CI without a database.

GitHub · Docs

If you try it against an existing model, I'd appreciate examples of false positives or tenant isolation problems the checks miss.

I've released TenantGuard 1.0.0, an open-source set of packages for EF Core 10 and 11, licensed under Apache-2.0.

It adds checks around applications that use query filters for tenant isolation. Those filters handle query scoping, but a new entity can be missing its filter, a query can bypass one, and tracked writes need their own tenant checks.

For example, if another tenant's entity gets attached to the context, the query filter alone won't prevent an update or delete through SaveChanges.

TenantGuard checks for these problems in a few places:

  • At build time, Roslyn analyzers (TG001–TG005) flag filter bypasses without a stated reason, including IgnoreQueryFilters() and ABP's IDataFilter.Disable<IMultiTenant>(). They also check raw SQL through EF Core, Dapper and ADO.NET for missing tenant-column comparisons.

  • At startup, 14 model rules check for missing filters, filters that accidentally hold a fixed tenant value, missing tenant indexes, and unique indexes that span tenants.

  • During SaveChanges, the write guard checks tracked inserts, updates and deletes against the current tenant. It also rejects tenant reassignment. Version 1.0 adds checks for owned entities through their owner, including changes such as order.Shipping.Street.

  • In tests, the isolation probe seeds a row per tenant and checks reads, Find, updates, deletes and Include. Each check appears as a separate xUnit v3 or TUnit test.

Here's the configuration for the write guard and startup validation:

builder.Services.AddDbContext<AppDbContext>(options => options
    .UseSqlServer(connectionString)
    .UseTenantGuard(tg => tg.CurrentTenant(ctx => ((AppDbContext)ctx).TenantId)));

builder.Services.AddTenantGuardStartupValidation<AppDbContext>();

It works with custom query filters and reads Finbuckle.MultiTenant's IsMultiTenant() configuration without extra setup. The dotnet tenantguard validate command can also check the model in CI without a database.

GitHub · Docs

If you try it against an existing model, I'd appreciate examples of false positives or tenant isolation problems the checks miss. Open to any critical feedback that could help improve it!


r/dotnet • • 15h ago

Show Reddit: Sharphy – Giving AI Coding Agents (Cursor/Claude) deep .NET CLR Memory Forensics & CIL Decompilation via MCP

0 Upvotes

Hey r/dotnet! 👋

Most AI coding assistants (Cursor, Claude Code, Windsurf) are great at writing code, but when it comes to investigating post-mortem crash dumps, unravelling thread deadlocks, or inspecting compiled .NET assemblies, they hit a wall. An LLM agent can't open WinDbg, run !dumpheap, or launch dnSpy.

To solve this, we created Sharphy: an open-source, native Model Context Protocol (MCP) server that transforms AI coding agents into deep .NET runtime diagnosticians, memory forensic analysts, and binary architects.

🔍 What Sharphy lets your AI Agent do directly in chat:

  1. Analyze Crash Dumps (.dmp): Heuristic analysis via Microsoft.Diagnostics.Runtime (ClrMD) to detect ThreadPool starvation, sync-over-async blocking, and high-memory retainers.

  2. Deadlock Detection (Wait-For Graph): Analyzes thread monitor contention and maps circular wait cycles with exact source line attribution.

  3. Decompile CIL into Clean C#: Embedded ILSpy engine decompiles methods on the fly into idiomatic modern C# without touching GUI tools.

  4. Unified CIL Bytecode Diffing: Compares two assembly versions at the ECMA-335 metadata level and outputs unified line-by-line CIL instruction diffs (--- Baseline vs +++ Updated).

  5. Zero-Touch IL Patching: Allows the AI agent to surgically patch opcodes (e.g. replacing validation with NOP/Ret/Ldnull) inside collectible AssemblyLoadContext without locking files on disk.

⚡ Quick Start (Cursor / Claude Code):

Add this to your MCP configuration (~/.cursor/mcp.json or claude_desktop_config.json):

{
  "mcpServers": {
    "sharphy": {
      "command": "dnx",
      "args": ["Sharphy.Cli", "mcp", "start"]
    }
  }
}

Or install as a global CLI tool:

dotnet tool install -g Sharphy.Cli
sharphy mcp start

📊 Performance & Invariants:

Feedback, PRs, and discussion are very welcome!


r/dotnet • • 23h ago

Promotion From a PS3 club notebook to a C#/WPF management app

Post image
1 Upvotes

I run two gaming clubs in Azerbaijan and build Time Control, a Windows app for managing PC and PlayStation sessions. In 2016, this was five TVs, a few PS3s and a notebook for times and payments. I tried existing software before starting my own. The screenshot shows the PC dashboard as it looks now.

The stack is C#, WPF, .NET 10 and SQLite. There's an admin app, a separate agent on each PC, and shared libraries for session data, payments and device control. Staff can start, extend, pause and move sessions, take payments and add shop orders. The PC agent handles locking and unlocking; compatible smart plugs handle TV power on the PlayStation side.

Most of the tricky work has been keeping the session and payment state consistent. A customer can pay for an hour and still owe money for an extension, so charges and payments are separate rather than one IsPaid flag. Money uses decimal. Sales, stock changes, receipts and related session changes go into one SQLite transaction. If that commits but the UI refresh fails, the sale still happened. Reporting it as a failed sale could make staff retry it and charge twice. Background autosaves also need a revision check so an old snapshot can't overwrite a newer sale.

Then there's the remote PC. The protocol carries session IDs, revisions and running/paused/disconnected states. Getting a ping back doesn't tell you which session is actually running. I'd be interested in how other desktop developers test this sort of recovery, especially when the DB commit succeeds but the UI or agent connection fails right afterwards.


r/dotnet • • 1d ago

Kumiko: an Elm-inspired UI framework for C# that coding agents can test themselves

13 Upvotes

I've wanted to build this for years, but a native UI framework for every platform was never going to fit around a day job. Then LLMs got good enough that I could finally do it.

Kumiko is the Elm architecture in plain C#: immutable records for state, messages, a pure Update and typed views. It turns out that's also a great fit for coding agents, because there's no hidden state and no surprises. Roslyn analyzers make sure you don't mutate state where you shouldn't. It renders natively with AppKit/Metal, Win32/D3D11, GTK and UIKit, with no browser and no Electron.

The "agent optimized" part: every app can render offscreen to a PNG plus a semantic tree. The agent changes something, takes a snapshot, looks at it and fixes what's wrong, without ever opening a window.

The repo has a small CRM, a Git client, a 120Hz diff viewer and a few iOS apps.

Heads up: I've only really been testing on my Mac so far, iOS is still rough - but fun to hack around. NativeAOT also builds really small iOS apps!

I'd love to hear what you think!

https://github.com/atresnjo/kumiko


r/dotnet • • 1d ago

Does .NET have anything like Timefold Solver / OptaPlanner?

2 Upvotes

Timefold Solver (the OptaPlanner successor) is the standard choice on the JVM for

rostering, routing and scheduling: you annotate your domain model, write

constraints declaratively, and it runs construction heuristics + local search

for you.

For .NET I only know Google OR-Tools (CP-SAT, routing), which is a solver rather

than a planning framework, and NuGet has no `timefold` or `optaplanner` package

at all.

So: does a .NET-native equivalent exist right now? Or is everyone using OR-Tools

directly, calling a Java/Python solver over REST, or writing their own heuristics?

Mostly interested in what people actually run in production.


r/dotnet • • 1d ago

Promotion Cake v7.0.0 released - .NET 11 & C# 15, unified DI across runners, container publishing, and more

Thumbnail reddit.com
3 Upvotes

Version 7.0.0 of Cake was release earlier this week

With same day support for

- .NET 11

- C# 15

And

- DSL improvements

- GitHub Azure OIDC

- Container publishing

- bug fixes and more.

Full release blog:

cakebuild.net/blog/2026/11/cake-v7.0.0-released

Was also shown at .NET Conf:

www.youtube.com/live/TF6qzdKwl84?t=11380&si=QfdIDnBCg8WRQQZS


r/dotnet • • 2d ago

Parquet.NET is now private?

Thumbnail
nuget.org
93 Upvotes

A few days ago I've noticed that the Parquet.NET GitHub repo is private. I think this is a recent change, because in Google search I still see a cached description, and there are forks of the latest 6.1.0 version. Anyone knows anything about it?


r/dotnet • • 1d ago

Where do you keep tests in a modular monolith architecture?

9 Upvotes

Which option you prefer?

A) - module's tests in a module folder, cross cutting tests in `repo/tests`/

repo/
    src/
        Apis/
        BuildingBlocks/
        Modules/
            Billing/
                Invoices/
                    Example.Invoices/
                        Example.Invoices.csproj
                    Example.Invoices.Contracts/
                        Example.Invoices.Contracts.csproj
                    Example.Invoices.Tests/
                        Example.Invoices.Tests.csproj
        Workers/
    tests/
        Architecture.Tests/
        Integration.Tests/

B - all tests in `repo/tests`

repo/
    src/
        Apis/
        BuildingBlocks/
        Modules/
            Billing/
                Invoices/
                    Example.Invoices/
                        Example.Invoices.csproj
                    Example.Invoices.Contracts/
                        Example.Invoices.Contracts.csproj
        Workers/
    tests/
        Modules/
            Billing/
                Example.Invoices.Tests/
                    Example.Invoices.Tests.csproj
        Architecture.Tests/
        Integration.Tests/

C - all tests in `repo/src`

repo/
    src/
        Apis/
        BuildingBlocks/
        Modules/
            Billing/
                Invoices/
                    Example.Invoices/
                        Example.Invoices.csproj
                    Example.Invoices.Contracts/
                        Example.Invoices.Contracts.csproj
                    Example.Invoices.Tests/
                        Example.Invoices.Tests.csproj
        Tests/
            Architecture.Tests/
            Integration.Tests/
        Workers/

r/dotnet • • 1d ago

I built a modular WinUI 3 template where features are hot-swapped from the server while the app runs. Fork it for your own projects

Thumbnail
github.com
4 Upvotes

Hey everyone,

I’ve been working on a side project for a while and it’s finally at a point where I’m not embarrassed to show it. It’s called Golden Hive, a modular framework for WinUI 3 desktop apps on .NET 10.

The idea in short: the desktop app is just a shell. Features (documents, reports, user management…) are modules the app downloads from the server after you sign in. Each module is a WinUI part plus its own ASP.NET Core backend in a Docker container. Ship a new version of a module and the server rolls it out in stages (pilot users first). The running app then swaps it in without a restart.

What’s in there right now:

  • Runtime modules. Each one runs in its own AssemblyLoadContext, packages are signed, and modules can depend on each other.

  • Hot-swap. Running commands get drained or cancelled, the module is replaced, your open views come back.

  • Navigation wheel. Hold Ctrl+Tab and a radial wheel pops up. One ring holds your modules, the other your open views. Tab or the arrow keys move around, and you release Ctrl to jump there. It’s like Alt+Tab, but for the app itself, and once you’re used to it you barely touch the sidebar anymore.

  • Workflows you build inside the app. Forms, approvals and module steps, triggered by events, schedules or commands. The reference example: an invoice gets submitted, gets pre-checked, and lands in an approver’s inbox.

  • An AI agent that can run those workflows, with guardrails. There’s a kill switch, confidence thresholds and daily limits. Critical steps always need a human, and every decision is logged. It also works fully offline with a rules-based provider, no API key needed.

  • Impact analysis on module updates. Rename a workflow step and the server checks every workflow that uses it. It auto-migrates them if you declared the rename, flags them for review if needed, or holds the rollout if something would break. This is honestly my favorite part.

  • The usual desktop stuff: docking and floating windows that remember their monitor, a command palette (Ctrl+Shift+P), live notifications, English/German.

  • Backend: 12 services in Docker Compose plus Postgres with a demo company already filled in. docker compose up, sign in as admin, and you can click around.

Under the hood it’s pretty functional-programming heavy (Result/Validation types all the way down instead of exceptions), if that’s your thing.

Use it as a template: the whole thing is meant as a starting point for your own projects. Fork it, delete the demo modules, add your own. The README has a step-by-step guide for building a module (backend + WinUI client + workflow integration), and the architecture is all there: auth, permissions, module delivery, rollouts, notifications, workflows, Docker setup.

It’s not battle-tested in production yet. The backend has end-to-end tests, the WinUI side is still young. If you build on it, I’d love to hear what breaks. That’s exactly the feedback I need to get it there.

Repo: https://github.com/zenoxart/GoldenHiveFramework
License: Apache 2.0


r/dotnet • • 1d ago

Promotion Built a lock free, thread-safe, token bucket rate limiter for .NET

9 Upvotes

Spent the past few days building a token bucket rate limiter and wanted to share it, mostly because I learned more doing this than most tutorials have taught me in a while.

The short version: it’s a token bucket, capacity + regen rate, standard stuff. The part I actually care about is that it’s thread-safe with zero locks. Every state change builds a new immutable snapshot and publishes it with Interlocked.CompareExchange, retrying if another thread beat it to the swap.

A few decisions:

  • Tokens/Capacity are int on the public API, but tracked as decimal internally. Didn’t want to expose fractional tokens (a token is one unit of work, doesn’t make sense to split one), but Regen needed to support fractional rates, and the internal math needed the precision.

  • There's a plain bool overload, and a Result enum overload (Authorized, Insufficient, ExceedsCapacity, Disabled, NeverRefills) so callers can tell “wait and retry” apart from “this will never succeed” Each method comes with a retryTime (overloads without).

  • Takes a TimeProvider so tests don’t have to sleep real seconds.

Repo’s here. README’s got the full API and an explanation of the design if you want the details.


r/dotnet • • 2d ago

Promotion C# 15 "unsafe" code: interactive tutorial + WebAssembly online playground

Post image
12 Upvotes

C# 15 brings some interesting changes to "unsafe" code, so we thought it would be useful to create a hands-on tutorial that starts with the basics AND also serves as an interacrive online playground.

It runs entirely in the browser: you edit the C# 15 code, compile it to WebAssembly and see the result immediately, without installation. (A desktop/laptop is recommended for the split-view experience)

Here's the link: https://xaml.io/s/Samples/UnsafeCodeTutorial?autorun=true&file=StartHere.cs

The tutorial has 10 short lessons, convering pointers, memory access, why unsafe code an be useful, safer alternatives like "Span<T>", and the new memory-safe rules.

Hope some of you find it useful.


r/dotnet • • 1d ago

Promotion NitroLite v1.2.0 - open-source NitroSense alternative in C#/WPF: reverse-engineering Acer's local services, 1089 tests

3 Upvotes

Weekend promotion post, as per the rules.

NitroLite is a MIT-licensed replacement for Acer's NitroSense on their Nitro gaming laptops. I wrote it because NitroSense was heavier than the job it does, and I wanted fan control that behaved.

What's technically interesting:

- Talks to AcerAgentService (localhost:46933) and Acer Care Center's local websocket using the same protocol the official client uses — command packets, capability queries, the works

- WPF UI that renders only the controls the service says the hardware supports (queried at startup, not hardcoded per model)

- A software fan-curve engine with hysteresis and minimum dwell time to stop fan hunting

- 1089 tests covering protocol packets, Eco/game transitions, crash recovery and concurrency

Repo: https://github.com/canerztk8/NitroLite

Runs as a single-file self-contained exe (.NET embedded), ~74 MB working set in the tray. If you have an Acer Nitro and want to test on a different model than my AN16-41, feedback via GitHub issues would help a lot.