When leveraging Dependency Injection in ASP.NET Core you will want to choose an appropriate lifetime for each registered service.
ASP.NET Core services can be configured with the following lifetimes:
When in doubt, make it Transient.
When you add a Transient service you are telling ASP.NET Core that each time the service is requested you want a new instance to be created.
At one time there was thought that using Transient lifetimes over Scoped lifetimes caused performance issues. This is more of a fable than a fact. That being said, if you are having performance issues I would recommend you look elsewhere before replacing all your Transient lifetimes with Scoped lifetimes.
When you add a Singleton service you are telling ASP.NET Core to create a single instance of the service, which will last the entire lifetime of the application.
Another way to look at it would be that after the initial request of the service, every other request will use the same instance. The service will span across web requests (So if two different users hit your website, the sames instance will be used for each user).
You can think of a Singleton similarly to that of a static variable in a class, it is a single value across multiple instances.
Use a Singleton when you want to share data across your services, you are saving “state” for the lifetime of your application.
When you add a Scoped lifetime service think of it this way, you are adding one object, or instance, per web request, granted it’s a little more complicated than that, but for most cases, you can think of Scoped objects as being per web request.
Scoped lifetime actually means that objects will be the same instance within a created “scope” objects. ASP.NET Core wraps a request within a “scope”, but you can actually create scopes manually.
While you can create scopes manually, ASP.NET Core wraps a request within a “scope”.