🔥 Pragmatic .NET Code Rules Course is on Presale - 50% off!BUY NOW
AI ROADMAP COURSE · TRACK A

Use AI to build .NET faster

The fastest wins in the whole roadmap: make Claude Code write your .NET, then turn it into a specialist with skills and agents. Real code, no theory.


PART 1 · LESSON 1 OF 5

Make Claude Code write your .NET

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.

The problem

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.

Step 1 - Install Claude Code

bash
# install, then run inside any project folder
npm install -g @anthropic-ai/claude-code
claude

This 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.

Step 2 - The one file that changes everything: CLAUDE.md

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:

  1. What's the stack? (exact versions)
  2. How is the project structured? (architecture + folders)
  3. What are the conventions? (the patterns you use)
  4. What should it never do? (the patterns you don't use)
md
# 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.
💡 Don't write it by hand
Use the free CLAUDE.md Generator - pick your stack and it builds this file for you. But understand why each line is there first.
⛔ The "Never suggest" section is the secret
"Never wrap EF Core in a repository." "Never use AutoMapper." These block the wrong default before Claude walks down that path - far cheaper than reviewing and reverting it afterward. This one section saves more review time than anything else in the course.

Step 3 - Prompt for real work

  • Describe the outcome, not the steps. Not "make a controller + service + repository" - but "add a create-product endpoint, return a Result, follow the existing features."
  • Ask for a plan before edits on anything non-trivial: "give me a short plan and wait for my OK." Catches wrong assumptions before they become wrong code.
  • Tell it to leave good code alone: "Don't invent problems."

Worked example

✗ Without CLAUDE.md
C#
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
  }
}
✓ With CLAUDE.md
C#
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.

Where CLAUDE.md lives (and its friends)

They stack - so you can set global preferences once and override per project:

FileScopeUse it for
~/.claude/CLAUDE.mdYou, every projectYour personal defaults (e.g. "always explain your plan first")
CLAUDE.md (repo root)The whole teamStack, architecture, conventions - commit it so everyone shares it
CLAUDE.local.mdJust you, this repoPersonal notes for this project - add it to .gitignore

Use Plan Mode for anything risky

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."

Prompting cheat sheet

Instead of…Say…
"Make this better""Optimize this for readability and remove the N+1 - don't change behavior"
"Add auth""Add JWT bearer auth with policy-based authorization; secrets in config"
"Fix the bug""Here's the exception + stack trace. Find the root cause and give the minimal fix - no try/catch that hides it"
"Write tests""Write integration tests with WebApplicationFactory + Testcontainers: happy path, validation, not-found"
"Refactor this""Refactor to the Result pattern; leave anything already idiomatic alone"

The pattern: state the outcome, name the constraints, and say what to avoid.

The bad defaults → what they should become

These are the patterns your CLAUDE.md should steer toward - and the raw material for a sharp "Never suggest" section.

AI's common defaultWhat you want insteadWhy
DateTime.NowTimeProviderTestable, deterministic time
Repository over EF CoreDbContext directlyDbContext is already a UoW + repository
AutoMapperExplicit mapping / projectionNo hidden reflection; project in EF queries
Exceptions for not-foundResult pattern + ProblemDetailsExpected outcomes aren't exceptional
new HttpClient()IHttpClientFactoryAvoids socket exhaustion
Manual cache serializeHybridCacheL1+L2, tag invalidation, stampede protection
Results.Ok(...)TypedResultsTyped, testable, better OpenAPI
UseInMemoryDatabase in testsTestcontainersReal engine catches real bugs
⚠️ Common mistakes
  • No CLAUDE.md at all → generic output → you blame the AI. The #1 mistake.
  • A CLAUDE.md that's docs for humans, not instructions for the AI. Keep it concise and imperative.
  • Accepting code you don't understand - you're still responsible.
  • Skipping the "Never suggest" section - the highest-value part.
✅ Your exercise
  1. Add a CLAUDE.md to a real project.
  2. Fill in "Never suggest" with the 3 patterns you're tired of correcting.
  3. Do one backlog task fully with Claude Code - plan first, then edits.
  4. Post what changed in the community feed.
Recap
Claude starts every session blind to your repo - 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.

PART 2 · LESSON 2 OF 5

Turn the assistant into a .NET specialist

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.

Skill vs. agent - the 20-second version

  • A skill is a focused capability Claude loads automatically when your request matches ("optimize this EF query", "scaffold an endpoint"). You don't call it - you describe what you want.
  • An agent explores your codebase on its own and produces a report ("audit the security of this API"). You invoke it by asking for what it does.
💡 Rule of thumb
Skill = "do this specific thing." Agent = "look at my repo and tell me what's wrong."

Step 1 - Install a set of skills

