By the end of this lesson you'll have an AI assistant that writes .NET the way you write it - matching your stack, architecture, and conventions on the first try. Most developers get this wrong.
You ask Claude Code for one endpoint. You get back a repository interface, an AutoMapper profile, DateTime.Now, and a folder structure from someone else's project. The code isn't wrong - it's just not your code.
The key insight: it's not that the AI doesn't know .NET. It starts every session knowing nothing about your repo, so it fills the gap with the most common .NET code it has seen. The fix isn't a better prompt every time - it's giving the AI context, once.
# install, then run inside any project folder
npm install -g @anthropic-ai/claude-code
claudeThis lesson uses Claude Code, but the CLAUDE.md idea maps to Cursor's rules and Copilot's instructions too. Open it inside a real solution - you learn this on code you care about.
CLAUDE.md is a markdown file at your repo root. Claude Code loads it automatically at the start of every session, before your first prompt. Think of it as the briefing you'd give a new senior dev joining your team. It answers four questions:
# Project: Orders API
## Stack
- .NET 10 / C# 14 · ASP.NET Core Minimal APIs
- EF Core 10 + PostgreSQL · FluentValidation · xUnit + Testcontainers
## Architecture
- Vertical Slice: everything for one feature in Features/[Feature]/.
## Conventions
- Result pattern, not exceptions for control flow.
- Inject TimeProvider - never DateTime.Now.
- TypedResults; DTOs are records; never expose EF entities.
- CancellationToken on every async method.
## Never suggest
- AutoMapper - write explicit mappings.
- Repository/UnitOfWork over EF Core - DbContext already is one.
- Exceptions for expected outcomes (not-found, validation).
- In-memory database in tests - use Testcontainers.public class OrdersController : ControllerBase
{
private readonly IOrderRepository _repo;
[HttpPost] public async Task<IActionResult>
Create(CreateOrderDto dto){
var o = new Order{ CreatedAt = DateTime.Now };
await _repo.AddAsync(o);
return Ok(o); // leaks the entity
}
}public sealed class CreateOrderEndpoint : IEndpointGroup
{
public void Map(IEndpointRouteBuilder app) =>
app.MapPost("/api/orders", Handle)
.Produces<OrderResponse>(201)
.ProducesValidationProblem();
static async Task<Results<Created<OrderResponse>,
ValidationProblem>> Handle(CreateOrderRequest req,
IOrderService svc, TimeProvider time,
CancellationToken ct) => ...
}Same prompt. Different universe. That's the CLAUDE.md at work.
They stack - so you can set global preferences once and override per project:
Claude Code has a plan mode: it proposes a full plan and waits for your approval before touching a single file. Use it for migrations, refactors, or anything that spans several files. It's the difference between "AI did something to my repo" and "AI did exactly what I approved."
The pattern: state the outcome, name the constraints, and say what to avoid.
These are the patterns your CLAUDE.md should steer toward - and the raw material for a sharp "Never suggest" section.
CLAUDE.md to a real project.CLAUDE.md fixes that. Cover stack, architecture, conventions, and (most importantly) what to never suggest. Prompt for outcomes, ask for a plan, leave good code alone.Next → Part 2: make the assistant a specialist with skills and agents.
In Part 1 you gave Claude context. Now, instead of re-explaining a task every time, you give it reusable capabilities it loads automatically. That's what skills and agents are.
/plugin marketplace add StefanTheCode/dotnet-ai-toolkit
/plugin install dotnet-ai-toolkit@thecodeman-ai-toolkitThen just talk to Claude Code normally and the matching skill kicks in - no command to remember:
> This EF query is slow, optimize it
> Scaffold a products endpoint
> Write integration tests for the checkout flow
> Review this PR for .NET antipatternsEach skill carries a fixed checklist, so output is consistent instead of depending on how you phrased the prompt. Start with the 5 you'll use daily - don't memorize 44.
Reopen the session after adding a skill so it loads. Update marketplace skills anytime with /plugin marketplace update thecodeman-ai-toolkit.
A skill is a folder with a SKILL.md: YAML frontmatter (the trigger) + instructions (what to do).
---
name: ef-core-query-optimizer
description: Optimize EF Core queries. Use whenever the user shares
EF Core / LINQ code or mentions N+1, AsNoTracking, projections...
---
# EF Core Query Optimizer
Run this checklist in order:
1. Projection - .Select() to a DTO if only some columns are needed
2. Tracking - .AsNoTracking() for read-only queries
3. N+1 - detect lazy loading in loops
4. Async + CancellationToken on every query
Output: the rewritten query + one line per change. Leave optimal code alone.description is the trigger. Make it specific and slightly pushy about when to fire. Vague description → skill never triggers.Name the triggers (the words and situations), list synonyms, and be a little pushy ("Always use this for…"). A references/ folder can hold extra material that loads only when the skill is active - keeping your main context light.
Pick one task you repeat weekly. Create .claude/skills/my-endpoint/SKILL.md:
---
name: my-endpoint
description: Scaffold a new Minimal API endpoint in our style. Use when
the user wants to add an endpoint, a route, or a new feature slice.
---
# New Endpoint
Create a full vertical slice in Features/[Feature]/:
- Request/Response records (never expose EF entities)
- FluentValidation validator + endpoint filter
- Handler returning Result<T>
- IEndpointGroup with TypedResults + OpenAPI metadata
- CancellationToken threaded through
- One integration test (WebApplicationFactory + Testcontainers)Reopen the session, type "add a create-customer endpoint" - your skill fires. You just encoded your team's standard once, forever.
When you want a review of the whole codebase, ask for what the agent does:
> Audit the security of this API
> Review this PR like a senior .NET engineer
> Find the architecture problems in this solutionThe agent explores your code on its own and returns a ranked report - Critical / Should-fix / Nit - with a fix for each. The fastest second pair of eyes you'll ever have.
An agent is a single .md file with frontmatter that defines its role, the tools it may use, and (optionally) the model:
---
name: aspnetcore-security-auditor
description: Audits an ASP.NET Core codebase against the OWASP Top 10 and
.NET-specific risks. Use for a security review or "is my API secure".
tools: Read, Glob, Grep, Bash
model: inherit
---
# ASP.NET Core Security Auditor
Walk the endpoints. Check authorization, injection, secrets in source,
CORS, mass assignment, vulnerable dependencies.
Output a ranked report (Critical / Should-fix / Nit) with a fix for each.Slash commands wrap a whole workflow behind one command. Instead of describing the steps, you type /scaffold and it runs the right skills and agents in order. A command is just a markdown file in .claude/commands/:
# .claude/commands/scaffold.md
Scaffold a complete vertical-slice feature: endpoint, validation,
Result handling, OpenAPI metadata, CancellationToken, and one
integration test. Match the existing features. Then run the tests.Handy commands to build: /scaffold, /verify, /code-review, /security-scan.
Hooks run automatically around tool use - shell commands wired to events:
Hooks turn your conventions from "things you hope the AI follows" into "things the tooling enforces."
description first - 90% of the time that's it.skills/<name>/SKILL.md, not a loose .md.description is the trigger, the body is a checklist). Agents = specialists that review your whole codebase. Together they turn a general assistant into your .NET specialist.Next → Part 3: MCP - give the AI real tools in C#, so it can do things in your systems, not just write code.
# Claude Code
npm install -g @anthropic-ai/claude-code
# The .NET AI ToolKit (skills + agents)
/plugin marketplace add StefanTheCode/dotnet-ai-toolkit
/plugin install dotnet-ai-toolkit@thecodeman-ai-toolkit
/plugin marketplace update thecodeman-ai-toolkit # get new skills> Give me a short plan first, then wait for my OK
> This EF query is slow, optimize it
> Refactor this to the Result pattern; leave idiomatic code alone
> Write integration tests with WebApplicationFactory + Testcontainers
> Review this PR like a senior .NET engineer
> Audit the security of this API
> Don't invent problems - leave correct code aloneThe lessons use Claude Code, but the ideas map across tools: CLAUDE.md maps to Cursor rules / Copilot instructions, and skills/agents/MCP are increasingly supported everywhere.
No. It replaces the developer who refuses to use it. You stay the engineer - you review everything, and you're still responsible for what ships.
No. This is applied engineering, not data science. You won't derive a transformer. You'll ship features.
Install a set, but reach for the 5 that match your daily work. A library of 44 you never open helps no one.
Almost always the description. Make it specific about when to fire, add synonyms, and reopen the session.
Use plan mode for risky changes, keep your work in git, and review diffs. Add a pre-commit hook to block bad patterns. You approve; it executes.
The full course - Claude Code, skills, MCP in C#, then building real AI features (LLMs, RAG, agents) into your .NET apps - is inside the community, with new video clips as I record them.
Join the community → Free newsletter (20k+)Built by Stefan Đokić - TheCodeMan · Microsoft MVP