European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET Core 9.0 Hosting - HostForLIFE :: Create Sturdy Middleware in.NET: Circuit Breaker and Retry Using Polly v8

clock July 16, 2025 09:23 by author Peter

Applications commonly depend on external databases, services, and APIs to operate in today's distributed systems and microservices architecture. High traffic, network problems, or temporary difficulties can cause certain dependencies to fail. It is our responsibility as developers to build apps that can gracefully handle such failures. Resilience patterns can help with that. We will use the most recent Polly v8 coupled with Microsoft to construct middleware for Retry and Circuit Breaker in this blog. extensions. tenacity.

When should I use a circuit breaker? What is its pattern?
Modern applications employ the Circuit Breaker design pattern to avoid invoking a service or function that is prone to malfunction. Consider it analogous to your home's electric circuit breaker, which trips and cuts off the electrical supply in the event of an overload to guard against harm. In software, a circuit breaker momentarily halts calls to a malfunctioning service in order to prevent further overloading it.

When Should You Use It?

  • When an external service is known to fail frequently.
  • When you want to fail fast instead of waiting for timeouts.
  • To prevent cascading failures in microservices.
  • To improve overall system responsiveness and stability.

Circuit Breaker Flow

What is Polly?
Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback. Polly has been widely adopted in the .NET community, and with Polly v8, Microsoft has introduced deep integration into the Microsoft.Extensions ecosystem through the new Microsoft.Extensions.Resilience package.

Polly with Microsoft.Extensions.Resilience
In Polly v8, resilience is more declarative and integrated into .NET’s dependency injection and configuration model. This makes it easier to build policies that are environment-aware and configurable. Let’s start building our retry and circuit breaker middleware using the latest packages.

Step 1. Set Up Your Project

Create a new web API project in Visual Studio, or if you are using Visual Studio Code, you can execute the following commands.
mkdir PollyResilienceApp
cd PollyResilienceApp
dotnet new PollyV8RetryDemo


Post that adds below the NuGet package
# In case of Visual Studio Code
dotnet add package Microsoft.Extensions.Resilience

# In case of Visual Studio Package Manager Console
NuGet\Install-Package Microsoft.Extensions.Resilience

Step 2. Configure Resilience Policies in the Program.cs
Open the Program.cs file and add the required namespace and Poly service to place it in the middleware. Below is the snippet of Program.cs file with service.
// namespaces
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Resilience;

var builder = WebApplication.CreateBuilder(args);

// add service
builder.Services.AddResiliencePipeline("standard-pipeline", pipelineBuilder =>
{
    // add retry configurations
    pipelineBuilder.AddRetry(new RetryStrategyOptions
    {
        MaxRetryAttempts = 3,  // -> this should be from appSettings.json
        Delay = TimeSpan.FromMilliseconds(500), // -> this should be from appSettings.json
        BackoffType = DelayBackoffType.Exponential
    });

    // set the circuit breaker pattern
    // configuration numbers should be driven from appSettings.json
    pipelineBuilder.AddCircuitBreaker(new CircuitBreakerStrategyOptions
    {
        FailureRatio = 0.5,  // -> this should be from appSettings.json
        SamplingDuration = TimeSpan.FromSeconds(30),
        MinimumThroughput = 10,
        BreakDuration = TimeSpan.FromSeconds(15)
    });
});

var app = builder.Build();

app.MapControllers();

app.Run();


Step 3. Inject and Use the Policy in a Controller
Once you set the service in the program.cs, it is time to inject the same in the Controllers. Below is an example of a sample controller where ResiliencePipelineProvider has been injected to execute
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Resilience;

[ApiController]
[Route("api/[controller]")]
public class MyAPIController : ControllerBase
{
    private readonly ResiliencePipelineProvider<string> _pipelineProvider;

    public MyAPIController(ResiliencePipelineProvider<string> pipelineProvider)
    {
        _pipelineProvider = pipelineProvider;
    }

    [HttpGet("execute")]
    public async Task<IActionResult> Execute_v1()
    {
        var pipeline = _pipelineProvider.GetPipeline("standard-pipeline");

        try
        {
            var result = await pipeline.ExecuteAsync(async token =>
            {
                // Actual operations goes here
                // For test, can place an sleep command
                // await Task.Delay(100);
                throw new HttpRequestException("Failure");
            });

            return Ok(result);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Operation failed: {ex.Message}");
        }
    }
}

