Tuesday, 10 February 2026

Real-Time Web Applications using SignalR

Leave a Comment

 Request-and-response communication is no longer the only communication method used by contemporary web apps. These days, users anticipate real-time dashboards, chat capabilities, live notifications, and quick changes. An ASP.NET Core package called SignalR makes it easier to incorporate real-time capabilities into online apps.

Without requiring clients to query the server frequently, SignalR allows server-side code to instantaneously push content to connected clients. It automatically selects the optimal transport by abstracting sophisticated real-time communication strategies like WebSockets, Server-Sent Events, and Long Polling.

The client submits a request and awaits a response in conventional web apps. The client must resubmit the request if the server's data changes. By enabling the server to proactively broadcast updates to all connected clients or to individual users, SignalR reverses this flow.

Live chat apps, stock price updates, live dashboards, notification systems, multiplayer games, and teamwork tools are a few examples of real-time use cases.

The Hub is the central component of SignalR. A hub is a high-level pipeline that enables method calls between the client and server.

Creating a SignalR Hub

using Microsoft.AspNetCore.SignalR;

public class NotificationHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
C#

This hub exposes a method, SendMessage, that clients can call. The server then broadcasts the message to all connected clients using Clients.All.

Registering SignalR in Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSignalR();

var app = builder.Build();

app.MapHub<NotificationHub>("/notificationHub");

app.Run();
C#

Here, SignalR services are registered and the hub is mapped to a specific endpoint. Clients will connect to /notificationHub.

Client-Side JavaScript Integration

<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/7.0.5/signalr.min.js"></script>

<script>
    const connection = new signalR.HubConnectionBuilder()
        .withUrl("/notificationHub")
        .build();

    connection.on("ReceiveMessage", function (user, message) {
        const msg = user + ": " + message;
        document.getElementById("messages").innerHTML += "<li>" + msg + "</li>";
    });

    connection.start();

    function sendMessage() {
        const user = document.getElementById("user").value;
        const message = document.getElementById("message").value;
        connection.invoke("SendMessage", user, message);
    }
</script>
HTML

This client code establishes a real-time connection with the SignalR hub. When the server sends a message using ReceiveMessage, the client immediately updates the UI without refreshing the page.

HTML UI Example

<input id="user" placeholder="User name" />
<input id="message" placeholder="Message" />
<button onclick="sendMessage()">Send</button>

<ul id="messages"></ul>
HTML

Once connected, multiple users can open the page and see messages appear instantly when someone sends a message.

SignalR supports multiple communication patterns. Broadcasting sends messages to all connected clients, while targeted messaging can send data to specific users, groups, or connections. Group messaging is especially useful for chat rooms, notifications by role, or department-based updates.

Another powerful feature of SignalR is automatic reconnection. If the connection drops due to network issues, SignalR can reconnect clients seamlessly, improving reliability.

SignalR also integrates well with authentication and authorization. You can restrict hub access using policies or roles, making it secure for enterprise applications.

Creating a SignalR Hub

using Microsoft.AspNetCore.SignalR;

public class NotificationHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
C#

This hub exposes a method, SendMessage, that clients can call. The server then broadcasts the message to all connected clients using Clients.All.

Registering SignalR in Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSignalR();

var app = builder.Build();

app.MapHub<NotificationHub>("/notificationHub");

app.Run();
C#

Here, SignalR services are registered and the hub is mapped to a specific endpoint. Clients will connect to /notificationHub.

Client-Side JavaScript Integration

<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/7.0.5/signalr.min.js"></script>

<script>
    const connection = new signalR.HubConnectionBuilder()
        .withUrl("/notificationHub")
        .build();

    connection.on("ReceiveMessage", function (user, message) {
        const msg = user + ": " + message;
        document.getElementById("messages").innerHTML += "<li>" + msg + "</li>";
    });

    connection.start();

    function sendMessage() {
        const user = document.getElementById("user").value;
        const message = document.getElementById("message").value;
        connection.invoke("SendMessage", user, message);
    }
