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 10.0 Hosting - HostForLIFE :: ASP.NET Core Service Lifetimes: Transient, Scoped, and Singleton

clock June 26, 2025 07:56 by author Peter

Dependency Injection (DI) is a potent feature in ASP.NET Core that aids programmers in creating loosely linked, tested, and maintainable applications. Understanding how services are handled over time is a crucial component of this system, and this is where Service Lifetimes enter the picture.

A Service Lifetime determines how long an instance of a service will live once it's created by the built-in IoC (Inversion of Control) container.

When a service is registered in the Program.cs (or Startup.cs in older versions), we must specify its lifetime. This decision directly affects.

  • When the service instance is created
  • How long will it be reused
  • Whether it's shared across requests, users, or components

"How long will the instance of the service live?" and "When will a new instance be created?"

There are 3 built-in lifetimes.

Lifetime Description
Transient New instance every time it is requested.
Scoped One instance per HTTP request (or scope).
Singleton One instance for the entire lifetime of the application..

Before diving into service lifetimes, it's very important to understand the core concepts.

Before diving into service lifetimes, it's very important to understand the core concepts.

  • Dependency Injection (DI)
  • Inversion of Control (IoC)

What is Dependency Injection (DI)?
Dependency Injection is a design pattern used to provide an object’s dependencies from the outside, instead of creating them inside the object itself.
Dependency = Another class or object that your class needs to function.
Injection = Supplying those dependencies externally.

Imagine you're a chef who needs ingredients to cook.

  • Without DI, the chef goes out to the farm, harvests the vegetables, and then cooks.
  • With DI, someone delivers the fresh ingredients to the chef so they can focus on cooking.

DI = Someone gives you what you need. You don’t fetch it yourself.
Without DI (tight coupling)
public class Car
{
    private Engine _engine = new Engine();  // Car creates its own engine

    public void Drive()
    {
        _engine.Start();
    }
}


Problem

  • Hard to test
  • Can’t swap the Engine with the electric engine easily
  • Tight coupling

With DI (loose coupling)
public class Car
{
    private readonly IEngine _engine;

    public Car(IEngine engine)  // Engine is "injected" from outside
    {
        _engine = engine;
    }

    public void Drive()
    {
        _engine.Start();
    }
}


Now we can,

  • Inject any IEngine implementation
  • Test easily (mock the engine)
  • Change logic without touching the Car class

What is Inversion of Control (IoC)?
Inversion of Control is a broader principle. It means that the control of creating and managing objects is inverted — from the class to a container or framework. In simpler terms.
Instead of our code controlling how things are created, the framework (like ASP.NET Core) does it for us.

Example of IoC
We register services in a container.
services.AddScoped<ICarService, CarService>();

Then our controller.
public class HomeController : Controller
{
    private readonly ICarService _carService;

    public HomeController(ICarService carService) // Injected by framework
    {
        _carService = carService;
    }
}


We didn’t create CarService the IoC container did and gave it to us!

Relationship Between DI and IoC

Concept Meaning Who Manages Creation
IoC Inverting object creation/control Framework/Container
DI A way to implement IoC by injecting dependencies The framework injects what you need

So, Dependency Injection is a technique used to achieve Inversion of Control.

  • IoC: Framework creates and manages the object
  • DI: The Controller gets the service it needs without creating it

Why Are Service Lifetimes Important?
Choosing the correct service lifetime is essential for,

  • Memory management: Avoid unnecessary object creation
  • Performance optimization: Reuse objects when appropriate
  • Thread safety prevents state corruption in multi-user scenarios
  • Correct behavior, especially when services maintain data like a database context
  • Prevents data leaks by isolating instances.
  • Promotes cleaner architecture via proper dependency reuse.

Types of Service Lifetimes in .NET Core
.NET provides three main service lifetimes.

  • Transient: A new instance is created every time the service is requested.
  • Scoped: A single instance is created per HTTP request and shared within that request.
  • Singleton: A single instance is created once and shared across the entire application.

Choosing the correct lifetime ensures better performance, resource management, and application behavior.