How Polly Helps Achieve the Circuit Breaker Pattern?
Polly allows you to plug in the circuit breaker logic without cluttering your business code. The resilience pipeline acts as a middleware that surrounds your code, monitoring failures, retries, and triggering breaks when needed.

With Polly, you get:

  • Observability: You can plug in logging and metrics easily.
  • Composability: You can combine Retry + Circuit Breaker + Timeout.
  • Declarative configuration: Adjust thresholds without touching the logic.

The diagram below explains how the request is flowing.

While all the retry actions are executing by Polly, logs can be done through the Logging Service. To enable the same, add the following code snippet in Program.cs. Appenders can be used based on the project needs.
builder.Services.AddLogging();

Conclusion
By integrating Polly v8 with Microsoft.Extensions.Resilience, you can build reliable, maintainable, and production-ready applications in .NET. Using the Retry and Circuit Breaker patterns, you shield your applications from transient errors and cascading failures.

If you’re building services at scale or working in a microservices environment, implementing these patterns is not just a good-to-have but a necessity.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: MediatR Library Modern in.NET Core 9.0

clock July 11, 2025 08:29 by author Peter

MediatR
The application's package message dispatcher is called MediatR. Commands, queries, and handlers are examples of requests and answers that can be implemented with its help. Additionally, MediatR supports a variety of architectural patterns in contemporary.NET and.NET Core apps and permits the delivery of messages. It’s introduced as a .NET Standard library, starting from .NET Core 2.0, 3.1, and till supports the latest .NET 9.0. Additionally, it is a robust, open-source framework for.NET applications that implements the Mediator paradigm. Below is a list of architectures that support mediatR.

Clean Architecture: Well-suited for decoupling the application layers from presentation and infrastructure layers. Clean Architecture is used to keep business logic isolated.
CQRS (Command Query Responsibility Segregation): CQRS  is fit for handling separate write and read operations (commands and queries) in request/responses APIs.
DDD (Domain-Driven Design): This is suitable for loosely coupling applications that can be created with domain events and services.
Event-Driven Architecture: it supports publishing and handling events using INotification and INotificationHandler<T>
Test-Driven Development (TDD): This architecture Handlers are easy to unit test, it's isolated from controllers and infrastructure.

MediatR Features in .NET 9 Core

  • .NET 9.0 minimal API and modular project structure enhancements in a better way
  • Dynamic Database support provided for using the Entity Framework (SQL Server, PostgreSQL, MySQL, SQLite)
  • Better developer experience in lightweight, testable service layers.
  • MediatR is used for implementing CQRS and a separate layer like Application, Domain, and infrastructure.
  • Event handling is improved with built-in support for Server-Sent Events (SSE), 

Advantages of MediatR in the latest version of .NET

  • Testability improved; unit test handlers are easy and isolated
  • Good for large applications that maintain many modules and features
  • Logging, Validation, and Caching are supported in Pipeline behaviours
  • Efficient for real-time applications and event-driven applications, and streaming API like OpenAI’s

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 10.0 Hosting - HostForLIFE :: SOLID Principles: A Comprehensive Guide to Practical.NET Projects

clock July 8, 2025 08:24 by author Peter

Single Responsibility Principle (SRP)
// One class = One job

Every class should have only one reason to change. This means no mixing database logic with business logic or API response formatting with validation rules.

Real-World .NET Example
// Bad: Doing too much
public class UserManager
{
    public void Register(User user) { /* logic */ }
    public void SaveToDb(User user) { /* DB logic */ }
    public void SendWelcomeEmail(User user) { /* Email logic */ }
}
// Good: SRP Applied
public class UserService
{
    public void Register(UserDto dto) { /* business rules */ }
}
public class UserRepository
{
    public void Save(User user) { /* DB only */ }
}
public class EmailSender
{
    public void SendWelcomeEmail(User user) { /* Email only */ }
}

Open/Closed Principle (OCP)
Open for extension, closed for modification