</script>
HTML

This client code establishes a real-time connection with the SignalR hub. When the server sends a message using ReceiveMessage, the client immediately updates the UI without refreshing the page.

HTML UI Example

<input id="user" placeholder="User name" />
<input id="message" placeholder="Message" />
<button onclick="sendMessage()">Send</button>

<ul id="messages"></ul>
HTML

Once connected, multiple users can open the page and see messages appear instantly when someone sends a message.

SignalR supports multiple communication patterns. Broadcasting sends messages to all connected clients, while targeted messaging can send data to specific users, groups, or connections. Group messaging is especially useful for chat rooms, notifications by role, or department-based updates.

Another powerful feature of SignalR is automatic reconnection. If the connection drops due to network issues, SignalR can reconnect clients seamlessly, improving reliability.

SignalR also integrates well with authentication and authorization. You can restrict hub access using policies or roles, making it secure for enterprise applications.

In terms of performance, SignalR scales efficiently when combined with backplanes like Redis or Azure SignalR Service, allowing thousands of concurrent connections across multiple servers.

When to use SignalR

  • Live chat systems

  • Real-time notifications

  • Stock market or crypto price updates

  • Live dashboards and monitoring systems

  • Collaborative applications

In conclusion, SignalR dramatically simplifies real-time web development in ASP.NET Core. By abstracting low-level communication details, it allows developers to focus on business logic while delivering fast, interactive, and modern user experiences.

In terms of performance, SignalR scales efficiently when combined with backplanes like Redis or Azure SignalR Service, allowing thousands of concurrent connections across multiple servers.

When to use SignalR

  • Live chat systems

  • Real-time notifications

  • Stock market or crypto price updates

  • Live dashboards and monitoring systems

  • Collaborative applications

In conclusion, SignalR dramatically simplifies real-time web development in ASP.NET Core. By abstracting low-level communication details, it allows developers to focus on business logic while delivering fast, interactive, and modern user experiences.

SignalR Hosting Recommendation

One of the most important things when choosing a good SignalR Hosting is the feature and reliability. HostForLIFE is the leading provider of Windows hosting and affordable SignalR Hosting, their servers are optimized for PHP web applications. The performance and the uptime of the hosting service are excellent and the features of the web hosting plan are even greater than what many hosting providers ask you to pay for. 

At HostForLIFE.eu, customers can also experience fast SignalR hosting. The company invested a lot of money to ensure the best and fastest performance of the datacenters, servers, network and other facilities. Its datacenters are equipped with the top equipments like cooling system, fire detection, high speed Internet connection, and so on. That is why HostForLIFE guarantees 99.9% uptime for SignalR Hosting. And the engineers do regular maintenance and monitoring works to assure its SignalR hosting are security and always up.

Read More...

Tuesday, 3 February 2026

Blazor Server with PostgreSQL Connection: A Useful Guide

Leave a Comment

 Step 1: Setting Up PostgreSQL

  • Install PostgreSQL locally or use a Docker container.

  • Create a database, e.g., BlazorDb.

  • Example command to create a database:

CREATE DATABASE "BlazorDb";
CREATE TABLE Products (
    Id SERIAL PRIMARY KEY,
    Name VARCHAR(100),
    Price DECIMAL
);

Step 2: Create Blazor Server Project and Add required NuGet packages:

dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Microsoft.EntityFrameworkCore.Design
Step 3: Configure EF Core for PostgreSQL
  • Create a Models folder with Product.cs:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Create AppDbContext.cs in Data folder:

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
    public DbSet<Product> Products { get; set; }
}

Configure Program.cs for PostgreSQL:

using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

var app = builder.Build();

Add connection string in appsettings.json:

"ConnectionStrings": {
  "DefaultConnection": "Host=localhost;Database=BlazorDb;Username=postgres;Password=yourpassword"
}

Step 4: Run Migrations

