IConfiguration vs IOptions NET
Synchronous and Asynchronous in .NET Core
Model Binding and Validation in ASP.NET Core
ControllerBase vs Controller in ASP.NET Core
ConfigureServices and Configure methods
IHostedService interface in .NET Core
ASP.NET Core request processing
| API Error Handling Best Practices | Engineering-Practices-NET-Core | |
JIT vs AOT in .NET (Simple Explanation) |
JIT compilation is when the .NET runtime (CLR) converts IL (Intermediate Language) to native machine code at runtime, typically the first time a method is executed. The compiled native code is then reused for subsequent calls.
Key points:
AOT compilation converts IL to native machine code before the application runs (during build/publish). .NET supports partial AOT via ReadyToRun (R2R) and full Native AOT (available in recent .NET versions).
Key points:
| Feature | JIT (Just-in-Time) | AOT (Ahead-of-Time) |
|---|---|---|
| Compilation Time | At runtime, when methods are invoked | At build time, before deployment |
| Execution Model | IL code compiled to native code on demand | IL code precompiled to native code during publish |
| Startup Performance | Slower due to runtime compilation | Faster due to precompiled binaries |
| Optimization Strategy | Dynamic PGO, tiered compilation (Tier 0 → Tier 1) | Static PGO, limited runtime feedback |
| Use Case | Long-running apps (e.g., web servers) | Short-lived apps (e.g., CLI tools, serverless) |
| Tooling | Default behavior in .NET Core | Enabled via PublishAot or NativeAOT |
| Portability | Requires .NET runtime on target system | Can produce self-contained native binaries |
| Binary Size | Smaller IL assemblies | Larger native binaries |
| Error Detection | Errors may surface at runtime | Compile-time validation of code paths |
| Reflection Support | Full support for reflection APIs | Limited or disabled reflection (must be trimmed) |
| Deployment Target | Cross-platform with runtime installed | Optimized for containers, embedded systems |
| Runtime dependencies | Requires .NET runtime (JIT) at runtime | Native AOT can be self-contained (no JIT/runtime required) |
| Best use cases | General apps, development, cross-platform scenarios | Microservices, serverless, low-latency apps, single-file deployments |
Default build (JIT at runtime):
dotnet build -c Release dotnet bin/Release/netX.X/YourApp.dll
ReadyToRun (partial AOT):
dotnet publish -c Release -r linux-x64 -p:PublishReadyToRun=true # replace runtime identifier (RID) with your platform, e.g. win-x64, osx-arm64
Native AOT (full AOT, .NET 7+ / 8+):
dotnet publish -c Release -r linux-x64 -p:PublishAot=true # this produces a native executable for the specified RID
JIT: flexible, smaller binaries, CPU-specific runtime optimizations — but slower cold starts.
AOT: faster startup and lower runtime footprint — but larger binaries, platform-specific, and
certain dynamic features (heavy reflection, runtime code generation) may need extra handling.
Use JIT for development and general-purpose cross-platform apps. Use ReadyToRun to speed startup while keeping some portability. Use Native AOT for scenarios where cold-start latency, small runtime footprint, or single-file native distribution are critical (microservices, serverless).
| API Error Handling Best Practices | Engineering-Practices-NET-Core | |