System.Text.Json is fast but MemoryPack uses binary format for extreme performance. Install: dotnet add package MemoryPack Define Serializable Type: [MemoryPackable] public partial class User { public int Id { get; set; } public string Name { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; public DateTime CreatedAt { get; […]
Tag: .NET Tips
C#: Use ObjectPool for Reusing Expensive Objects
Creating and destroying heavy objects (StringBuilder, MemoryStream) repeatedly wastes memory. ObjectPool reuses them. Install: dotnet add package Microsoft.Extensions.ObjectPool Setup: // Program.cs builder.Services.AddSingleton(); builder.Services.AddSingleton(sp => { var provider = sp.GetRequiredService(); return provider.CreateStringBuilderPool(); }); Use in Service: public class TextService(ObjectPool pool) { public string BuildLargeText(IEnumerable items) { // Get StringBuilder from pool (reuse, no new allocation) var […]
.NET Core: Use Result Pattern to Avoid Exceptions for Expected Errors
Throwing exceptions for business logic (user not found, invalid input) is expensive. Result pattern is cleaner and faster. Define Result Type: public class Result { public T? Value { get; } public string? Error { get; } public bool IsSuccess { get; } private Result(T value) { Value = value; IsSuccess = true; } private […]
.NET Core: Use IOptions Pattern for Strongly-Typed Configuration
Reading config with magic strings breaks on typos. IOptions pattern gives strongly-typed, validated config. Define Config Class: public class EmailSettings { public string SmtpHost { get; set; } = string.Empty; public int SmtpPort { get; set; } public string Username { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; […]
.NET Core: Use Polly for Resilient HTTP Requests with Retry Logic
Network failures happen. Polly adds retry, circuit breaker, and timeout policies automatically. Install: dotnet add package Polly dotnet add package Microsoft.Extensions.Http.Polly Add to HttpClient: // Program.cs builder.Services.AddHttpClient(“MyAPI”, client => { client.BaseAddress = new Uri(“https://api.example.com”); }) .AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt))) ) .AddTransientHttpErrorPolicy(policy => policy.CircuitBreakerAsync(5, TimeSpan.FromMinutes(1)) ); Usage: public class MyService { private readonly […]
.NET Core: Use Dapper for Lightweight ORM Alternative to Entity Framework
Entity Framework too heavy for simple queries? Dapper is micro-ORM with near-raw SQL performance. Install: dotnet add package Dapper Basic Usage: using Dapper; using System.Data.SqlClient; var connection = new SqlConnection(connectionString); // Query (returns list) var users = connection.Query( “SELECT * FROM Users WHERE Age > @MinAge”, new { MinAge = 18 } ).ToList(); // Single […]
.NET Core: Use Rate Limiting to Prevent API Abuse
APIs getting hammered with requests? .NET 7+ has built-in rate limiting middleware. Setup: // Program.cs builder.Services.AddRateLimiter(options => { options.AddFixedWindowLimiter(“fixed”, opt => { opt.Window = TimeSpan.FromMinutes(1); opt.PermitLimit = 100; // 100 requests per minute opt.QueueLimit = 0; }); }); var app = builder.Build(); app.UseRateLimiter(); Apply to Endpoints: app.MapGet(“/api/data”, () => “Data”) .RequireRateLimiting(“fixed”); // If user exceeds […]
.NET Core: Use Health Checks to Monitor Application Status
Need to know if your app is healthy? Health checks provide monitoring endpoints automatically. Setup: // Program.cs builder.Services.AddHealthChecks() .AddDbContextCheck() // Check database .AddUrlGroup(new Uri(“https://api.example.com”), “External API”); // Check external dependency var app = builder.Build(); app.MapHealthChecks(“/health”); Test: curl http://localhost:5000/health # Healthy response: 200 OK # Unhealthy: 503 Service Unavailable Custom Health Check: public class MemoryHealthCheck : […]
.NET Core: Use Output Caching to Cache Entire HTTP Responses
Response caching at application level is slow. Output caching caches at server level for max speed. Enable (.NET 7+): // Program.cs builder.Services.AddOutputCache(); var app = builder.Build(); app.UseOutputCache(); Use on Endpoints: app.MapGet(“/products”, async (IProductService service) => { return await service.GetAllProductsAsync(); }) .CacheOutput(policy => policy.Expire(TimeSpan.FromMinutes(5))); // First request: 50ms (database query) // Next requests: 0.5ms (from cache) […]
.NET Core: Use ILogger with Scopes for Better Log Context
Logs without context are hard to trace. Scopes add contextual information to all logs within a scope. Basic Logging: _logger.LogInformation(“Processing order”); _logger.LogInformation(“Payment completed”); // Hard to know which order in production logs With Scopes: using (_logger.BeginScope(“OrderId:{OrderId}, UserId:{UserId}”, orderId, userId)) { _logger.LogInformation(“Processing order”); _logger.LogInformation(“Payment completed”); _logger.LogInformation(“Email sent”); } // All logs include: OrderId:12345, UserId:67890 // Easy […]
.NET Core: Use BackgroundService for Long-Running Tasks
Need background job in your ASP.NET app? BackgroundService is built-in – no Hangfire or Quartz needed. Create Background Service: public class EmailCleanupService : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // Do work await CleanupOldEmails(); // Wait 1 hour await Task.Delay(TimeSpan.FromHours(1), stoppingToken); } } private async Task CleanupOldEmails() { // […]
.NET Core: Use IConfiguration.GetValue for Type-Safe Config Reading
Parsing config strings manually is error-prone. GetValue handles conversion automatically. Manual Parsing (Error-Prone): // appsettings.json: “MaxRetries”: “3” var maxRetries = int.Parse(_config[“MaxRetries”]); // NullReferenceException if key missing! // FormatException if value is not a number! Type-Safe GetValue: var maxRetries = _config.GetValue(“MaxRetries”, defaultValue: 5); // Returns 3 if exists // Returns 5 if missing or invalid // […]
.NET Core: Use Required Modifier to Force Property Initialization
Tired of null reference exceptions because someone forgot to set a property? Make it required. Old Problem: public class User { public string Name { get; set; } // Can be null! public string Email { get; set; } // Can be null! } var user = new User(); // Compiles fine Console.WriteLine(user.Name.Length); // NullReferenceException! […]
.NET Core: Use Global Using Directives to Avoid Repeating Imports
Typing the same using statements in every file? Declare them globally once. Create GlobalUsings.cs: // GlobalUsings.cs global using System; global using System.Collections.Generic; global using System.Linq; global using System.Threading.Tasks; global using Microsoft.EntityFrameworkCore; Now these namespaces are available in ALL files automatically! Your Other Files: // ProductService.cs // No using statements needed! public class ProductService { private […]
.NET Core: Use Top-Level Statements to Skip Program Class Boilerplate
Don’t need Program class and Main method for simple apps. Write code directly. Old Way: namespace MyApp { class Program { static void Main(string[] args) { Console.WriteLine(“Hello World”); } } } New Way (.NET 6+): Console.WriteLine(“Hello World”); That’s your entire Program.cs file! Compiler generates the boilerplate. Can Still Use Services: var builder = WebApplication.CreateBuilder(args); var […]
.NET Core: Use Minimal APIs to Create Lightweight Endpoints Without Controllers
Creating a controller, action method, and routing just to return simple JSON? Minimal APIs in .NET 6+ let you define endpoints in 3 lines. Traditional Controller Way: [ApiController] [Route(“api/[controller]”)] public class ProductsController : ControllerBase { private readonly IProductService _productService; public ProductsController(IProductService productService) { _productService = productService; } [HttpGet] public async Task GetAll() { var products […]
.NET Core: Use IMemoryCache for Lightning-Fast Data Access Without Redis
Hitting database for same data 1000 times per second? IMemoryCache stores frequently-accessed data in RAM for instant access. Setup: // Program.cs or Startup.cs builder.Services.AddMemoryCache(); Basic Usage: public class ProductService { private readonly IMemoryCache _cache; private readonly ApplicationDbContext _db; public ProductService(IMemoryCache cache, ApplicationDbContext db) { _cache = cache; _db = db; } public async Task GetProductAsync(int […]
















