ASP.NET Hosting

ASP.NET Tutorial: Understanding and Using Scope in .NET Core

One of the most important ideas in.NET Core dependency injection (DI) is the scope. It chooses the services that are injected into your application and their visibility and lifespan. Gaining an understanding of scope will enable you to handle resources more effectively and steer clear of typical issues like memory leaks and pointless object creation. This article will explain scope, go over the various.NET Core scope classes, and provide real-world examples of how to use them.

Types of Scopes in .NET Core

  1. Transient: A new instance of the service is created every time it is requested.
  2. Scoped: A single instance of the service is created per request (or per scope).
  3. Singleton: A single instance of the service is created and shared throughout the application’s lifetime.

Using Scope in .NET Core
Let’s dive into how to use these scopes with examples.

1. Transient
A transient service is created each time it is requested. This is useful for lightweight, stateless services.

public interface ITransientService
{
    Guid GetOperationId();
}
public class TransientService : ITransientService
{
    private readonly Guid _operationId;
    public TransientService()
    {
        _operationId = Guid.NewGuid();
    }
    public Guid GetOperationId() => _operationId;
}

Register the service in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ITransientService, TransientService>();
}

Use the service in a controller

[ApiController]
[Route("api/[controller]")]
public class ExampleController : ControllerBase
{
    private readonly ITransientService _transientService1;
    private readonly ITransientService _transientService2;
    public ExampleController(
        ITransientService transientService1,
        ITransientService transientService2)
    {
        _transientService1 = transientService1;
        _transientService2 = transientService2;
    }
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new
        {
            Service1 = _transientService1.GetOperationId(),
            Service2 = _transientService2.GetOperationId()
        });
    }
}

Each time you hit the endpoint, you’ll see different GUIDs for each service instance.

2. Scoped

A scoped service is created once per request. This is useful for services that maintain state within a single request.

public interface IScopedService
{
    Guid GetOperationId();
}

public class ScopedService : IScopedService
{
    private readonly Guid _operationId;
    public ScopedService()
    {
        _operationId = Guid.NewGuid();
    }
    public Guid GetOperationId() => _operationId;
}

Register the service in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IScopedService, ScopedService>();
}

Use the service in a controller

[ApiController]
[Route("api/[controller]")]
public class ExampleController : ControllerBase
{
    private readonly IScopedService _scopedService1;
    private readonly IScopedService _scopedService2;
    public ExampleController(IScopedService scopedService1, IScopedService scopedService2)
    {
        _scopedService1 = scopedService1;
        _scopedService2 = scopedService2;
    }
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new
        {
            Service1 = _scopedService1.GetOperationId(),
            Service2 = _scopedService2.GetOperationId()
        });
    }
}

Each time you hit the endpoint, you’ll see the same GUID for both service instances within a single request, but different GUIDs across different requests.

3. Singleton

A singleton service is created once and shared across all requests. This is useful for stateless services that can be shared.

public interface ISingletonService
{
    Guid GetOperationId();
}

public class SingletonService : ISingletonService
{
    private readonly Guid _operationId;
    public SingletonService()
    {
        _operationId = Guid.NewGuid();
    }
    public Guid GetOperationId() => _operationId;
}

Register the service in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ISingletonService, SingletonService>();
}

Use the service in a controller

[ApiController]
[Route("api/[controller]")]
public class ExampleController : ControllerBase
{
    private readonly ISingletonService _singletonService1;
    private readonly ISingletonService _singletonService2;
    public ExampleController(ISingletonService singletonService1, ISingletonService singletonService2)
    {
        _singletonService1 = singletonService1;
        _singletonService2 = singletonService2;
    }
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new
        {
            Service1 = _singletonService1.GetOperationId(),
            Service2 = _singletonService2.GetOperationId()
        });
    }
}

Each time you hit the endpoint, you’ll see the same GUID for both service instances across all requests.

Conclusion

Understanding and using the appropriate scope for your services in .NET Core is essential for efficient resource management and application performance. Transient services are suitable for lightweight and stateless operations, scoped services for maintaining state within a request, and singleton services for shared, stateless operations across the entire application. By carefully choosing the right scope, you can optimize your application’s performance and maintainability. I hope this article helps you understand the concept of scope in .NET Core and how to use it effectively. If you have any questions or need further clarification, feel free to ask!

ASP.NET Core 9 Hosting Recommendation

HostForLIFE.eu
HostForLIFE.eu is a popular recommendation that offers various hosting choices. Starting from shared hosting to dedicated servers, you will find options fit for beginners and popular websites. It offers various hosting choices if you want to scale up. Also, you get flexible billing plans where you can choose to purchase a subscription even for one or six months.