Skip to main content

Services & Dependency Injection

1. What Is a Service?

A service is a class that contains business logic.

Controllers should:

  • Handle HTTP
  • Delegate work to services

Services should:

  • Do the real work (data access, rules, calculations)

Rule of thumb

Controllers = what happens

Services = how it happens


2. Why Use Services?

  • Separation of concerns – controllers stay thin
  • Reusability – same service used in many places
  • Testability – easy to unit test
  • Maintainability – logic lives in one place

3. Basic Service Example

public interface ICitiesService
{
List<string> GetCities();
}

public class CitiesService : ICitiesService
{
public List<string> GetCities()
{
return new() { "London", "Paris", "Tokyo" };
}
}

Dependency Injection (DI)

Instead of creating services manually:

new CitiesService(); // ❌

ASP.NET Core injects them for you:

public HomeController(ICitiesService citiesService)
{
_citiesService = citiesService;
}

This is Dependency Injection


5. Registering Services (Program.cs)

builder.Services.AddScoped<ICitiesService, CitiesService>();

That's it. ASP.NET Core handles creation and disposal.


6. DIP, IoC, DI (Easy Explanation)

DIP (Design Principle)

Depend on interfaces, not concrete classes

ICitiesService; // good
CitiesService; // bad dependency

IoC (Concept)

You don't control object creation — the framework does


DI (Implementation)

Dependencies are provided, usually via constructors

public HomeController(ICitiesService service)

7. Service Lifetimes (Very Important)

LifetimeMeaningUse Case
TransientNew instance every timeStateless helpers
ScopedOne per HTTP requestMost services
SingletonOne for entire appCache, config
AddTransient&lt;T&gt;()
AddScoped&lt;T&gt;() // ⭐ most common
AddSingleton&lt;T&gt;()

⚠️ Never inject Scoped into Singleton


8. Injection Types (Know This)

✅ Constructor Injection (Best)

public Controller(IService service)

⚠️ Method / Action Injection

public IActionResult Index([FromServices] IService service)

❌ Property Injection (Rare)

Used sparingly

Interview answer: Constructor injection is preferred


9. Why Interfaces Matter

Interfaces allow:

  • Mocking in tests
  • Swapping implementations
  • Loose coupling
ICitiesServiceCitiesService
ICitiesServiceFakeCitiesService (tests)

10. Service Scope (Quick)

  • ASP.NET Core creates one scope per request
  • All scoped services share that instance
  • Disposed automatically after request ends

Used for:

  • DbContext
  • User/session logic
  • Transactions

11. Autofac (When Mentioned)

Autofac is a more powerful DI container.

Why use it?

  • Advanced registration
  • Decorators
  • Interceptors

But:

Built-in DI is enough for most apps


12. Common DI Best Practices

  • Use interfaces
  • Prefer Scoped for services
  • Keep services stateless
  • Avoid Service Locator
  • Don't inject everything "just because"

"Services contain business logic and are injected into controllers using dependency injection. ASP.NET Core's DI container manages lifetimes, promotes loose coupling via interfaces, and improves testability and maintainability."


14. Mental Map 🧠

Controller

Service (interface)

Implementation