Your code should allow new behavior without changing existing code. This avoids regressions and makes it easier to add future features.

Real-World Example
public interface IDiscountStrategy
{
    decimal ApplyDiscount(decimal price);
}
public class HolidayDiscount : IDiscountStrategy
{
    public decimal ApplyDiscount(decimal price) => price * 0.9m;
}
public class NoDiscount : IDiscountStrategy
{
    public decimal ApplyDiscount(decimal price) => price;
}

By injecting IDiscountStrategy, you can add new discounts without changing your OrderService.

Liskov Substitution Principle (LSP)
Subtypes must be substitutable for their base types

Any derived class should be replaceable for its parent without breaking functionality.

Anti-Pattern
public class Rectangle
{
    public virtual void SetWidth(int width) { }
}
public class Square : Rectangle
{
    public override void SetWidth(int width)
    {
        throw new NotImplementedException(); // LSP Violation
    }
}

Instead, design with interfaces or composition when inheritance breaks behavior.

Interface Segregation Principle (ISP)
Keep interfaces small and focused

Clients shouldn't be forced to implement methods they don’t use. This avoids bloated and confusing code.

Better Design
public interface ILoginService
{
    void Login(string user, string password);
}
public interface IRegistrationService
{
    void Register(UserDto dto);
}

Instead of forcing everything into a single IUserService, split interfaces by responsibility.

Dependency Inversion Principle (DIP)
Depend on abstractions, not concrete classes

High-level modules (like OrderService) should depend on interfaces, not low-level classes like SqlOrderRepository.

Real-World Example
public interface IEmailService
{
    void SendEmail(string to, string message);
}
public class EmailService : IEmailService
{
    public void SendEmail(string to, string message)
    {
        // SMTP logic
    }
}
public class NotificationManager
{
    private readonly IEmailService _emailService;

    public NotificationManager(IEmailService emailService)
    {
        _emailService = emailService;
    }

    public void Notify(string msg)
    {
        _emailService.SendEmail("[email protected]", msg);
    }
}


In Program.cs
services.AddScoped<IEmailService, EmailService>();

How to Apply SOLID Principles Efficiently While Working?

  • Start with interfaces, then build implementations.
  • Don’t mix responsibilities: Separate service, repository, controller.
  • Write unit tests: If a class is hard to test, it’s probably violating SOLID.
  • Utilize design patterns:such as Strategy, Factory, and Mediator, to simplify SOLID principles.
  • Think like Lego: Compose functionality from small, testable bricks.


Final Thoughts
Mastering SOLID is like upgrading your dev brain. You’ll not only write clean and testable code but also scale faster, debug smarter, and survive enterprise-level chaos like a pro.
Want feedback on how SOLID your current codebase is? Drop a sample, and let's refactor it together!

Happy coding, and stay SOLID.

HostForLIFE ASP.NET Core 10.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 10.0 Hosting - HostForLIFE :: Wolverine's Modern CQRS and Messaging in.NET

clock July 1, 2025 08:44 by author Peter

You have most likely used libraries like MediatR, MassTransit, or CAP to handle commands and messages at some time during your.NET journey. Although each has advantages, wiring and configuration can occasionally impede the development of features alone. I recently learned about the JasperFx team's command and message bus library, Wolverine. It combines scheduled jobs, communications, CQRS, and a robust inbox/outbox into a single, streamlined solution. What's the best part? It's enjoyable to work with, quick, and clean.

This post will show you how to use Wolverine to manage commands, publish events, and schedule background messages without the need for a database or web API by guiding you through a straightforward console application. 

Why Wolverine?
Wolverine aims to simplify distributed application architecture by combining.

  • Command handling (like MediatR).
  • Asynchronous and scheduled messaging.
  • Built-in middleware and behaviors.
  • Optional durable inbox/outbox with Marten (PostgreSQL).

Instead of bolting together multiple libraries, Wolverine gives you a unified model with batteries included.
The Example: Console-Based User Registration

We’ll build a console app that,

  • Registers a user via a command.
  • Sends a welcome email (simulated).
  • Schedules a follow-up reminder message.

Everything runs in-process using Wolverine's local message bus.

Step 1. Create the Project