dotnet ef migrations add InitialCreate
dotnet ef database update

EF Core will create tables automatically in PostgreSQL.

Step 5: CRUD Operations in Blazor

Inject AppDbContext into a Blazor component, e.g., Pages/Products.razor:

@page "/products"
@inject AppDbContext _context

<h3>Products</h3>

<ul>
    @foreach (var product in products)
    {
        <li>@product.Name - [email protected]</li>
    }
</ul>

@code {
    private List<Product> products;

    protected override async Task OnInitializedAsync()
    {
        products = await _context.Products.ToListAsync();
    }
}

You can extend with Add/Edit/Delete functionality with forms and buttons.

Step 6: Tips & Best Practices

  • Always use async EF Core methods in Blazor to avoid blocking the UI.

  • Use Dependency Injection for DbContext.

  • Consider connection pooling for production apps.

  • Avoid exposing sensitive credentials — use secrets.json or environment variables.

Conclusion

  • You now have a Blazor Server app talking to PostgreSQL.

  • Can extend with authentication, advanced queries, stored procedures, etc.

  • PostgreSQL + Blazor is perfect for modern enterprise apps with .NET Core. 

Best ASP.NET Core 10.0 Hosting Recommendation 

One of the most important things when choosing a good ASP.NET Core 9 hosting is the feature and reliability. HostForLIFE is the leading provider of Windows hosting and affordable ASP.NET Core, their servers are optimized for PHP web applications. The performance and the uptime of the hosting service are excellent and the features of the web hosting plan are even greater than what many hosting providers ask you to pay for. At HostForLIFE, customers can also experience fast ASP.NET Core hosting. The company invested a lot of money to ensure the best and fastest performance of the datacenters, servers, network and other facilities. Its data centers are equipped with the top equipments like cooling system, fire detection, high speed Internet connection, and so on. That is why HostForLIFE guarantees 99.9% uptime for ASP.NET Core. And the engineers do regular maintenance and monitoring works to assure its Orchard hosting are security and always up. 

Read More...

Tuesday, 27 January 2026

Task Parallel Library (TPL) in ASP.NET Core

Leave a Comment

The goal of ASP.NET Core is to create scalable, high-performance web applications. Its widespread usage of asynchronous programming is one of the main factors contributing to its efficiency. The Task Parallel Library (TPL) is the core of this programming paradigm.

In ASP.NET Core, the Task Parallel Library (TPL) is a crucial component of request processing and application scalability, offering a uniform solution to write asynchronous and parallel code in.NET.

The function of TPL in ASP.NET Core, its operation, typical usage patterns, and best practices for practical applications are all covered in this article.

Task Parallel Library (TPL): What Is It?
A collection of APIs called the Task Parallel Library (TPL) was added to.NET to make parallel and asynchronous programming easier. The System.Threading.Tasks namespace is where it is mostly found.

Developers use Task objects, which represent asynchronous operations, rather than working directly with threads. Developers can concentrate on application logic since the runtime controls scheduling, execution, and resource usage. 

Why TPL Matters in ASP.NET Core?

ASP.NET Core uses a thread pool–based request handling model. Each incoming HTTP request requires a thread to execute. If that thread is blocked during I/O operations, it cannot serve other requests.

Using TPL correctly helps:

  • Improve application scalability

  • Avoid thread starvation

  • Increase throughput under high load

  • Use server resources efficiently

For these reasons, asynchronous programming using TPL is a best practice in ASP.NET Core.

Asynchronous Programming with async and await

The most common way to use TPL in ASP.NET Core is through the async and await keywords.

Example: Async Controller Action

public async Task<IActionResult> GetUsers()
{
    var users = await _userService.GetUsersAsync();
    return Ok(users);
}

This approach ensures that the thread is released while waiting for I/O operations, such as database or API calls.

Using TPL in Services and Repositories

Asynchronous programming should be implemented consistently across controllers, services, and repositories.

Example: Async Service Method

