Maintained by Halil İbrahim Sayın — 7+ years building .NET production systems in regulated industries. Issues and PRs welcome.
Production-tested Claude Code patterns, skills, and playbooks for enterprise .NET developers.
- Why Claude Code for .NET
- Quick Start
- Skills
- Playbooks
- CLAUDE.md Examples
- Production Patterns
- Common Pitfalls
- Contributing
Placeholder — content coming soon.
- Claude Code CLI v2.1.154 or later
- .NET SDK 8.0 or later
claude --version
dotnet --versionThis is not a project you clone and run. It is a collection of assets — skills, playbooks, and CLAUDE.md templates — that you copy into your own .NET solution. Each skill lives in skills/<skill-name>/SKILL.md and is drop-in compatible with Claude Code's standard .claude/skills/ directory layout. Pick what you need, copy it, and commit it to your own repo.
Paste this at the root of your .NET solution and adjust to match your project:
# Project
## Layout
src/ # Production projects
tests/ # Unit and integration test projects
.claude/ # Claude Code skills and configuration
## Model preference
- Daily work: sonnet
- Architecture decisions and large refactors: opus
## Rules
- Never add static Log.Logger calls — use injected ILogger<T> for application
logs and IAuditLogger for audit events. See skills/serilog-graylog-setup.
## Skills
Skills available in .claude/skills/ — Claude auto-invokes when triggers match. Run `/skills` to verify.
## Evolving this file
Add a rule here whenever a pattern gets settled; remove rules that no longer apply.- Create the
.claude/skillsdirectory in your solution root. - Copy the
serilog-graylog-setupskill from this repo into it. - Verify Claude Code sees it: run
claude, then/skills— confirm the skill appears in the listing.
mkdir -p .claude/skills
curl -L https://github.com/sayinbrahim/claude-code-for-dotnet/raw/main/skills/serilog-graylog-setup/SKILL.md \
--create-dirs -o .claude/skills/serilog-graylog-setup/SKILL.mdLeave sayinbrahim as a literal placeholder — replace it with your GitHub username or org.
After installing the skill, run these in Claude Code against your own .NET solution:
Audit every ILogger<T> usage in this solution and flag which calls should be application logs vs. audit events.Add the two-stage Serilog bootstrap pattern to Program.cs so startup errors are captured before the host is built.Generate a CorrelationIdMiddleware that reads X-Correlation-Id from the request, sets it on the response, and enriches the Serilog context.Update appsettings.json to route logs to Graylog UDP, wrap the sink in an async wrapper, and set minimum levels per namespace.Write xUnit tests that verify the audit logger writes exclusively to the audit facility and never leaks entries into the application log.
Reusable
/skilldefinitions you can drop into your.claude/folder.
| Skill | Description | File |
|---|---|---|
| serilog-graylog-setup | Centralized Serilog + Graylog (GELF) setup with strict audit/application log separation via two independent ILogger instances. | skills/serilog-graylog-setup/SKILL.md |
| ef-core-migration-review | Pre-merge safety review for EF Core migrations: catches destructive renames, missing defaults, blocking index creation, and data migrations mixed into schema changes. | skills/ef-core-migration-review/SKILL.md |
See skills/ for all skill files and usage notes.
Step-by-step workflows for common .NET engineering scenarios.
| Playbook | Scenario |
|---|---|
| legacy-net6-to-net8-migration | Migrating a production ASP.NET Core 3.1 + EF Core solution to .NET 8 LTS without data-shape regressions |
See playbooks/ for full playbook files.
Ready-to-adapt
CLAUDE.mdtemplates for real .NET project archetypes.
| Template | Project Type |
|---|---|
| enterprise-aspnet-core | ASP.NET Core 8+ Web API with EF Core, Serilog/Graylog, and xUnit |
See claude-md-examples/ for all templates.
Patterns that don't rise to skill or playbook scope but recur across every Claude Code session against a .NET codebase.
A .NET solution with 20+ projects exceeds Claude's working window if loaded wholesale. Reference files by path with @ only when their content is actually needed for the task. For ambient context — naming conventions, layering rules — push that into CLAUDE.md once instead of into every session.
EF Core migration snapshots, OpenAPI clients, gRPC stubs, and Designer.cs files are regenerated by tooling. Claude editing them produces drift that the next generation overwrites. Add an explicit rule in CLAUDE.md: "Never edit files matching *ModelSnapshot.cs, *.Designer.cs, or generated client folders — regenerate them via their tool instead."
A Claude session that drifts from "add audit logging" to "also refactor this controller" to "while we're here, fix this test" accumulates context noise that degrades output quality. End the session, commit, start fresh. The context window is a budget, not a memory.
Solution-wide rules (layout, naming, async discipline) live in the root CLAUDE.md. Project-specific rules (this Web API exposes Problem+JSON; this Worker Service uses Hangfire) live in src/<ProjectName>/CLAUDE.md. Claude reads both; the project file overrides the root when they conflict.
Treat a Claude-authored PR like a PR from a competent but new team member. Three questions resolve most reviews: Does the change touch files it shouldn't? Are the tests covering the new behavior, not just the happy path? Does the diff include speculative refactors that weren't in the task description?
Files you @-reference may end up in Claude's context. appsettings.json with real connection strings, .env files, certificates — none of these should be referenced. Use user-secrets locally and keep secrets out of any file Claude can read. If a file must be referenced and contains a secret, redact it before the session.
Recurring failure modes specific to Claude Code + .NET workflows. Most are recoverable; all are avoidable.
A CLAUDE.md written six months ago describes the codebase as it was, not as it is. Claude follows it literally and produces code that no longer matches your conventions. Review and prune CLAUDE.md after every significant refactor; treat stale rules the way you'd treat stale comments.
A skill copied into .claude/skills/ does nothing unless Claude recognizes the trigger phrases in your prompt. After installing a skill, run a test prompt that should match its triggers and verify it activates. If it doesn't, the description needs tightening — the skill is dead weight until the trigger fires.
Claude generates an EF Core migration, a unit test, or a controller endpoint. The build is green. Ship it. Then production reveals the migration drops a column, the test asserts the wrong invariant, or the endpoint returns 500 on edge cases. Generated code requires the same review discipline as hand-written code; a green build is not the bar.
A single Claude session that's been running for 90 minutes across five unrelated tasks produces lower-quality output than five focused 20-minute sessions. The signal that you've crossed this threshold: Claude starts forgetting earlier rules or repeats mistakes you already corrected. End the session and start fresh.
Claude occasionally suggests packages that look real but aren't published, or that exist with a different name. Before adding any new package reference, verify the package on nuget.org. Hallucinated packages are documented in AI agent benchmarks; .NET-specific hallucinations include plausible-sounding Microsoft.Extensions.* sub-packages that never shipped.
A test fixture file with a real database password, a fake-but-valid API key, or a redacted-but-recoverable token gets committed because Claude referenced it during a session. Audit tests/ directories for any string that pattern-matches a credential before pushing. The fix is upfront: never put real credentials in any file Claude can read, even in tests.
Contributions are welcome. See CONTRIBUTING.md for guidelines.
Living document — updated as patterns are battle-tested in production.