C# Mastery

Dependency Injection Internals (ServiceCollection from scratch)

1 Views Updated 5/4/2026

Dependency Injection Internals

Every ASP.NET Core developer uses builder.Services.AddScoped<...>(), but few understand what happens inside the Inversion of Control (IoC) Container. To master C# architecture, you must understand how the container uses Reflection and Service Lifetimes to manage the memory and disposal of your entire application graph.

1. The Three Lifetimes

Choosing the wrong lifetime is the #1 cause of memory leaks and captive dependencies in production.

  • Transient: A brand new instance is created every time it's requested. (Lightweight, stateless).
  • Scoped: One instance is created per HTTP Request. Shared across all classes in that request.
  • Singleton: Exactly ONE instance is created for the entire life of the application. (Stateful, must be thread-safe).

2. How the Container Resolves Types

The container is essentially a giant Dictionary<Type, ServiceDescriptor>. When you ask for an IUserService, the container:

  1. Looks up the implementation type (UserService).
  2. Uses Reflection to find its constructor.
  3. Recursively resolves every parameter in that constructor.
  4. Instantiates the object and handles the lifecycle.

3. Captive Dependencies

This happens when a Singleton service mistakenly tries to inject a Scoped service. Because the Singleton never dies, it "captures" the Scoped service, keeping it alive for the entire app life. This can lead to database connection leaks or stale user data appearing for the wrong person!

4. Interview Mastery

Q: "Why should we prefer Constructor Injection over the Service Locator pattern (`serviceProvider.GetService()`)?"

Architect Answer: "Service Locator is considered an Anti-Pattern because it hides the dependencies of a class. When you use Constructor Injection, you are declaring: 'I cannot function without these 3 services.' This makes the code self-documenting and incredibly easy to Unit Test (you just pass mocks). If you use a Service Locator, the class 'lies' about its dependencies, hides its requirements inside method bodies, and becomes almost impossible to test without mocking the entire underlying .NET service provider architecture."

C# Mastery
1. Modern C# & Framework Fundamentals
Introduction to the .NET Ecosystem & Runtime (JIT, CLR) C# 12/13 Top-Level Statements & Global Usings Variables, Data Types, and Value vs Reference Deep Dive Mastering Nullable Reference Types & Null Safety The Magic of Strings (Interpolation, Verbatim, and Immutability)
2. Control Flow & Logical Structures
Advanced Pattern Matching (Switch Expressions) The Precision of Numbers: Checked vs Unchecked Math Iterators: Foreach, Yield Return, and Deferred Execution Defensive Programming: Guard Clauses and Exception Mastery
3. Object-Oriented Mastery
Classes vs Structs vs Records (Which to use when?) Mastering Primary Constructors & Object Initializers Interface Architectures: Default Implementations & Segregation Polymorphism vs Composition (The Architect's Dilemma) Partial Classes, Extension Methods, and Static Classes
4. Functional C# & Collections
Delegates, Func, Action, and Predicates Lambda Expressions & The Evolution of Linq Dynamic Array Management: List<T>, Dictionary, and HashSet Custom Collections & Yielding Data streams
5. Asynchronous & Parallel Programming
Async/Await Deep Dive: Task Lifecycle & Thread Safety Synchronization Context & Avoiding Deadlocks Parallel.ForEach vs PLINQ vs Tasks CancellationToken Mastery: Surgically Aborting Operations
6. Advanced Engineering & High Performance
Generics & Constraints: Building Type-Safe Libraries Reflection and Attributes: Reading Metadata at Runtime Dependency Injection Internals (ServiceCollection from scratch) High-Performance Memory: Span<T> and ReadOnlySpan<T> Garbage Collection Segments & LOH Internals Managing Unmanaged Resources: IDisposable & Finalizers Introduction to Source Generators & Interceptors C# Interview Masterclass: Architect-Level Explanations