Where Are Lifetimes Defined?
Lifetimes are defined when registering services in the Program.cs file.
builder.Services.AddTransient<IMyService, MyService>();   // Transient
builder.Services.AddScoped<IMyService, MyService>();      // Scoped
builder.Services.AddSingleton<IMyService, MyService>();   // Singleton

Service Lifetime Differences in ASP.NET Core

Feature / Criteria Transient Scoped Singleton
Object Creation Every time it is requested Once per HTTP request Once for the entire application
Shared Between Never shared Shared within one request Shared across all requests and components
Reuse Behavior New instance for every injection Same instance reused during one request Same instance reused everywhere
Lifetime Ends Immediately after use End of the HTTP request When the app shuts down
Thread-Safety Required No (short-lived) No (request-specific) Yes (used by multiple threads)
Testing Use Case Best for isolated tests Good for per-request logic Good for app-level state
Best For Lightweight, stateless services Entity Framework DbContext, per-user logic Logging, Caching, Configuration
Common Pitfall High object creation cost Cannot be injected into a Singleton Memory leaks or shared state issues

Best Practices for Choosing Service Lifetimes in .NET

Scenario Recommended Lifetime Real Example Explanation
Stateless utility like a formatter/calculator Transient PriceFormatterService Creates a new instance each time — ideal for small, stateless services like currency formatting or calculations.
Database access, user session services Scoped ApplicationDbContext, UserService Ensures consistency within a single HTTP request — needed for services handling DB transactions or per-user data.
Global logger, configuration, and caching Singleton LoggerService, ConfigProvider Created once and reused across the app — perfect for shared logic like logging or reading global settings.

What Happens If We Choose the Wrong Lifetime?

1. Scoped Service Injected into Singleton

  • Problem: Scoped services (like DbContext) are created per request. A Singleton lives for the entire app.
  • What Happens: .NET throws a runtime error InvalidOperationException.
  • Why: A Singleton can't depend on something that changes per request.

2. Storing Large Data in a Singleton

  • Problem: Singleton services stay alive for the app's entire lifetime.
  • What Happens: If you store large data (e.g., thousands of records), it causes memory leaks or slow performance.
  • Why: Data is never released from memory.

3. Using Transient for Expensive or Stateful Services

  • Problem: Transient creates a new instance every time.
  • What Happens: Extra memory usage, duplicate work (like database connections or API calls), and inconsistent behavior.
  • Why: Data/state is not shared between calls.

4. Expecting Transient or Scoped to Act Like Singleton

  • Problem: Assuming the service "remembers" data across requests or injections.ASP.NET Core Service Lifetimes: Transient, Scoped, and Singleton
  • What Happens: Data is lost or reset unexpectedly.
  • Why: Scoped lasts only one request, and Transient lasts only one use.

Conclusion
Understanding Service Lifetimes in .NET is essential for building efficient, scalable, and maintainable applications. By mastering Dependency Injection and properly choosing between Transient, Scoped, and Singleton lifetimes, you can control how services behave, improve app performance, and avoid bugs related to memory leaks or shared state. Always start with Transient unless your scenario calls for Scoped or Singleton. Use Scoped for request-based operations like database access, and use Singleton cautiously for shared logic like configuration or logging, while ensuring thread safety. With the right service lifetime choices and a solid understanding of DI and IoC, your ASP.NET Core applications will be more testable, modular, and cleanly architected.

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 :: Monitoring of Entity Framework Changes

clock June 23, 2025 09:10 by author Peter

We shall study Entity Framework Change Tracking in this article. Now, let's get going.

Comprehending Change Tracking

EF Core uses a technology called change tracking to monitor modifications made to your entities. This aids EF Core in figuring out which SQL commands must be run in order to maintain database changes.

Example
using (var context = new AppDbContext())
  {
      var employee = context.Employees.FirstOrDefault(e => e.EmployeeId == 101);
      employee.City = "Mumbai";

      // EF Core tracks the change in the City property.
  }


Managing the State of Entities
EF Core tracks the state of each entity (Added, Unchanged, Modified, Deleted) to determine the operations to be performed during SaveChanges.
using (var context = new AppDbContext())
  {
      var employee = context.Employees.FirstOrDefault(e => e.EmployeeId == 101);
      context.Entry(employee).State = EntityState.Modified;
      context.SaveChanges();

      // The state is set to Modified, prompting and UPDATE command
  }

