Skip to content

Plasma-Paris/LifetimeConsistencyCheck

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logo

LifetimeConsistencyCheck

Add extensions that allow consistency lifetime check for services registered into Microsoft's native dependency injection system for .NET Core (originally wrtitten for 2.0, since, upgraded to .NET Core 6.0)

Why we need this ?

Logically, a Scoped or Transient dependency can not be injected into a Singleton dependency: the lifetime of a dependency injected into a service's constructor can not be shorter than the lifetime of the service itself.

The native Microsoft system allow to check this behavior, but not at the application startup, only at each service resolving. If this check is not activate, a Scoped dependency injected into a Singleton will behave as if it was itself a Singleton, without the developer being informed.

This can create unwanted side effects, especially in a multi-threaded applications.

This behavior is clearly described in the Microsoft documentation: log_warning

Source : https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.0

Installing / Getting started

Simply reference the librairies into your project, or use NuGet :

Install-Package LifetimeConsistencyCheck

https://www.nuget.org/packages/LifetimeConsistencyCheck

Usage

public class Startup
{
	// …
	public IServiceProvider ConfigureServices(IServiceCollection services)
	{
		// …
		services.AddSingleton<IMyService1, MyService1>();
		services.AddScoped<IMyService2, MyService2>();
		// …

		services.CheckLifetimeConsistency();
		return services.BuildService(validateScopes: true);
	}
}

Check at application start

services.CheckLifetimeConsistency();

This method checks the consistency of the lifetime of all the services that were register (as far as possible) as soon as the method is executed, which makes it possible to be informed as soon as possible if there is an inconsistency.

ignoreMicrosoftInternalErrors Parameter

Even Microsoft do the mistake of using Transient services in Singleton services (Exemple : ICompositeMetadataDetailsProvider is a Transient service used in the DefaultModelMetadataProvider Singleton service, same for IRazorPageFactoryProvider and PageActionInvokerProvider, and a few others). This parameter allow to ignore errors generated by services in the Microsoft or System namespace.

Check at service resolving

Ideally we would have wanted to use only the check at startup method, but it is not always possible. If a service is register as follows:

services.AddSingleton<IMyService>((c) => new MyService(c.GetService<IMyService2>());

It is possible to know the exact implementation of the service only by running the factory that creates it. For avoid undesirable side effects, check of the consistency of this kind of service can be done only when the dependency injection system resolves the service. So you can use:

services.BuildService(validateScopes: true);

If you set the validateScopes parameter to true, the service provider will check the consistency of each service regarding its dependencies at its resolving. This is native to Microsoft dependency injection system.

To Do

  • Optimizations
    • Make a custom implementation of BuildService method for check the consistency at service resolving, but only for services registered with the factory method
      • The ServiceProvider is sealed, so it is not trivial
  • Make the error message more detailed when check at resolve

Contributing

If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are welcome. Please update the ChangeLog.md file in the documentation directory.

Licensing

The code in this project is licensed under BSD-3-Clause license.

About

Add extensions that allow consistency lifetime check for services registered into Microsoft's native dependency injection system for .NET Core 2.0

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages