# How I Stopped Fighting AI Context: JetBrains AI vs. Copilot in Rider

> Source: <https://dev.to/dotnetwithai/how-i-stopped-fighting-ai-context-jetbrains-ai-vs-copilot-in-rider-3lhi>
> Published: 2026-05-28 12:13:39+00:00

Last Tuesday, I was staring at a `System.NullReferenceException: Object reference not set to an instance of an object. (Parameter 'serviceProvider')`

in a new `Program.cs`

file, trying to boot up a .NET 9 API. The kicker? The code came almost entirely from an AI assistant. I'd been trying to leverage JetBrains AI Assistant and GitHub Copilot in Rider 2026 to speed up a legacy .NET 7 service migration, and honestly, the context dance between them was driving me a little nuts.

For a while, I felt like I was spending more time debugging AI output than writing actual code. My goal was simple: use AI to offload boilerplate, understand unfamiliar patterns in a large codebase, and generally accelerate my daily work. What I ended up with initially was a chaotic mix of half-baked suggestions and context-blind refactors. It took some serious trial and error, but I think I've finally settled on a pragmatic approach that works for me.

My initial mistake was treating both JetBrains AI Assistant (powered by Claude Sonnet 4.6) and GitHub Copilot (the latest Copilot for Workspaces version) as interchangeable, all-knowing oracles. I'd ask a question in the chat window, or expect an inline completion to magically understand my entire project structure. This almost never worked.

For instance, I'd ask JetBrains AI Assistant to "add a new `AuditLogService`

to this project" and get back a barebones class definition that completely ignored my existing DI setup, `appsettings.json`

conventions, or even the `ILogger`

pattern I was using everywhere else. It was technically correct C#, but utterly useless in my context. Copilot, meanwhile, would often complete a line based purely on syntax and local variables, completely missing the architectural implications. I even got a code block where `_dbContext`

was used before it was injected, leading to that nasty `NullReferenceException`

I mentioned.

Here’s a simplified example of the kind of output I was getting, which compiled but didn't quite fit:

```
// Asking JetBrains AI Assistant to "Add a new AuditLogService"
public class AuditLogService
{
    public void LogAction(string user, string action)
    {
        Console.WriteLine($"User {user} performed {action}");
    }
}

// And then Copilot suggesting usage without context
public class MyController
{
    private readonly AuditLogService _auditLogService; // No constructor injection

    public MyController() // Missing dependency
    {
        // ...
        _auditLogService.LogAction("current_user", "some_action"); // NRE waiting to happen
    }
}
```

The issue wasn't the AI's intelligence, but my *prompting strategy* and expectation of its context awareness. While MCP (Model Context Protocol) support in Rider 2026 does a great job of feeding relevant code snippets, it's not a mind-reader. **I learned that explicit context is king.**

What I ended up with is a clearer division of labor, treating them less as rivals and more as complementary tools. Your mileage may vary, but this has drastically improved my productivity.

**GitHub Copilot in Rider:** This is my fast-twitch muscle memory. For quick, inline completions, generating boilerplate, writing unit tests for a specific method, or even just filling out XML documentation comments, Copilot is incredibly efficient. It excels when the context is narrow and immediately visible in the current file or surrounding lines. I use it constantly for things like `if (string.IsNullOrWhiteSpace(value))`

or generating switch expressions. I've also found Copilot Edits surprisingly useful for quick refactors within a single method, like extracting a local function or simplifying a LINQ query.

```
// Using Copilot for quick completion and test generation
public interface IOrderService
{
    Task<bool> ProcessOrderAsync(Guid orderId);
}

// After defining IOrderService, Copilot often suggests this:
public class OrderService : IOrderService
{
    public async Task<bool> ProcessOrderAsync(Guid orderId)
    {
        // TODO: Implement order processing logic
        return await Task.FromResult(true); 
    }
}

// If I then navigate to the test project and create a new test file:
[TestFixture]
public class OrderServiceTests
{
    [Test]
    public async Task ProcessOrderAsync_ValidId_ReturnsTrue()
    {
        // Copilot will often suggest this test setup:
        var service = new OrderService();
        var result = await service.ProcessOrderAsync(Guid.NewGuid());
        Assert.That(result, Is.True);
    }
}
```

**JetBrains AI Assistant (with Claude Sonnet 4.6) in Rider:** This is where I go for deeper understanding, architectural refactoring, or when I need more nuanced code generation. Its strength lies in its chat interface, allowing for multi-turn conversations and explicit context feeding. When I need to understand a complex legacy class, I'll paste the entire file into the chat, ask "Explain the dependencies and responsibilities of this `LegacyOrderProcessor`

," and then follow up with "Suggest a strategy to refactor this using a CQRS pattern for .NET 9." It takes more effort to craft the prompt, but the quality of the output is significantly higher for complex tasks. I've even used Claude Opus 4.7 via the assistant for particularly thorny problems, though it's slower.

```
// Prompting JetBrains AI Assistant for a refactor
// (Imagine I've pasted the entire 'LegacyOrderProcessor' class into the chat window first)
"Refactor the provided `LegacyOrderProcessor` class to use an `IOrderStategy` pattern. 
Create a new interface `IOrderProcessingStrategy` and at least two concrete implementations
(`StandardOrderStrategy`, `PremiumOrderStrategy`). Explain the changes step-by-step and 
show how to update the processor to use a strategy factory."

// Partial example of the kind of detailed response I get back:
// (AI Assistant would provide full code, explanations, and factory logic)
public interface IOrderProcessingStrategy
{
    Task<bool> ProcessAsync(Order order);
}

public class StandardOrderStrategy : IOrderProcessingStrategy
{
    public async Task<bool> ProcessAsync(Order order)
    {
        // Standard processing logic here
        return await Task.FromResult(true);
    }
}
```

This dual-tool approach means Copilot handles the small, localized tasks, while JetBrains AI Assistant tackles the bigger picture, aided by more explicit context from me.

I'm still figuring out the best way to leverage Copilot for Workspaces' broader context features without feeling overwhelmed by its suggestions, especially when dealing with early .NET 10 preview features. If you've managed to integrate both JetBrains AI Assistant and GitHub Copilot effectively in Rider for large-scale .NET refactoring, I'd love to hear your strategies and any pitfalls you've encountered.
