Cursor Rules for .NET: C#, Project Boundaries, and Tests
A practical rule set for .NET and C# projects in Cursor, covering solution structure, dependency direction, database conventions, and test commands. Adapt each rule to your project and keep the team decisions that make them specific in fenbs.
Updated 6 min read
Cursor rules for a .NET project tell the assistant how your solution is organized, which project owns what, how to handle errors and data access, and which commands to run when verifying changes. Without them, the assistant makes reasonable guesses based on common .NET patterns — but your project may use different naming conventions, a specific ORM approach, or a custom error type that generic advice does not know about. A tool like fenbs helps teams record the decisions behind those conventions, so every connected assistant starts with the approved choices rather than default assumptions.
The rules below are templates. Replace placeholder names with your actual project names, namespaces, and file paths before using them. Test each rule on a real file in your codebase to confirm it produces the behavior you want. Discard any rule that duplicates what the compiler or your linter already enforces — redundant rules add noise without helping.
Solution and project structure
The most common source of confusion in a .NET solution is which project a new class should live in. A rule that names your projects and their responsibilities saves the assistant from adding a domain model to the API project or a database query to the domain layer.
This solution contains: - YourProject.Domain: domain models and interfaces, no infrastructure dependencies - YourProject.Application: use cases and service interfaces, depends only on Domain - YourProject.Infrastructure: EF Core, external services, implements interfaces from Application - YourProject.Api: ASP.NET controllers and middleware, depends only on Application Never add infrastructure dependencies to Domain or Application. Never reference the Api project from any other layer.
Dependency and namespace rules
Dependency direction is the most important architectural constraint in a layered .NET solution. An assistant that adds a direct database call to a domain class breaks the separation that the solution was designed around. A short, specific rule prevents this without requiring the assistant to infer the architecture from the folder structure.
Dependency direction: Domain <- Application <- Infrastructure <- Api. Do not create references that go against this direction. If you need to call infrastructure from Application, define an interface in Application and implement it in Infrastructure. Inject the interface, not the implementation.
Database and Entity Framework rules
If your project uses Entity Framework, a rule that specifies your migration approach and query style prevents the assistant from mixing approaches. Whether you use database-first with hand-written SQL, code-first migrations, or no migrations at all, make the rule explicit. An assistant that generates a migration when your project forbids it creates work to undo.
Data access: - Use YourDbContext from Infrastructure/Data/YourDbContext.cs - Do not call the database from Domain or Application classes directly - All queries go through repository interfaces defined in Application - Do not use raw SQL unless the repository method explicitly requires it - Migrations: [describe your approach — e.g., "hand-written SQL in db/" or "EF migrations via dotnet-ef"]
Error handling and result types
C# projects vary widely in how they handle errors. Some throw exceptions, some use a Result or Either type, some use problem details for HTTP responses. A rule that names your actual error type and where to import it from prevents the assistant from introducing a different approach that breaks your existing error handling middleware.
Error handling: - Use Result<T> from YourProject.Application.Common.Result for service methods - Do not throw exceptions from application service methods; return a failed Result - Controller actions map Result failures to HTTP status codes via the ResultMapper - Only throw for truly unexpected errors (OutOfMemoryException etc.)
Test project and command rules
A test rule tells the assistant which test project to add tests to, which framework is in use, and what command to run to verify changes. Without this, the assistant may create test files in the wrong location, use a different assertion library, or suggest an invalid test command.
Tests: - Unit tests: YourProject.Tests.Unit (xUnit, FluentAssertions) - Integration tests: YourProject.Tests.Integration - File naming: match the subject class name with Tests suffix (e.g., UserServiceTests.cs) - Run: dotnet test --no-build from the solution root - Do not use [InlineData] for more than 5 cases; switch to [ClassData] or [MemberData]
Keep your .NET rule set where every assistant can read it
Add your approved .NET rules to fenbs Skills and prompts. Include the project name, the version of .NET and EF Core in use, and the decisions your team made about error handling and migration approach. When conventions change — say the team adopts a new ORM — update the entry in fenbs and every future session starts from the current decision, not the old one.
Create a free accountFree for one person · No credit card · Works with Claude, ChatGPT, Cursor and more
How to do this with fenbs
- Create a free account and add a project for your .NET solution.
- Add a skill or prompt for each rule category: solution structure, dependency direction, data access, error handling, and tests. Short, named rules are easier to maintain than one large block.
- Record the choices that make your project specific in Decisions and rules: why you chose this ORM, why the migration approach is what it is, which error type to use and why. The assistant reads these before starting work.
- When the team debates changing a convention — switching from xUnit to MSTest, for example — record the open decision in fenbs and wait for sign-off before updating the rules.
- Connect your AI tools from Integrations so they read the current rule set at the start of each coding session.
What these rules cannot replace
Rules handle repeatable conventions. They do not replace a code review for the specific logic of a new feature, a decision about which third-party library to use, or a discussion about whether to change the solution architecture. Rules also cannot capture project-specific business requirements or the context of a current task. That context belongs in your task and project notes in fenbs, not in a rule file.
fenbs does not connect to the .NET build system or run dotnet commands. If you need to verify that a rule is being followed, run dotnet test and dotnet build yourself. The cursor rules hierarchy article explains how to scope your .NET rules to the right files so they do not conflict with rules for other parts of the project.
When the solution upgrades to a new .NET version, review the rule files for references to obsolete APIs or patterns. Some patterns standard in .NET 6 are superseded in .NET 8 or later — minimal APIs, primary constructors, and collection expressions all changed what idiomatic C# looks like. A rule written for an older version that still suggests the old pattern actively misleads the assistant once the project has upgraded.
If the project uses a vertical slice or feature-folder architecture instead of the traditional layered approach, update the structure rule to reflect that. The template above uses a classic layered structure. A feature-folder layout has different conventions for where services, models, and tests live. Write the rule for how your solution actually works — a rule that describes a pattern the codebase abandoned is worse than no rule at all.