public async Task<List<User>> GetUsersAsync()
{
    return await _context.Users.ToListAsync();
}

Entity Framework Core provides native asynchronous methods that integrate directly with TPL and should always be preferred.

Executing Multiple Tasks in Parallel

When multiple independent operations need to be executed, TPL allows them to run concurrently using Task.WhenAll.

Example: Parallel Execution of Independent Tasks
public async Task<IActionResult> GetDashboardData()
{
    var usersTask = _userService.GetUsersAsync();
    var ordersTask = _orderService.GetOrdersAsync();

    await Task.WhenAll(usersTask, ordersTask);

    return Ok(new
    {
        Users = usersTask.Result,
        Orders = ordersTask.Result
    });
}

This pattern improves performance by reducing total execution time for independent I/O-bound operations.

Handling CPU-Bound Operations

ASP.NET Core applications are primarily I/O-bound. However, in rare cases, CPU-intensive operations may be required.

For such scenarios, it Task.Run can be used to offload work to a background thread.

await Task.Run(() => PerformComplexCalculation());
Important Notes
  • Use Task.Run sparingly

  • Avoid using it for database or HTTP operations

  • Prefer background services for long-running CPU-bound tasks

Background Processing Using TPL

Long-running tasks should not be executed within controller actions. ASP.NET Core provides BackgroundService for such use cases.

Example: Background Worker
public class EmailBackgroundService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            await SendEmailsAsync();
            await Task.Delay(5000, stoppingToken);
        }
    }
}

This approach ensures proper lifecycle management and graceful shutdown.

Common Mistakes to Avoid

Blocking Asynchronous Code

Avoid blocking asynchronous calls using .Result or .Wait().

var data = GetDataAsync().Result; // Not recommended

Blocking can lead to deadlocks and thread pool exhaustion.

Fire-and-Forget Tasks

Starting tasks without awaiting them inside controllers can result in incomplete operations if the application restarts.

Instead, use background services or message queues.

Using Parallel.For in Web Requests

Parallel.For is intended for CPU-bound workloads and should not be used inside ASP.NET Core controllers.

Best Practices for Using TPL in ASP.NET Core
  • Use async it await consistently

  • Prefer asynchronous APIs provided by libraries

  • Use Task.WhenAll for independent operations

  • Avoid blocking calls

  • Keep controllers lightweight

  • Use background services for long-running tasks

TPL vs Traditional Threading
Traditional ThreadingTask Parallel Library
Manual thread managementManaged by runtime
Blocking executionNon-blocking
Hard to scaleHighly scalable
Error-proneException-safe

Conclusion

The Task Parallel Library plays a crucial role in the architecture of ASP.NET Core applications. By leveraging asynchronous programming and parallel execution correctly, developers can build applications that are scalable, responsive, and efficient.

Understanding and applying TPL best practices is essential for developing modern, high-performance ASP.NET Core applications.

ASP.NET Core 10.0 Hosting Recommendation

One of the most important things when choosing a good ASP.NET Core 10.0 hosting is the feature and reliability. HostForLIFE is the leading provider of Windows hosting and affordable ASP.NET Core, their servers are optimized for PHP web applications. The performance and the uptime of the hosting service are excellent and the features of the web hosting plan are even greater than what many hosting providers ask you to pay for. 

At HostForLIFE.eu, customers can also experience fast ASP.NET Core hosting. The company invested a lot of money to ensure the best and fastest performance of the datacenters, servers, network and other facilities. Its datacenters are equipped with the top equipments like cooling system, fire detection, high speed Internet connection, and so on. That is why HostForLIFE guarantees 99.9% uptime for ASP.NET Core. And the engineers do regular maintenance and monitoring works to assure its Orchard hosting are security and always up.

 

 

Read More...

Thursday, 22 January 2026

Common Dependency Injection Errors in Scrutor and How to Prevent Them

Leave a Comment

