dotnet / dotnet/runtime

[API Proposal]: Add an IServiceLifetimeProvider that takes in a type and returns the lifetime that it was registered with

Open
#128,251 8 comments 1 reaction 0 assignees View on GitHub
api-suggestion area-Extensions-DependencyInjection
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Background and motivation

Per the discussion in #125609 it seemed like it might be useful to have a service that could retrieve the `ServiceLifetime` of a given type. There are already similar interfaces that exist, such as `IServiceProviderIsService` which returns whether or not a type is registered as a service, but none that can retrieve the lifetime.

The driving cause of this proposal is that it makes it easier to deal with the fact that services registered as Transient that implement `IDisposable` are kept alive until their scope is disposed which commonly leads to memory leaks in long lived scopes, but there may be other benefits.

### API Proposal

```csharp
namespace Microsoft.Extensions.DependencyInjection;

public interface IServiceLifetimeProvider
{
// Could be this
ServiceLifetime? GetServiceLifetime(Type serviceType);

// Or this
bool TryGetServiceLifetime(Type serviceType, out ServiceLifetime lifetime);
}
```

### API Usage

```csharp
// Pattern used to create a service and determine if it should be disposed or not by the consumer
public class Consumer()
{
public Consumer(IServiceProvider serviceProvider, IServiceLifetimeProvider lifetimeProvider)
{
IService service;
bool disposeService;
// If IService is registered as scoped or singleton, then we just get the service and won't dispose of it when we're done
if (lifetimeProvider.GetServiceLifetime(typeof(IService)) is ServiceLifetime.Scoped or ServiceLifetime.Singleton)
{
service = serviceProvider.GetService();
disposeService = false;
}
// Otherwise we manually create a new one and know we need to dispose of it. In this case, the IoC container won't track the reference created
else
{
service = ActivatorUtilities.CreateInstance(serviceProvider);
disposeService = true;
}
}
}
```

### Alternative Designs

_No response_

### Risks

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.