Using No-Tracking Queries
No-tracking queries improve performance for read-only operations by not tracking the entities in the context. This reduces memory usage and speeds up query execution.
using (var context = new AppDbContext())
  {
      var employees = context.Employees.AsNoTracking().ToList();

      // No change tracking is performed, ideal for read-only operations
  }


Benefits of No-Tracking Queries

  • Performance: Faster queries and lower memory footprint.
  • Scalability: Better for large-scale read operations.
  • Simplicity: Reduces overhead when changes to entities are not needed


using (var context = new AppDbContext())
  {
      var employees = context.Employees.AsNoTracking().FirstOrDefault(e => e.EmployeeId == 101);

      // Efficiently retrieves the post without tracking it's state
  }


Summary

  • Change Tracking: Tracks changes to determine necessary database operations.
  • Entity State Management: Manages entity states for accurate database updates.
  • No-Tracking Queries: Optimizes performance for read-only operations.

In this article, I have tried to cover how to handle Entity Framework Change Tracking.

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 :: LINQ's FirstOrDefault and SingleOrDefault: Important Distinctions and Applications

clock June 17, 2025 08:06 by author Peter

In this article, we explore the key differences between FirstOrDefault and SingleOrDefault in LINQ. You'll learn how each method behaves, the scenarios where they are best applied, and when to choose one over the other. By the end, you’ll gain clarity on how to use them effectively to write cleaner and more efficient LINQ queries in your C# applications. Understanding the correct usage of these methods helps you avoid common runtime errors, improve application performance, and maintain predictable code behavior. Always perform null checks when working with reference types, and use SingleOrDefault() cautiously in performance-critical sections of your code.

In this short and simple guide, we’ll explain the key differences, show you when to use each one, and help you avoid common mistakes in real-life coding situations.

What is FirstOrDefault()?
FirstOrDefault() returns the first element of a sequence or the default value (e.g., null for reference types) if no element is found.

Use Cases

  • When multiple results are expected, but you want just the first match.
  • When the sequence can be empty.
  • When performance is a concern and early exit is ideal.

Code Example
var firstProduct = products.FirstOrDefault(p => p.Price > 100);

What is SingleOrDefault()?
SingleOrDefault() returns exactly one element that matches the condition or the default value if no match is found. It throws an exception if more than one element is found.
var uniqueProduct = products.SingleOrDefault(p => p.Id == 101);

Use Cases

  • When you expect only one matching result.
  • Ideal for unique identifiers, like primary keys.
  • Use it when data integrity is important and duplicates are unexpected.

FirstOrDefault vs. SingleOrDefault

Feature FirstOrDefault SingleOrDefault
Returns First match or default Single match or default
Throws if multiple matches? ❌ No ✅ Yes
Use case First matching item Exactly one expected match
Performance Stops at the first match Scans all items to validate uniqueness


Performance Considerations

  • FirstOrDefault() stops evaluating after the first match — faster on large datasets.
  • SingleOrDefault() must scan the entire sequence to ensure there's only one match — slower if the collection is large.

Best Practices

  • Use SingleOrDefault(): only when data constraints guarantee that at most one element can satisfy the condition.
  • Prefer FirstOrDefault(): When multiple matches are possible and you only need the first occurrence, or can handle a missing result.
  • Always perform a null check: after using either method when working with reference types to prevent NullReferenceException.
  • Minimize the use of SingleOrDefault(): In performance-sensitive operations, it must evaluate the entire collection to ensure uniqueness.

Summary
In LINQ, both FirstOrDefault() and SingleOrDefault() are used to retrieve elements from a collection, but they serve different purposes. FirstOrDefault() returns the first matching element or a default value if none is found—ideal when multiple matches are possible. On the other hand, SingleOrDefault() ensures only one match exists and throws an exception if multiple results are found, making it suitable for unique identifiers or strict data constraints.

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 :: How to Build ASP.NET Core Background Tasks?

clock June 10, 2025 08:23 by author Peter

