How to specify service lifetime for register service that added as a dependency C# Asp.net Core?

The built-in IoC container in ASP.NET Core manages the lifetime of registered services and automatically disposes service instances based on the specified lifetime. Understanding service lifetimes is crucial for proper dependency injection and resource management.

The built-in IoC container supports three kinds of lifetimes −

  • Singleton − IoC container will create and share a single instance of a service throughout the application's lifetime.

  • Transient − The IoC container will create a new instance of the specified service type every time you ask for it.

  • Scoped − IoC container will create an instance of the specified service type once per request and will be shared in a single request.

Service Lifetime Comparison Singleton One instance for entire app lifetime Transient New instance every time requested Scoped One instance per HTTP request App Start ? App End Each Injection Per Request Choose based on your service's state requirements Stateless ? Singleton | Stateful ? Scoped | Lightweight ? Transient

Syntax

Following is the syntax for registering services using ServiceDescriptor

services.Add(new ServiceDescriptor(typeof(IService), typeof(ServiceImpl), ServiceLifetime.Singleton));
services.Add(new ServiceDescriptor(typeof(IService), typeof(ServiceImpl), ServiceLifetime.Transient));
services.Add(new ServiceDescriptor(typeof(IService), typeof(ServiceImpl), ServiceLifetime.Scoped));

Following is the syntax for registering services using extension methods −

services.AddSingleton<IService, ServiceImpl>();
services.AddTransient<IService, ServiceImpl>();
services.AddScoped<IService, ServiceImpl>();

Using ServiceDescriptor for Service Registration

The first approach uses the ServiceDescriptor class to explicitly define the service type, implementation, and lifetime −

using Microsoft.Extensions.DependencyInjection;
using System;

public interface ILog {
    void Info(string str);
}

class MyConsoleLogger : ILog {
    public void Info(string str) {
        Console.WriteLine($"[LOG]: {str}");
    }
}

public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        // Singleton - single instance for entire application
        services.Add(new ServiceDescriptor(typeof(ILog), new MyConsoleLogger()));
        
        // Transient - new instance every time
        services.Add(new ServiceDescriptor(typeof(ILog), typeof(MyConsoleLogger), ServiceLifetime.Transient));
        
        // Scoped - one instance per request
        services.Add(new ServiceDescriptor(typeof(ILog), typeof(MyConsoleLogger), ServiceLifetime.Scoped));
    }
    
    public static void Main(string[] args) {
        var services = new ServiceCollection();
        var startup = new Startup();
        startup.ConfigureServices(services);
        
        var serviceProvider = services.BuildServiceProvider();
        var logger = serviceProvider.GetService<ILog>();
        logger?.Info("Service registration complete");
    }
}

The output of the above code is −

[LOG]: Service registration complete

Using Extension Methods for Service Registration

ASP.NET Core provides convenient extension methods that make service registration more readable and concise −

using Microsoft.Extensions.DependencyInjection;
using System;

public interface ILog {
    void Info(string str);
}

public interface IEmailService {
    void SendEmail(string message);
}

class MyConsoleLogger : ILog {
    public void Info(string str) {
        Console.WriteLine($"[LOG]: {str}");
    }
}

class EmailService : IEmailService {
    public void SendEmail(string message) {
        Console.WriteLine($"[EMAIL]: {message}");
    }
}

public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        // Generic syntax
        services.AddSingleton<ILog, MyConsoleLogger>();
        services.AddTransient<IEmailService, EmailService>();
        services.AddScoped<ILog, MyConsoleLogger>();
        
        // Type syntax
        services.AddSingleton(typeof(ILog), typeof(MyConsoleLogger));
        services.AddTransient(typeof(IEmailService), typeof(EmailService));
        services.AddScoped(typeof(ILog), typeof(MyConsoleLogger));
    }
    
    public static void Main(string[] args) {
        var services = new ServiceCollection();
        var startup = new Startup();
        startup.ConfigureServices(services);
        
        var serviceProvider = services.BuildServiceProvider();
        
        var logger = serviceProvider.GetService<ILog>();
        var emailService = serviceProvider.GetService<IEmailService>();
        
        logger?.Info("Application started");
        emailService?.SendEmail("Welcome to the application");
    }
}

The output of the above code is −

[LOG]: Application started
[EMAIL]: Welcome to the application

Comparison of Service Lifetimes

Lifetime Instance Creation Best Use Case Memory Usage
Singleton Once per application Stateless services, configuration Low
Scoped Once per HTTP request Database contexts, request-specific data Medium
Transient Every injection Lightweight stateless services High

Conclusion

Service lifetime specification in ASP.NET Core determines how long service instances live and when they are created or disposed. Choose Singleton for stateless services, Scoped for per-request services like database contexts, and Transient for lightweight services that need fresh instances each time.

Updated on: 2026-03-17T07:04:36+05:30

716 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements