I. History of DI pattern
- The Pioneer of DI is Robert C. Martin. He wrote in his paper about "The Dependency Inversion Principle", which also known as DIP for short. This is eventually known as IoC/DI’s principle, just like now.
II. Advantage of DI
DI is a design pattern to implement Inversion of Control
- DI working as an Object Creator and manage the lifetime of it
- Reduce the dependency between components / Decouples the higher-level Class from its dependencies so that you can change the code of a lower-level Class without changing the code that uses it
III. DI lifetime in .NET Core
1. Singleton Lifetime
This lifetime creates one instance of the service per application instance.
- If you have multiple application instance same or different server, it means you have multiple "singleton" instance of the service 🙃
2. Transient Lifetime
By using this lifetime, your service will be created each time it will be requested.
- It means every time you inject it, it will create a new instance for the requester.
- Also, it very close to
newObject as a traditional way 🤭
- Therefore, pretty rare we use it in the application have using DI framework.
- For example, we need a new instance of the Class for each thread to implement the parallel mechanism.
So using the Transient Lifetime equal to you will not take advantage of DI that object lifetime management 👎.
3. Scoped Lifetime
The scoped lifetime allows you to create an instance of a service for each Scope.
- In .NET Core each HTTP request automation create a global Scope wrap whole the request.
- You can create the "Scope" in your code in case you would like to have separate scope by
- This lifetime is most popular in Web/API Project because the scope auto creates for each HTTP request then all scoped instances will be shared during request then disposed when the HTTP response is completed. Perfect! saved server resource 🤑
1. What lifetime should I use for my application?
If your application is a web server/API then you should use the Scoped Lifetime.
- The web server/API provide service and functionality for multiple end-user.
- Each HTTP request serves for 1 end-user and need keep the web server in stateless. So release/dispose instances during the HTTP request to save server resources and retain high performance for the next one.
If your application is a Desktop Application, then you should use the Singleton Lifetime.
- The Desktop Application provide service and functionality for only 1 end-user with the highest performance.
Also, it depend on your business that some case you must use Singleton and Transient Lifetime.
2. What happen if I inject Scoped to Singleton? Transient to Singleton? Transient to Scoped? Scoped to Transient? ... 🙀
2.1 Will it exception if I inject a lower lifetime to a higher lifetime?
Firstly, WTF low and high lifetime? who and how to define it??? 🖕
Secondly, exception *beep* *beep* did you tried it? why exception? 👊
2.2 Will the transient lifetime become a singleton lifetime when the singleton lifetime class injected the transient lifetime class?
Firstly, you can scroll up to read again about the Transient and Singleton lifetime definition.
- Transient lifetime - create an instance when "request"
- Singleton will be 1 instance per application.
The DI work as an Object Creator, so the workflow is easy to imagine as below
- When the class singleton lifetime (Class S) created, it will hit to "constructor"
- The constructor will "request" an instance of Transient Lifetime class (Class T)
- Yeah, the DI now creates an instance for Class T and returns it for Class S.
Because Class S is a singleton lifetime so after the first creation instance for Class S, we never go to Class S constructor again.
In the next time, in Class A inject Class S and because the Class S already have instance then it will never hit to "constructor" again... so never "request" new instance for class T again.
But in another class 😅 Class B , inject Class T. Then when create class B, it will be a request a new instance of Class T (not same instance of Class T for Class S).
- In Class S context, Class T worked as Singleton Lifetime💩
- In the Application context, Class T still Transient Lifetime
So the Answer for the question is... Yes but No 😂