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:

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

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

5. Centralize Exception Handling

In MVC/Web API, use:

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

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:

10. Use EF6 Best Practices

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

12. Keep Global.asax Clean

13. Static Analysis & Style Rules

14. Async in ASP.NET

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

15. Document Your APIs

Conclusion

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