Scrutor is an effective addition to the Dependency Injection (DI) container that comes with.NET. Without taking the place of the default DI system, it makes assembly scanning, convention-based registration, and decorator support possible. Scrutor greatly saves boilerplate, but if used carelessly, it also adds indirection that can conceal architectural issues. The majority of Dependency Injection problems encountered in practical applications are not caused by Scrutor per se, but rather by excessively expansive scanning rules, ambiguous lifetimes, or hard-to-understand implicit registrations.



Using real-world, production-focused examples, this article examines the most frequent Dependency Injection errors while using Scrutor and discusses how to avoid them.

1. Over-Scanning Assemblies

The problem

builder.Services.Scan(scan =>
    scan.FromApplicationDependencies()
        .AddClasses()
        .AsImplementedInterfaces()
);

Why does this cause issues

Scanning all application dependencies registers every discoverable class, including framework and third-party types. This makes the DI container unpredictable, slows application startup, and creates behavior that is difficult to debug and reason about.

The correct approach

Scan only assemblies you own and apply strict filters.

builder.Services.Scan(scan =>
    scan.FromAssemblyOf<IApplicationService>()
        .AddClasses(c => c.AssignableTo<IApplicationService>())
        .AsImplementedInterfaces()
        .WithScopedLifetime()
);

Assembly scanning should always be deliberate and narrowly scoped.

2. Accidental Multiple Interface Registrations

The problem

public class UserService :
    IUserService,
    IApplicationService,
    IDisposable
{
}
.AsImplementedInterfaces()

This registers every implemented interface, including interfaces that were never meant to be resolved from the container.

Why this is dangerous

Unintended registrations can override other services and introduce subtle bugs that appear only at runtime.

The correct approach

Be explicit when registering services that implement multiple interfaces.

.AddClasses(c => c.AssignableTo<IApplicationService>())
.As<IUserService>()
.WithScopedLifetime()

Automatic interface registration should be used only when the intent is clear and controlled.

3. Lifetime Mismatch (Captive Dependency)

The problem

services.AddSingleton<ReportService>();
services.AddScoped<AppDbContext>();
public class ReportService
{
    public ReportService(AppDbContext context) { }
}

Why this breaks applications

A singleton capturing a scoped dependency leads to memory leaks, invalid object lifetimes, and runtime exceptions under load.

The correct approach

Align lifetimes so that dependencies live at least as long as their consumers.

services.AddScoped<ReportService>();

Alternatively, use factory abstractions such as IDbContextFactory .

4. Hidden Decorators and Execution Order Confusion

The problem

services.Decorate<IUserService, LoggingUserService>();
services.Decorate<IUserService, CachingUserService>();

What actually happens

The runtime execution order becomes:

Caching -> Logging -> UserService

Why this is confusing

Decorators are invisible at injection sites, and the execution order is not obvious. Changing the registration order can silently alter application behavior.

The correct approach

Register decorators together, document their order, and add constructor logging in development to make resolution explicit.

public LoggingUserService(...)
{
    Console.WriteLine("Logging decorator created");
}

Decorator order should always be intentional.

5. Mixing Manual and Scrutor Registrations

The problem

services.AddScoped<IUserService, UserService>();

services.Scan(scan =>
    scan.FromAssemblyOf<IApplicationService>()
        .AddClasses(c => c.AssignableTo<IApplicationService>())
        .AsImplementedInterfaces()
);

Why this leads to bugs

The .NET DI container follows a last-registration-wins strategy. Mixing manual and scanned registrations makes behavior unpredictable and environment-dependent.

The correct approach

Use one registration strategy per layer. Scrutor is well-suited for application services and repositories, while manual registration should be reserved for infrastructure and framework services.

Consistency is more important than flexibility.

6. Not Validating Dependency Injection at Startup

The problem

Dependency Injection errors surface only at runtime, often under load.

The correct approach

Enable DI validation during application startup.

builder.Host.UseDefaultServiceProvider(options =>
{
    options.ValidateScopes = true;
    options.ValidateOnBuild = true;
});

