Key .NET Concepts vs. Spring (The “Next Level”)

1. Middleware Pipeline vs. Spring Security Filter Chain

  • Spring: Uses a heavy servlet-based filter chain and Spring Security configurations where you override WebSecurityConfigurerAdapter (or modern component-based security chains).

  • .NET: Uses a linear Middleware Pipeline built directly into HTTP request handling via app.Use(...) extensions. Every piece of request processing—authentication, static files, routing, exception handling—is explicitly stacked as a onion-like layer in Program.cs.

2. Entity Framework (EF Core) vs. Hibernate / JPA

  • Spring/JPA: Relies heavily on annotations (@Entity, @Table, @ManyToOne) and proxy objects to handle state, dirty tracking, and lazy loading under Hibernate.

  • .NET (EF Core): Uses code-first mapping via a DbContext and LINQ (Language Integrated Query). Unlike Java streams, LINQ translates directly into expression trees that execute heavily optimized SQL natively at the database level.

3. Async/Await Model

  • Spring: Traditionally built on blocking I/O (though Spring WebFlux brought reactive programming via Project Reactor).

  • .NET: Built from the ground up to be Asynchronous by default. The async/await pattern propagates from the controller all the way down to the database driver (async/await tasks), resulting in massive throughput with minimal thread pool starvation.

High-Yield .NET Interview Questions (With Spring Contrasts)

Q1: What is a “Captive Dependency” in .NET, and how does the container prevent it?

  • The Trap: Trying to answer with a generic definition of dependency injection.

  • The Answer: A captive dependency happens when a longer-lived service (like a Singleton) holds a reference to a shorter-lived service (like a Scoped database context). In .NET, if a singleton captures a scoped service, that scoped service is inadvertently trapped in memory forever, bypassing its per-request lifecycle and causing massive concurrency bugs.

  • How .NET handles it: ASP.NET Core has a built-in scope validation mechanism. In development mode, the DI container throws an explicit exception on startup if it detects a singleton depending on a scoped service. (Spring behaves more implicitly here, which often hides the bug until production).

Q2: How does middleware execution order affect your application?

  • The Trap: Thinking order doesn’t matter as long as services are registered.

  • The Answer: In .NET, because the HTTP pipeline is processed sequentially via delegates (RequestDelegate), order is everything. For example, if you place app.UseAuthorization() before app.UseAuthentication(), your authorization middleware will run before the user’s identity has even been established, breaking your security flow.

Q3: What is the difference between AddTransient, AddScoped, and AddSingleton, and how do they map to Spring scopes?

  • Transient: A new instance is created every single time it is requested anywhere. (Similar to Spring’s prototype).
  • Scoped: One instance is created per HTTP request. (Closest to Spring’s HTTP request-bound scopes).
  • Singleton: One instance is created the very first time and shared across the entire application lifecycle. (Identical to Spring’s default singleton).

Q4: Why does .NET discourage Field Injection (@Autowired equivalents), unlike Spring?

  • The Answer: .NET heavily enforces Constructor Injection to ensure compile-time safety and immutability. If a class requires dependencies to function, making them private readonly fields set via the constructor guarantees the object can never exist in an invalid, half-initialized state. Field injection relies on post-construction reflection manipulation, which hides dependencies and makes unit testing much harder without container bootstrapping.