bash
/plugin marketplace add StefanTheCode/dotnet-ai-toolkit
/plugin install dotnet-ai-toolkit@thecodeman-ai-toolkit

Then just talk to Claude Code normally and the matching skill kicks in - no command to remember:

bash
> This EF query is slow, optimize it
> Scaffold a products endpoint
> Write integration tests for the checkout flow
> Review this PR for .NET antipatterns

Each 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.

Where skills & agents live

LocationAvailable in
~/.claude/skills/ · ~/.claude/agents/Every project (personal)
.claude/skills/ · .claude/agents/ (in the repo)Just this project - commit to share with the team
A plugin marketplace (like the ToolKit)Every project, and you get updates with one command

Reopen the session after adding a skill so it loads. Update marketplace skills anytime with /plugin marketplace update thecodeman-ai-toolkit.

Step 2 - How a skill works (so you can write one)

A skill is a folder with a SKILL.md: YAML frontmatter (the trigger) + instructions (what to do).

md
---
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.
  • The description is the trigger. Make it specific and slightly pushy about when to fire. Vague description → skill never triggers.
  • The body is a checklist, not an essay. Concrete steps + BAD/GOOD examples + a fixed output format = consistent results.
Anatomy of a description that actually triggers
Weak (rarely fires)Strong (fires reliably)
"Helps with EF Core.""Use whenever the user shares EF Core / LINQ code, a DbContext, or a slow query, or mentions N+1, AsNoTracking, projections, cartesian explosion. Always use this for EF performance instead of answering from memory."

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.

Step 3 - Write your own skill

Pick one task you repeat weekly. Create .claude/skills/my-endpoint/SKILL.md:

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.

Step 4 - Use an agent

When you want a review of the whole codebase, ask for what the agent does:

bash
> Audit the security of this API
> Review this PR like a senior .NET engineer
> Find the architecture problems in this solution

The 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:

md
---
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.

Level up - slash commands & hooks

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/:

md
# .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:

HookWhat it does
Post-edit on *.csRuns dotnet format - every file stays clean automatically
Pre-commitBlocks DateTime.Now, async void, new HttpClient() in staged files
Pre-bash guardBlocks destructive git ops (force push, reset --hard)

Hooks turn your conventions from "things you hope the AI follows" into "things the tooling enforces."

🔧 Troubleshooting: "my skill won't trigger"
  • Fix the description first - 90% of the time that's it.
  • Reopen the session after adding a skill - it loads at start.
  • Name it explicitly in your prompt ("optimize this EF Core query").
  • Check the folder - a skill is skills/<name>/SKILL.md, not a loose .md.
✅ Your exercise
  1. Install the ToolKit skills and use 5 on a real repo.
  2. Write one custom skill for a task you repeat weekly.
  3. Run one agent (security or code review) and act on its top finding.
  4. Share your custom skill (or what the agent caught) in the feed.
Recap
Skills = reusable, auto-triggered capabilities (the 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.

QUICK REFERENCE

The one-screen cheat sheet

Install

bash
# 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

Where things live

PathWhat
CLAUDE.md (repo root)Project context - commit it
~/.claude/CLAUDE.mdYour personal defaults, every project
.claude/skills/<name>/SKILL.mdA skill
.claude/agents/<name>.mdAn agent
.claude/commands/<name>.mdA slash command

Prompts that pull their weight

bash
> 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 alone
GLOSSARY

The words, in plain English

TermWhat it means
CLAUDE.mdA context file at your repo root the AI reads at the start of every session - your stack, conventions, and what to never do.
SkillA reusable, auto-triggered capability (one SKILL.md) that does one focused thing well.
AgentA specialist that explores your codebase on its own and returns a report. You invoke it by asking for what it does.
Slash commandA saved workflow you trigger with /name - it orchestrates skills and agents.
HookA shell command that runs automatically around tool use (e.g. format on every edit).
MCPModel Context Protocol - a standard that lets AI clients call external tools/data. You can build an MCP server in C#.
LLMLarge Language Model - the model behind Claude/GPT that generates text.
EmbeddingA vector representation of text, so you can search by meaning.
RAGRetrieval-Augmented Generation - retrieve your relevant data, then let the LLM answer from it (covered in Track B).
IChatClientThe Microsoft.Extensions.AI abstraction for calling any LLM provider from .NET.
FAQ

Frequently asked

Does this only work with Claude Code?

The 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.

Is the AI going to replace me?

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.

Do I need to know AI/ML math for this?

No. This is applied engineering, not data science. You won't derive a transformer. You'll ship features.

How many skills should I install?

Install a set, but reach for the 5 that match your daily work. A library of 44 you never open helps no one.

My skill isn't triggering - what's wrong?

Almost always the description. Make it specific about when to fire, add synonyms, and reopen the session.

Is it safe to let the AI edit my repo?

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.

This is Track A. Track B is where it gets rare.

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