This configuration catches missing registrations, circular dependencies, and lifetime mismatches early.

7. Business Logic Inside Decorators

The problem

public class AuthorizationDecorator : IUserService
{
    public async Task DeleteUser(int id)
    {
        if (!IsAdmin())
            throw new UnauthorizedAccessException();

        await _inner.DeleteUser(id);
    }
}

Why this is a design flaw

Decorators should not contain business rules. Hiding business logic inside decorators makes behavior harder to understand, test, and maintain.

The correct approach

Decorators should handle technical cross-cutting concerns such as logging, caching, validation, or metrics. Business rules should remain in the core service.

8. Overusing Singleton Services

The problem

services.AddSingleton<UserService>();

Why this causes problems

Singletons introduce shared mutable state, thread-safety issues, and test instability. Many services do not need to live for the entire lifetime of the application.

The correct approach

Default to scoped services unless there is a clear and justified reason to use a singleton.

services.AddScoped<IUserService, UserService>();

Singletons should be rare and stateless.

9. Service Locator Usage in Minimal APIs

The problem

app.MapGet("/users", (IServiceProvider provider) =>
{
    var service = provider.GetRequiredService<IUserService>();
});

Why this is harmful

Manually resolving services hides dependencies and reintroduces the service locator anti-pattern, making the code harder to test and reason about.

The correct approach

Let the framework inject dependencies directly.

app.MapGet("/users", (IUserService service) =>
{
    return service.GetAll();
});
Mental Model to Remember

Scrutor reduces boilerplate, but it also hides complexity. If your DI configuration is difficult to explain, difficult to debug, or behaves differently across environments, your scanning rules are too permissive.

Key Takeaway

Scrutor is not inherently dangerous. Uncontrolled conventions are.

When used with tight assembly scanning, clear lifetimes, explicit intent, and proper validation, Scrutor becomes a powerful tool for building clean, scalable Dependency Injection in .NET.

Happy Coding!

I write about modern C#, .NET, and real-world development practices. Follow me on C# Corner for regular insights, tips, and deep dives.

Best ASP.NET Core 10.0 Hosting Recommendation

One of the most important things when choosing a good ASP.NET Core 8.0 hosting is the feature and reliability. HostForLIFE is the leading provider of Windows hosting and affordable ASP.NET Core, their servers are optimized for PHP web applications. The performance and the uptime of the hosting service are excellent and the features of the web hosting plan are even greater than what many hosting providers ask you to pay for. 

At HostForLIFEASP.NET, customers can also experience fast ASP.NET Core hosting. The company invested a lot of money to ensure the best and fastest performance of the datacenters, servers, network and other facilities. Its datacenters are equipped with the top equipments like cooling system, fire detection, high speed Internet connection, and so on. That is why HostForLIFEASP.NET guarantees 99.9% uptime for ASP.NET Core. And the engineers do regular maintenance and monitoring works to assure its Orchard hosting are security and always up.
Read More...

Monday, 19 January 2026

How to Begin Using Minimal APIs in.NET Core?

Leave a Comment

Microsoft introduced Minimal APIs, a streamlined approach to creating HTTP APIs with fewer boilerplate and a greater emphasis on functionality, with the release of.NET 6. Microservices, lightweight APIs, and quick prototyping are all best served by minimal APIs.


Minimal APIs: What Are They?
Developers can design RESTful services without controllers, starting classes, or complicated configurations thanks to minimal APIs. The Program.cs file contains definitions for everything.

They are:

  • Lightweight

  • Fast to develop

  • Easy to read

  • Perfect for small to medium APIs

Why Minimal APIs?

Traditional Web APIs require:

  • Controllers

  • Attributes

  • Dependency injection setup

  • Multiple files

Minimal APIs reduce this complexity by enabling you to define endpoints directly using lambda expressions.

Benefits:

  • Less boilerplate code

  • Improved performance

  • Easy learning curve

  • Clean and concise syntax

