📁 Sangam Dhakal - Portfolio v2.0 - Netscape Navigator 4.0
_
□
×

📰 AI Isn't Replacing .NET Developers. It's Changing What Our Job Is.

AI Isn't Replacing .NET Developers. It's Changing What Our Job Is.

AI Isn't Replacing .NET Developers. It's Changing What Our Job Is.

I've been writing C# for more than six years now, across fintech, insurance and aviation, first in Nepal and now here in Sydney. In all that time I don't think the way we build software has changed as fast as it has in the last twelve months.

A year ago, "AI in .NET" mostly meant calling the OpenAI API from a controller and hoping the JSON came back in the right shape. Today it's a proper part of the platform, with its own abstractions, its own frameworks and its own place in Visual Studio. I want to write down what has actually changed, and what I think it means for people like me who earn a living as .NET developers.

There's a lot of noise about AI and jobs right now. Some people say developers will be gone in two years. Others say nothing will really change. From where I sit, building AI features in .NET every week, neither is true. The job is very much still there. But it's a different job than it was.

The building blocks finally feel like .NET

The change I appreciate most is the boring one. Microsoft.Extensions.AI gives us a common set of abstractions, mainly IChatClient and IEmbeddingGenerator, so our code doesn't have to be married to a single AI provider.

That sounds small, but it's the same idea that made ILogger and dependency injection so useful. You write your service against an interface, register a concrete provider in Program.cs, and swap it later without touching business logic.

public class SummaryService(IChatClient chat)
{
    public async Task<string> SummariseAsync(string text)
    {
        var response = await chat.GetResponseAsync(
            $"Summarise this in two sentences:\n{text}");

        return response.Text;
    }
}

There is nothing exotic in that class. It's injectable, testable and provider-agnostic, which is exactly how I want AI code to look in a production codebase.

Middleware around the model

The part that really sold me is that the model sits in a pipeline, the same way a request does in ASP.NET Core. You can wrap it with caching, logging, telemetry and automatic tool calling, all in Program.cs:

builder.Services.AddDistributedMemoryCache();

builder.Services
    .AddChatClient(sp => CreateProviderClient(builder.Configuration))
    .UseDistributedCache()
    .UseFunctionInvocation()
    .UseOpenTelemetry()
    .UseLogging();

That's a big deal in real projects. Repeated prompts can be served from the cache instead of costing money. Every model call shows up in the same traces as the rest of the app. And when the model wants to call one of your functions, the function invocation middleware handles the back and forth for you.

Structured output, without the JSON guessing

Another small thing that saves a lot of pain: you can ask for a typed result instead of a string and then parsing it yourself.

public record TicketTriage(string Category, int Priority, string Reason);

var result = await chat.GetResponseAsync<TicketTriage>(
    $"Triage this support ticket:\n{ticketText}");

TicketTriage triage = result.Result;

I remember writing fragile code to strip markdown fences and fix half-broken JSON from model responses. This is so much nicer, and it fits naturally with records and the rest of modern C#.

RAG is becoming a normal backend feature

Most business AI features I've worked on aren't about the model knowing everything. They're about the model answering questions using your data: policies, product documents, internal knowledge, past tickets. That's retrieval-augmented generation, or RAG.

The pieces for this in .NET are now standard too. IEmbeddingGenerator turns text into vectors, and the vector store abstractions let you save and search them in a database, without tying your code to one vendor.

The interesting thing is how un-AI most of the work is. The hard parts of a good RAG system are:

  • Splitting documents into sensible chunks.
  • Keeping the index up to date when the source data changes.
  • Making sure a user can only retrieve documents they're allowed to see.
  • Measuring whether the answers are actually correct.

That's data engineering, security and testing. Again, classic backend work.

Agents grew up: Microsoft Agent Framework 1.0

For a while the agent story in .NET was confusing. Semantic Kernel did one thing, AutoGen did another, and you had to pick a side. That changed in April, when Microsoft shipped Agent Framework 1.0, which brings the ideas from both projects into a single SDK for .NET and Python.

It sits on top of Microsoft.Extensions.AI and adds the parts you need once an agent leaves the demo stage: multi-agent workflows, checkpointing, human-in-the-loop steps, observability and support for protocols like MCP and A2A. Semantic Kernel is still supported for existing apps, but if I were starting a new agent project today, I would start on Agent Framework.

What I like is the mindset behind it. The hard part of an agent is not the prompt. It's managing state, controlling the flow, limiting what tools it can call and making sure you can recover when something goes wrong. Those are classic backend engineering problems, and .NET developers are already good at them.

I think about agents a bit like a new team member who is very fast but has no common sense. You wouldn't give a new hire admin access to production on their first day. You'd give them clear tasks, limited permissions, and someone to check their work. Agents need exactly the same thing, and designing that is our job.

A developer working on a laptop

MCP: the new API surface

If there is one thing I'd tell every .NET developer to learn this year, it's the Model Context Protocol (MCP). It's an open standard for exposing tools and data to AI models, and there is now an official C# SDK for it, including an ASP.NET Core package for HTTP-based servers.

I built my own interview-question bank as an MCP server, and it honestly felt like building a normal Web API. You decorate methods, register them, and the AI client can discover and call them:

builder.Services.AddMcpServer()
    .WithHttpTransport()
    .WithToolsFromAssembly();

app.MapMcp();

[McpServerToolType]
public static class QuestionTools
{
    [McpServerTool, Description("Search interview questions by keyword.")]
    public static Task<IReadOnlyList<Question>> Search(
        IQuestionRepository repo, string keyword) => repo.SearchAsync(keyword);
}

The way I think about it now: a few years ago every system needed a REST API so other apps could talk to it. Soon, a lot of systems will also need an MCP server so AI agents can talk to it. That's a big opportunity for anyone who already knows how to design clean, secure APIs.

What building my own MCP server taught me

A few lessons I didn't expect:

  • Descriptions are part of the API. The model decides which tool to call based on its name and description. A vague description means the wrong tool gets called. I spent more time improving tool descriptions than writing the tool code.
  • Design for a caller that makes mistakes. An AI client will sometimes pass odd values or call things in a strange order. Good validation and clear error messages help it correct itself.
  • Keep tools small and focused. One tool that does one thing well works much better than a giant tool with ten optional parameters.
  • Have a UAT environment. I run a UAT and a production version of my server. I test new tools against UAT with a real AI client before anything reaches production. It caught a lot of issues.

MCP needs security thinking

MCP is powerful, and that's exactly why it needs care. When you give an AI model tools, you're letting it take actions. Some things I always think about:

  • Least privilege. Only expose the tools that are really needed. A read-only tool is much safer than a tool that can delete.
  • Authentication and authorisation. A remote MCP server is an API. Protect it like one, and check permissions inside each tool, not just at the door.
  • Prompt injection. If a tool returns text from users or the web, that text can contain instructions trying to trick the model. Treat tool output as data, never as commands.
  • Confirmation for destructive actions. Deleting, paying or sending something should need a human to approve it.

Copilot moved from autocomplete to teammate

The tooling side has changed just as much. GitHub Copilot in Visual Studio 2026 is no longer just finishing my lines. It has an agent mode that can plan a change across several files, run the build and the tests, and fix what it broke. The newer agent, built on the same Copilot SDK as the Copilot CLI, even ships with built-in skills written by the .NET and Azure teams.

On GitHub, the Copilot coding agent can pick up an issue and come back with a pull request. I still review every line, but the first draft of a lot of routine work, like unit tests, DTO mapping, migration boilerplate or upgrading an old .NET Framework project, now takes minutes instead of an afternoon.

What my day actually looks like now

If I compare a normal working day now with a couple of years ago, the biggest difference is where my time goes.

I spend less time typing code and searching for syntax. I spend much more time on:

  • Writing clear task descriptions, with context and a definition of done.
  • Reading and reviewing code I didn't type myself.
  • Thinking about design before anything gets written.
  • Checking edge cases, security and tests.

In a way, every developer now does a bit of what a tech lead used to do. You're guiding work, not just doing it. That's exciting, but it also means you need to know what good looks like, or you'll happily approve something that isn't.

So what does this mean for us?

I don't believe AI is replacing .NET developers. But I do think it's replacing a certain kind of .NET work: the repetitive, low-judgement typing that used to fill a good part of the day. What's left is the work that needs real understanding.

From what I've seen, the skills that matter more now are:

  1. System design. Agents are only as good as the boundaries and tools you give them.
  2. Reviewing code properly. If AI writes the first draft, you have to be very good at spotting what's subtly wrong.
  3. Security. Prompt injection, over-permissioned tools and data leaks are the new SQL injection. My information security studies have suddenly become very practical.
  4. Testing and evaluation. You can't unit test an LLM the old way, so you need evaluation, guardrails and good observability.
  5. Domain knowledge. Knowing how a payment, a policy or a flight booking actually works is what turns a generic agent into something a business can trust.

A clean desk setup with a laptop

What worries me a little

I want to be honest that not everything about this is easy.

I worry most about junior developers. A lot of what I learned came from doing the repetitive work myself: writing the CRUD screens, mapping the DTOs, fixing my own silly bugs. If AI does all of that from day one, how do new developers build the instincts to know when the AI is wrong? I don't have a perfect answer. I think teams need to be more deliberate about teaching, and juniors need to be curious about why the code works, not just whether it does.

I also see people trusting AI output too much. Code that compiles and looks clean isn't the same as code that's correct. The faster code is produced, the more important reviews and tests become.

What this means for interviews

I'm also going through interviews myself, and I can see the questions changing. Alongside the classic C#, async, EF Core and system design questions, I'm now seeing things like:

  • How would you add an AI feature to an existing ASP.NET Core app?
  • How do you stop an agent from doing something it shouldn't?
  • How do you test a feature when the model's output isn't the same every time?
  • How would you keep customer data safe in a RAG system?

None of these replace the fundamentals. If anything, they build on them. You can't answer "how do you secure an MCP server" well without understanding authentication, authorisation and API design first.

Where I'd start if you're new to this

If you're a .NET developer and all of this feels like a lot, don't try to learn it all at once. Here's the path I'd suggest:

  1. Add IChatClient to a small side project and call a model through it. Then add caching and logging with the middleware.
  2. Try structured output. Ask the model to return a record instead of a string.
  3. Build a tiny RAG feature. Index a handful of your own documents and answer questions from them.
  4. Turn one of your existing APIs into an MCP server and connect it to an AI client.
  5. Build a simple agent with Agent Framework that uses those tools, with a human approval step for anything that changes data.

That path takes you from "I've used ChatGPT" to "I can build AI features in production", and it uses skills you already have: dependency injection, ASP.NET Core and good API design.

Final thoughts

The .NET ecosystem has caught up with AI faster than I expected, and in some areas it now feels like one of the most solid places to build serious AI systems. The job is changing, but the fundamentals we've spent years learning matter more, not less.

If you're feeling anxious about AI and your career, I understand. I've felt it too. But every time I actually build something with these tools, I come away more confident, not less. The hard problems are still hard. They still need people who understand systems, data, security and the business. That's us.

I'll keep writing about what I build along the way. If you're a .NET developer going through the same shift, I'd love to hear how it's changing your work. Leave a comment below.

X / Twitter LinkedIn

Comments (0)

No comments yet. Be the first!

🌐 Sangam's Webring

⏪ Previous 🏠 Main Next ⏩
💬 Chat with me