Tutorials ASP.NET Core Tutorial
Dependency Injection — Complete Guide
Dependency Injection — Complete Guide: free step-by-step lesson with examples, common mistakes, and interview tips — part of ASP.NET Core Tutorial on Toolliyo Academy.
On this page
ASP.NET Core Tutorial (ShopNest) · Lesson 21 of 100
Dependency Injection
Beginner ✓ → Intermediate → Advanced → Professional
Intermediate · 2 — Building apps · ~14 min read · Module 3: Services & Pipeline
Introduction
You know the basics now. Here we use Dependency Injection in real app situations — controllers, databases, and APIs. Still plain language, just a bit more depth. Dependency injection (DI) means ASP.NET Core creates your services and passes them into controllers. You ask for IOrderService in the constructor — you do not write new OrderService() yourself. DI makes code testable and flexible. You can swap a fake payment service in tests without changing the controller.
The pipeline and DI container are the heart of ASP.NET Core. Every request passes through them before your code runs.
When will you use this?
Reach for middleware and DI when requests need logging, auth, or shared services.
- Middleware handles auth, logging, and errors before your controller runs.
- Dependency injection gives each request its own DbContext without you writing new everywhere.
Real-world: Toolliyo-style learning platform
The EdTech / LMS team building Toolliyo-style learning platform uses Dependency Injection to inject IOrderService into the controller without writing new OrderService(). students and instructors never see the C# code — they just get a fast, reliable course API and lesson progress tracking.
Production-style code
// Program.cs
builder.Services.AddScoped<IOrderService, OrderService>();
// OrdersController.cs
public class OrdersController : ControllerBase
{
private readonly IOrderService _orders;
public OrdersController(IOrderService orders) => _orders = orders;
[HttpPost]
public async Task<IActionResult> Create(OrderDto dto) =>
Ok(await _orders.PlaceOrderAsync(dto));
}
What happens in production: In Toolliyo-style learning platform, getting Dependency Injection right means students and instructors trust the course API and lesson progress tracking every day.
Lesson example (start here)
Copy this smaller example first. Once it works, compare it with the real-world code above.
// Program.cs
builder.Services.AddScoped<IProductService, ProductService>();
// ProductsController.cs
public class ProductsController : Controller
{
private readonly IProductService _products;
public ProductsController(IProductService products) => _products = products;
public async Task<IActionResult> Index() =>
View(await _products.GetFeaturedAsync());
}
Line-by-line walkthrough
| Code | What it means |
|---|---|
// Program.cs | Comment — notes for humans; the compiler ignores it. |
builder.Services.AddScoped<IProductService, ProductService>(); | Registers services in dependency injection — available in controllers later. |
// ProductsController.cs | Comment — notes for humans; the compiler ignores it. |
public class ProductsController : Controller | Controller class — handles HTTP requests and returns views or JSON. |
{ | Part of the Dependency Injection example — read it together with the lines before and after. |
private readonly IProductService _products; | Part of the Dependency Injection example — read it together with the lines before and after. |
public ProductsController(IProductService products) => _products = products; | Method — often an action that runs when a URL is hit. |
public async Task<IActionResult> Index() => | Return type — can be a view, redirect, JSON, or error response. |
View(await _products.GetFeaturedAsync()); | Async — waits for database or HTTP without blocking other requests. |
} | Closes a block started by { above. |
How it works (big picture)
- AddScoped registers one ProductService per HTTP request.
- The controller constructor receives it automatically.
Do this on your computer
- Create IProductService and ProductService classes.
- Register AddScoped in Program.cs.
- Inject into a controller and call a method.
- Run dotnet run and hit the page.
- Read the real-world section and name which part of the app uses this topic.
- Run the example locally with dotnet run and confirm the same behavior.
- Change one value in the example (route, text, or connection string) and predict what will happen before you save.
Experiments — try changing this
- Change a string or route in the example and save — watch the browser or Swagger response update.
- Break the code on purpose (remove a semicolon), read the error message, then fix it.
- Use dotnet watch run while editing Dependency Injection — the app restarts on save.
Remember
Register services in Program.cs. Inject via constructor. Use interfaces for testability.
Common questions
Singleton vs Scoped vs Transient?
Singleton = one for whole app. Scoped = one per request. Transient = new every time you ask.
How long should I spend on Dependency Injection?
Until you can explain it in your own words and run the example without looking at the answer. Beginners often need 30–60 minutes per new concept; setup lessons may take one afternoon.
What if I get stuck on Dependency Injection?
Re-read the line-by-line walkthrough, check the terminal for red errors, and compare your code character-by-character with the example. Search the exact error text — someone else had it too.
Where is Dependency Injection used in real jobs?
See the real-world section above — the same pattern appears in LMS, banking, e-commerce, and SaaS backends. Interviewers ask you to explain it using one concrete example.
Sign in to ask a question or upvote helpful answers.
No questions yet — be the first to ask!