Creating a Minimal API in .NET Core

Step 1: Create a New Project

Use the following command:

dotnet new web -n MinimalApiDemo
Plain text

Open the project in Visual Studio or VS Code.

Step 2: Program.cs Example

Here is a simple Minimal API example:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Welcome to Minimal API!");

app.MapGet("/hello/{name}", (string name) =>
{
    return $"Hello, {name}!";
});

app.Run();
Plain text

Step 3: Run the Application

Run the project and navigate to:

  • https://localhost:5001/

  • https://localhost:5001/hello/John

HTTP Methods in Minimal APIs

app.MapGet("/users", () => "Get all users");

app.MapPost("/users", (User user) => $"User {user.Name} created");

app.MapPut("/users/{id}", (int id, User user) =>
    $"User {id} updated");

app.MapDelete("/users/{id}", (int id) =>
    $"User {id} deleted");
Plain text

Model Binding Example

public record User(int Id, string Name, string Email);
Plain text

Minimal APIs automatically bind request data to models.

Dependency Injection in Minimal APIs

builder.Services.AddScoped<IUserService, UserService>();

app.MapGet("/service", (IUserService service) =>
{
    return service.GetMessage();
});
Plain text

When Should You Use Minimal APIs?

  • Microservices

  • Lightweight REST APIs

  • Prototypes & PoCs

  • Serverless applications

Not ideal for very large, complex enterprise applications

Minimal APIs vs Controller-Based APIs

FeatureMinimal APIsController APIs
BoilerplateVery LowHigh
Learning CurveEasyModerate
PerformanceHighGood
StructureFlatLayered

Conclusion

A contemporary, tidy, and effective method of creating APIs in.NET is using minimal APIs. They preserve power and flexibility while lowering complexity. Minimal APIs are a great option if your application doesn't need complex architecture.

Read More...

Tuesday, 13 January 2026

Learning FastEndpoints in ASP.NET

Leave a Comment

In the evolution of ASP.NET Core, we have moved from the rigid structure of MVC (Model-View-Controller) to the streamlined simplicity of Minimal APIs. However, as applications grow, Minimal APIs can become disorganized, and Controllers often suffer from “bloat”—violating the Single Responsibility Principle.

 

Enter FastEndpoints.

This library is not just another framework; it is a philosophy shift. It wraps the performance of Minimal APIs in a structured, maintainable pattern known as REPR (Request-Endpoint-Response). In this post, we will dive deep into what FastEndpoints is, why it matters, and how to implement it in your .NET projects.

The Problem with Controllers 

Traditionally, .NET developers group logic by resource. A UserController, for example, might handle Get, Create, Update, and Delete operations.

While this looks organized initially, it leads to several issues:

  • Constructor Bloat: A controller injecting dependencies for all its methods means every request instantiates services it might not need.

  • Hidden Coupling: Shared private methods inside a controller create tight coupling between unrelated endpoints (e.g., “Get User” logic bleeding into “Update User”).

  • Violation of SRP: A controller handles many responsibilities, rather than just one.

The Solution: The REPR Pattern 

FastEndpoints implements the REPR pattern, which stands for Request-Endpoint-Response.

Instead of grouping by resource (a Controller), you group by feature (an Endpoint). Each endpoint is a distinct class dedicated to a single purpose (e.g., CreateUserEndpoint, GetUserEndpoint).

The Components

  1. Request: A DTO (Data Transfer Object) defining what the client sends.

  2. Endpoint: A class containing the logic for only that specific request.

  3. Response: A DTO defining what the server returns.

Getting Started with FastEndpoints 

Let’s look at how to implement a simple “Create User” feature using FastEndpoints in .NET 8.

  1. Installation

First, install the necessary package via the NuGet Package Manager or CLI:

dotnet add package FastEndpoints
  1. Configuration

In your Program.cs, register and enable FastEndpoints. It sits on top of the existing ASP.NET Core pipeline, so it integrates seamlessly.

