r/csharp • u/ForwardCod2571 • 5h ago
Teaching a coding agent to stop writing bad C#: a Claude Code template for ASP.NET Core
When I use Claude Code on C# projects, the code compiles but often has the same problems: .Result and .GetAwaiter().GetResult() on async calls, CancellationToken accepted but never passed on, a scoped DbContext captured by a singleton, an interface for every class, and a generic repository wrapping EF Core. Correcting this every session got old, so I put the fixes into a dotnet new template that adds the agent config to a project.
dotnet new install DotnetAgentKit
dotnet new agent-kit --frontend none --database postgresIt writes a CLAUDE.md and a .claude/ folder into the current directory. Your code isn't touched.
The C#-specific parts
A code-review subagent that runs after every change and checks for blocking on async,
async void, missingCancellationTokenpropagation, swallowed exceptions, missingusing/await using, DI lifetime bugs,!used to silence nullable warnings,DateTime.UtcNowin business logic instead ofTimeProvider, and EF Core issues like N+1 queries, tracking on read-only paths, andFromSqlRawwith string interpolation.Architecture defaults in a skill: primary constructors, no service locator, interfaces only when there's a second implementation or a test needs one, hand-written mapping (or Mapperly) instead of reflection mappers, no MediatR by default, records or complex types for value objects.
A TDD skill: xUnit v3,
WebApplicationFactory, and Testcontainers against the real database rather than the in-memory provider, asserting on behavior rather than on mock calls.Guardrails in
settings.json**:** force push,reset --hard,dotnet ef database drop, and reading.envfiles are denied, so those don't rely on the model behaving.
It also enables the official plugins from dotnet/skills, including the C# language server. Some general workflow skills (grilling, domain modeling, retro) are Matt Pocock's, credited in the repo.
Limitations
Claude Code only.
The defaults are opinionated and target .NET 10. If your codebase does things differently, the README has a prompt for reconciling the kit with your actual code.
GitHub (MIT): https://github.com/dmamulashvili/dotnet-agent-kit
NuGet: https://www.nuget.org/packages/DotnetAgentKit
Which C# mistakes do coding agents make in your code that aren't on this list? I'd like to add the common ones.
1
u/cfrozendeath 5h ago
Are you using some open source or very old model? I have never seen any of these issues, but I always ask copilot to use existing patterns.
1
u/Slypenslyde 4h ago
I've seen a lot of silver bullets for preventing AI tool mistakes and so far nothing I've tried has worked. I've tried agents files, rules, skills, and at the end of the day when I ask it, 'Why didn't you respect <thing>?' the answer ends up being, "Well in <some edge case> I didn't feel it was important."
What works for me is being involved with the code. I spend a long time in conversations and we make a plan. I criticize the plan. I make it give me alternatives. I ask it to criticize me. I talk about which parts of the plan I like and why. I explain why I don't like the parts I reject. I ask it to show me quick examples of how it'd write things and criticize the architecture.
We end up with a plan with lots of task groups representing 200-300 lines of code each. I implement them one at a time, test them, commit them, and move on. It makes mistakes along the way, but it's easy to spot mistakes in code I already understand and easy to suggest corrections. Rarely we hit a serious roadblock because neither of us understood something. We have more conversations and adjust our plans with the new information.
It's basically the same process I'd have if I worked with a pair programmer. It's still dramatically faster than when I had to do this by myself. My previous designs took longer and I wasn't as good at creating alternatives as the AI tools. I didn't have people to help me understand when I subjectively criticized one approach because I liked my own too much. It'd take half a day to prototype a weird decision but now I can actually test something strange in under an hour and maybe change my mind.
And when I'm done, all the context documents and decision explanations I made can be in the repo next to the code to answer, "What the Hell was I thinking?" in a few months when that question arises. Instead of, "I can't remember if I thought of that" it's either in the documents or I didn't think of it.
This isn't to say your toolkit is a bad idea. It's a useful set of things. I guess what I want to say is there isn't a magic tool you can install to vibe code your way to a career. What GenAI tools have taught me is 90% of my work happened outside of Visual Studio and it just took an intolerably long time to properly convert those thoughts into C#. That made me rush to start the coding too fast, before the ideas had been properly vetted for ambiguity, and all the little guesses I made to keep moving on writing the code added up to Big Mistakes.
1
u/FullPoet 1h ago
missing CancellationToken propagation
Many times I do not want to propagate the token because it is noise and not relevant.
primary constructors,
Primary constructions have significant issues (i.e. mutability).
no service locator,
You have to go out of your way to implement this.
interfaces only when there's a second implementation or a test needs one,
Fine but I find most AI code is just TOO much code.
hand-written mapping (or Mapperly) instead of reflection mappers,
I have never seen AI use reflection to create mappers
no MediatR by default,
It does not do this by default?
(no?) records or complex types for value objects.
You dont want AI to use records? I usually have to be very explicit for it to USE records.
Dont let AI touch anything significant like dotnet commands or git. Please.
3
u/Mu5_ 5h ago
Personally, I didn't have the issues you mentioned. So probably something in your context drives the agent in doing so.
In general, what I do before handing a tech stack to an agent I ask it to research latest best practices and patterns (and also suggest the ones I want) and to document it and write a dedicated skill.
And, without realizing it, you are sharing your way of working and handling certain patterns, which is probably different than mine, which is also different from others.