Project Folder Structure
WolverineConsoleDemo/
├── Program.cs
├── WolverineConsoleDemo.csproj
├── Messages/
│   ├── RegisterUser.cs
│   ├── UserRegistered.cs
│   └── RemindAdmin.cs
├── Handlers/
│   ├── RegisterUserHandler.cs
│   ├── UserRegisteredHandler.cs
│   └── RemindAdminHandler.cs


dotnet new console -n WolverineConsoleDemo
cd WolverineConsoleDemo

dotnet add package WolverineFx


Step 2. Define Messages and Handlers
RegisterUser.cs
public record RegisterUser(string Email, string FullName);

UserRegistered.cs
public record UserRegistered(string Email);

RemindAdmin.cs
public record RemindAdmin(string Email);

Step 3. Implement Handlers
RegisterUserHandler.cs

using Wolverine;
using WolverineConsoleDemo.Messages;
namespace WolverineConsoleDemo.Handlers
{
    public class RegisterUserHandler
    {
        /// <summary>
        /// Handles the specified command.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="context">The context.</param>
        public static async Task Handle(RegisterUser command, IMessageContext context)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"Registered: {command.FullName}");
            Console.ResetColor();
            await context.PublishAsync(new UserRegistered(command.Email));
            await context.ScheduleAsync(new RemindAdmin(command.Email), TimeSpan.FromSeconds(10));
        }
    }
}


UserRegisteredHandler.cs
using WolverineConsoleDemo.Messages;
namespace WolverineConsoleDemo.Handlers
{
    public class UserRegisteredHandler
    {
        /// <summary>
        /// Handles the specified event.
        /// </summary>
        /// <param name="event">The event.</param>
        /// <returns></returns>
        public static Task Handle(UserRegistered @event)
        {
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine($"Welcome email sent to {@event.Email}");
            Console.ResetColor();
            return Task.CompletedTask;
        }
    }
}


RemindAdminHandler.cs
using WolverineConsoleDemo.Messages;
namespace WolverineConsoleDemo.Handlers
{
    public class RemindAdminHandler
    {
        /// <summary>
        /// Handles the specified MSG.
        /// </summary>
        /// <param name="msg">The MSG.</param>
        /// <returns></returns>
        public static Task Handle(RemindAdmin msg)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine($"Admin reminded for: {msg.Email}");
            Console.ResetColor();
            return Task.CompletedTask;
        }
    }
}

Step 4. Configure Wolverine in the Program.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Wolverine;
using WolverineConsoleDemo.Messages;
var builder = Host.CreateApplicationBuilder(args);
// suppress hosting lifetime logs
builder.Logging.AddFilter("Microsoft.Hosting.Lifetime", LogLevel.None);
builder.Services.AddWolverine(opts =>
{
    opts.PublishMessage<RegisterUser>().ToLocalQueue("users");
    opts.PublishMessage<UserRegistered>().ToLocalQueue("emails");
    opts.PublishMessage<RemindAdmin>().ToLocalQueue("admin");
});
using var host = builder.Build();
// Start the host before using Wolverine
await host.StartAsync();
var bus = host.Services.GetRequiredService<IMessageBus>();
await bus.InvokeAsync(new RegisterUser("[email protected]", "Test User"));
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
// Optional: gracefully shut down
await host.StopAsync();


Sample Console Output
This output demonstrates how Wolverine utilizes color-coded messages to distinguish each part of the registration process clearly.


Conclusion
Wolverine brings a fresh, powerful approach to building message-driven systems in .NET. With minimal setup and zero boilerplate, we’ve seen how easy it is to.

  • Create and handle commands.
  • Publish and respond to events.
  • Schedule background tasks.
  • Run everything in-process without external queues or services.

This lightweight console app demonstrates that you don’t need heavy infrastructure to adopt clean, decoupled architectures. Whether you’re prototyping a feature, building core business logic, or moving toward microservices, Wolverine gives you the right tools with a developer-friendly experience. If you're tired of wiring up multiple libraries to do what Wolverine does out of the box, give it a try in your next project. You might be surprised how much simpler your code becomes.

HostForLIFE ASP.NET Core 10.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



About HostForLIFE

HostForLIFE is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Month List

Tag cloud

Sign in