A crucial prerequisite for contemporary ASP.NET Core applications is background processing, particularly for those that use microservices. Background services are crucial for tasks like email sending, Kafka message processing, cron-type processes, and managing lengthy workflows.

With the introduction of the Generic Host and robust improvements in .NET 6, 7, and 8, ASP.NET Core now provides powerful patterns through:

  • IHostedService
  • BackgroundService
  • Worker Service templates

This article dives deep into how to design, build, and optimize background services for production.

Worker Services vs Hosted Services: What’s the Difference?

Feature IHostedService BackgroundService Worker Service Template
Interface-based Yes Yes (abstracts IHostedService) Yes (project template-based)
Long-running support Needs manual implementation Provides an infinite loop (ExecuteAsync) Yes
Best for Short-lived or event-based tasks Long-running background jobs Standalone background apps

Setting Up a Worker Service Project

You can create a worker service using.
dotnet new worker -n EmailBackgroundService

This creates a ready-to-run worker template using the Generic Host.

The Program.cs in .NET 8+ is minimal.
var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((context, services) =>
    {
        services.AddHostedService<EmailSenderWorker>();
    })
    .Build();

await host.RunAsync();


Creating a Custom BackgroundService
Here’s a simple example of a background worker.
public class EmailSenderWorker : BackgroundService
{
    private readonly ILogger<EmailSenderWorker> _logger;

    public EmailSenderWorker(ILogger<EmailSenderWorker> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Sending queued emails at: {time}", DateTimeOffset.Now);
            await SendPendingEmails();
            await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
        }
    }

    private Task SendPendingEmails()
    {
        // Implement actual email logic here
        return Task.CompletedTask;
    }
}

Advanced Hosted Services with IHostedService
When you need fine-grained control over start/stop behavior (e.g., for message queue consumers).
public class KafkaConsumerService : IHostedService
{
    public Task StartAsync(CancellationToken cancellationToken)
    {
        // Connect to Kafka and begin consuming
        return Task.Run(() => ConsumeMessages(cancellationToken), cancellationToken);
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        // Cleanup, disconnect
        return Task.CompletedTask;
    }

    private void ConsumeMessages(CancellationToken cancellationToken)
    {
        // Poll Kafka and process messages
    }
}


Managing Multiple Background Services

You can register multiple services easily.
services.AddHostedService<EmailSenderWorker>();
services.AddHostedService<KafkaConsumerService>();
services.AddHostedService<DataSyncWorker>();


Each runs independently inside the host.

Handling Exceptions & Graceful Shutdown

To avoid crashing the entire app due to unhandled exceptions in workers.
try
{
    await SomeBackgroundTask();
}
catch (Exception ex)
{
    _logger.LogError(ex, "An error occurred.");
}


For graceful shutdown, ensure your workers respond to the CancellationToken from ExecuteAsync.

Dependency Injection in Background Services
Services are injected normally.
public class DataSyncWorker : BackgroundService
{
    private readonly IDataService _dataService;

    public DataSyncWorker(IDataService dataService)
    {
        _dataService = dataService;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await _dataService.SyncExternalData();
    }
}

Scheduling and Cron-like Jobs
For scheduled tasks, consider:

  • Quartz.NET for CRON jobs.
  • Hangfire for background jobs with retry support.
  • Or a Timer-based service with Task.Delay.

Example using the Cronos package.
var cron = CronExpression.Parse("0 */5 * * * *");
var next = cron.GetNextOccurrence(DateTimeOffset.Now);

Logging, Metrics & Observability
Integrate with:

  • Serilog / Seq for structured logging
  • Prometheus for metrics
  • OpenTelemetry for traces and spans

Production Tips
Always handle exceptions gracefully

  • Use scoped services inside BackgroundService via IServiceScopeFactory
  • Monitor using health checks (IHealthCheck)
  • Separate retry logic (e.g., use Polly)
  • Set max concurrency (e.g., in queues) to prevent overload

Conclusion
ASP.NET Core’s Hosted Services and Worker Services provide powerful primitives for executing background tasks in a clean, reliable, and scalable way. Whether you're building message consumers, email dispatchers, or data processors, background services allow you to decouple, scale, and manage your application’s background logic like a pro. Happy coding!

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