using FastEndpoints;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFastEndpoints(); // Register services
var app = builder.Build();
app.UseFastEndpoints(); // Register middleware
app.Run();
  1. Defining the Endpoint

Here is where the magic happens. Instead of a method inside a controller, we define a class.

The DTOs:

public class CreateUserRequest
{
    public string FirstName { get; set; } = default!;
    public string LastName { get; set; } = default!;
    public string Email { get; set; } = default!;
}
public class CreateUserResponse
{
    public string FullName { get; set; } = default!;
    public string Message { get; set; } = default!;
}

 The Endpoint:

using FastEndpoints;
public class CreateUserEndpoint : Endpoint<CreateUserRequest, CreateUserResponse>
{
    public override void Configure()
    {
        Post("/api/users/create");
        AllowAnonymous();
    }
    public override async Task HandleAsync(CreateUserRequest req, CancellationToken ct)
    {
        // Simulate database logic
        var fullName = $"{req.FirstName} {req.LastName}";
        // Send the response
        await SendAsync(new CreateUserResponse
        {
            FullName = fullName,
            Message = "User created successfully!"
        }, cancellation: ct);
    }
}

Breakdown of the Code

  • Inheritance: The class inherits from Endpoint<TRequest, TResponse>, providing strict typing immediately.

  • Configure(): This replaces route attributes ([HttpPost], [Route]). You define the configuration imperatively, which is often cleaner and more discoverable.

  • HandleAsync(): This contains your business logic. It takes the strongly-typed Request object and a CancellationToken automatically.

Key Features & Benefits

1. Built-in Validation

FastEndpoints integrates heavily with FluentValidation. You don’t need to manually check ModelState.IsValid. You simply define a validator, and the library handles the 400 Bad Request response automatically if validation fails.

public class CreateUserValidator : Validator<CreateUserRequest>
{
    public CreateUserValidator()
    {
        RuleFor(x => x.Email).NotEmpty().EmailAddress();
        RuleFor(x => x.FirstName).NotEmpty().MinimumLength(3);
    }
}
2. Vertical Slice Architecture

By forcing you to create a file per endpoint, FastEndpoints naturally pushes your project toward Vertical Slice Architecture. All files related to a feature (the Endpoint, the Request/Response DTOs, the Validator, and the Mapper) can live in a single folder. This makes navigating code significantly easier than jumping between Controllers/, Models/, and Services/ folders.

3. Performance

Because FastEndpoints is a wrapper around ASP.NET Core’s Minimal APIs, it is extremely performant—significantly faster than traditional MVC Controllers and effectively on par with raw Minimal APIs. It builds the expression trees for mapping and validation at startup, ensuring runtime speed is maximized.

Conclusion

FastEndpoints offers the “sweet spot” for modern .NET API development. It provides the structure that Minimal APIs lack and removes the bloat that Controllers impose. If you are looking to build maintainable, high-performance, and type-safe APIs, adopting the REPR pattern with FastEndpoints is a powerful choice.

Happy Coding !!!

ASP.NET Core 10.0 Hosting Recommendation

One of the most important things when choosing a good ASP.NET Core 10.0 hosting is the feature and reliability. HostForLIFE is the leading provider of Windows hosting and affordable ASP.NET Core, their servers are optimized for PHP web applications. The performance and the uptime of the hosting service are excellent and the features of the web hosting plan are even greater than what many hosting providers ask you to pay for. 

At HostForLIFE.eu, customers can also experience fast ASP.NET Core hosting. The company invested a lot of money to ensure the best and fastest performance of the datacenters, servers, network and other facilities. Its datacenters are equipped with the top equipments like cooling system, fire detection, high speed Internet connection, and so on. That is why HostForLIFE.eu guarantees 99.9% uptime for ASP.NET Core. And the engineers do regular maintenance and monitoring works to assure its Orchard hosting are security and always up.

 
Read More...