.NET  

Best Practice to Make Your Project Cleaner in .NET

Introduction

In this article, we will see the Best practice to make your project cleaner in .NET

Before we start, please take a look at my last article on Best practice to make your project cleaner in .NET CORE.

Let's get started.

The clean project principles are mostly the same, but in .NET Framework there are some differences in structure, DI, and configuration because:

  • There's no Program.cs with minimal hosting model.

  • You often work with ASP.NET MVC 5, Web API 2, or WCF instead of ASP.NET Core.

  • Dependency Injection and configuration are not built-in — you use NuGet packages (e.g., Autofac, Unity, Ninject).

Here’s the .NET Framework–specific best practices:

1. Keep a Layered Architecture

Example for ASP.NET MVC 5 / Web API 2:

MyApp.sln
 ├─ MyApp.Web         // MVC or Web API project (Controllers, Views)
 ├─ MyApp.Application // Service layer (business logic, DTOs)
 ├─ MyApp.Domain      // Entities, enums, interfaces
 ├─ MyApp.Infrastructure // EF6, repositories, external integrations
 └─ MyApp.Tests       // Unit & integration tests

Note: You can still do feature-based folders inside Web or Application.

2. Use Dependency Injection (Manually Registered)

In .NET Framework, you add a DI container manually, for example Autofac:

var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<OrderService>().As<IOrderService>();
builder.RegisterType<OrderRepository>().As<IOrderRepository>();

var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

Note: Do this in Global.asaxApplication_Start().

3. Keep Controllers Thin

Same as in Core: controllers only handle HTTP flow — move logic into services.

4. Use ViewModels & DTOs

  • Avoid passing EF entities directly to views or API responses.

  • Use AutoMapper for mapping between domain models and DTOs:

Mapper.Initialize(cfg => cfg.CreateMap<Order, OrderDto>());

5. Centralize Exception Handling

In MVC/Web API, use:

  • Global Filters:
public class GlobalExceptionFilter : IExceptionFilter {
    public void OnException(ExceptionContext filterContext) {
        // log error
        filterContext.Result = new ViewResult { ViewName = "Error" };
        filterContext.ExceptionHandled = true;
    }
}

Register in FilterConfig.cs

6. Keep Configuration Out of Code

  • Use Web.config for settings.

  • For strongly typed configs:

var settingValue = ConfigurationManager.AppSettings["MySetting"];

Or use Settings.settings file for auto-generated config classes.

7. Avoid Magic Strings / Numbers

Same principle:

public static class Roles {
    public const string Admin = "Admin";
}

8. Apply SOLID

Even in .NET Framework — especially important because older projects tend to get “God classes”.

9. Use Filters & Action Attributes

Instead of putting auth/logging/validation code in controllers:

  • AuthorizationFilterAttribute for role-based checks.

  • ActionFilterAttribute for logging and pre/post action hooks.

10. Use EF6 Best Practices

  • Avoid lazy loading unless needed.

  • Use AsNoTracking() for queries that don’t need entity tracking.

  • Keep DB logic in repositories or a dedicated DAL.

11. Unit Testing Without Core’s Built-in DI

  • Mock services using Moq/FakeItEasy.

  • Avoid static dependencies — make them injectable.

12. Keep Global.asax Clean

  • Move route configs to RouteConfig.cs.

  • Bundle/minify in BundleConfig.cs.

  • Register filters in FilterConfig.cs.

  • Only call setup methods in Application_Start().

13. Static Analysis & Style Rules

  • Use FxCop, StyleCop, or ReSharper for code quality.

14. Async in ASP.NET

  • Use async/await in MVC/Web API to free threads for scalability.

public async Task<ActionResult> GetOrders() {
    var orders = await _orderService.GetOrdersAsync();
    return Json(orders, JsonRequestBehavior.AllowGet);
}

15. Document Your APIs

  • For Web API 2, use Swashbuckle for .NET Framework to generate Swagger docs.

Conclusion

Here we tried to cover Best practice to make your project cleaner in .NET