Welcome! This is a beginner-friendly tutorial project demonstrating Dependency Injection (DI) concepts in C# across multiple .NET platforms. This repository is designed to accompany my YouTube tutorial series.
Dependency Injection is a design pattern that helps you write cleaner, more maintainable, and testable code. Instead of objects creating their own dependencies, you "inject" them from the outside.
- β Loose Coupling - Components are less dependent on each other
- β Easy Testing - Mock dependencies for unit tests
- β Maintainability - Easier to modify and extend code
- β Flexibility - Swap implementations without changing code
This solution demonstrates DI with a real-world analogy: Writers using different Writing Instruments (Pens, Pencils, etc.) across two different .NET platforms.
DependencyInjectionTutorial/
β
βββ net472/ # .NET Framework 4.7.2 Examples
β βββ TutorialDI.App/ # Console application (entry point)
β β βββ Program.cs
β β βββ RunManualDI.cs # Example 1: Manual DI
β β βββ RunContainerDI.cs # Example 2: Using Autofac container
β β βββ App.config
β β βββ TutorialDI.App.csproj
β β
β βββ TutorialDI.Core/ # Core abstractions & interfaces
β β βββ IWritingInstrument.cs # Interface for writing instruments
β β βββ Writer.cs # Writer class that uses an instrument
β β βββ TutorialDI.Core.csproj
β β
β βββ TutorialDI.Instrument/ # Concrete implementations
β βββ Pencil.cs
β βββ BallPen.cs
β βββ FountainPen.cs
β βββ GelPen.cs
β βββ TutorialDI.Instrument.csproj
β
βββ netcore/ # .NET Core (Modern .NET) Examples
β βββ TutorialDI.NetCore.Example/ # Single project with all examples
β βββ Program.cs # Entry point (console app)
β βββ TutorialDI.NetCore.Example.csproj
β βββ Core/ # Core abstractions
β β βββ IWritingInstrument.cs
β β βββ Writer.cs
β βββ Instrument/ # Concrete implementations
β βββ Pencil.cs
β βββ FountainPen.cs
β
βββ Shared Documentation/
βββ README.md # This file
βββ CONTRIBUTING.md # Contribution guidelines
βββ LICENSE.txt # MIT License
βββ .gitattributes # Git line ending config
- Visual Studio 2019+ or Visual Studio Code
- .NET Framework 4.7.2+ (for .NET Framework examples)
- .NET 10.0+ (for .NET Core examples)
- Basic understanding of C# and OOP concepts
-
Clone the repository:
git clone https://github.com/YourUsername/DependencyInjectionTutorial.git cd DependencyInjectionTutorial -
Open in Visual Studio:
- Open
DependencyInjectionTutorial.slnxin Visual Studio - Or open individual projects in VS Code
- Open
-
Restore NuGet Packages:
- Visual Studio will auto-restore
- Or run:
nuget restore
-
Build the Solution:
- Press
Ctrl + Shift + Bor go to Build > Build Solution
- Press
-
Run Applications:
For .NET Framework (net472):
- Set
TutorialDI.Appas the startup project - Press
F5or click Start
For .NET Core (netcore):
- Set
TutorialDI.NetCore.Exampleas the startup project - Press
F5or click Start
- Set
// β BAD: Writer is tightly coupled to Pencil
public class Writer
{
private Pencil pencil = new Pencil(); // Hard-coded dependency
public void Write()
{
pencil.DrawMark();
}
}Issues:
- Can't use a different instrument without changing the code
- Hard to test (can't mock the Pencil)
- Not flexible for future changes
// β
GOOD: Writer depends on abstraction, not concrete class
public class Writer
{
private IWritingInstrument instrument;
// Dependencies are injected through constructor
public Writer(IWritingInstrument instrument)
{
this.instrument = instrument;
}
public void Write()
{
instrument.DrawMark();
}
}
// Now you can use any writing instrument:
var pencil = new Pencil();
var writer = new Writer(pencil);
writer.Write();
var pen = new BallPen();
var writer2 = new Writer(pen);
writer2.Write();Manually creating and passing dependencies:
// Create dependencies
IWritingInstrument pencil = new Pencil();
IWritingInstrument ballPen = new BallPen();
// Inject into Writer
Writer writer1 = new Writer(pencil);
Writer writer2 = new Writer(ballPen);
// Use them
writer1.Write();
writer2.Write();Pros: Simple, no external dependencies
Cons: Manual management, gets complex with many dependencies
// Configure container
var builder = new ContainerBuilder();
builder.RegisterType<Pencil>().As<IWritingInstrument>();
builder.RegisterType<Writer>();
using (var container = builder.Build())
{
// Resolve dependencies automatically
var writer = container.Resolve<Writer>();
writer.Write();
}// Configure services
var services = new ServiceCollection();
services.AddScoped<IWritingInstrument, Pencil>();
services.AddScoped<Writer>();
var serviceProvider = services.BuildServiceProvider();
// Resolve dependencies automatically
var writer = serviceProvider.GetRequiredService<Writer>();
writer.Write();Pros: Scalable, automatic dependency resolution, easy to manage
Cons: Additional dependencies, slightly more complex setup
| Feature | .NET Framework 4.7.2 | .NET Core 10.0 |
|---|---|---|
| DI Container | Autofac | Microsoft.Extensions.DI |
| Project Structure | Multi-project | Single project |
| Configuration | App.config | appsettings.json (if added) |
| Execution | Console app (.exe) | Console app (.exe/.dll) |
| Performance | Good | Excellent |
| Cross-platform | Windows only | Windows, Mac, Linux |
| Use Case | Legacy/Enterprise | Modern/Cloud |
Purpose: Contains abstractions (interfaces) and core classes
-
IWritingInstrument.cs- Interface defining what a writing instrument can dopublic interface IWritingInstrument { void DrawMark(); }
-
Writer.cs- Class that depends onIWritingInstrumentpublic class Writer { private readonly IWritingInstrument instrument; public Writer(IWritingInstrument instrument) { this.instrument = instrument; } public void Write() { // Calls the injected instrument instrument.DrawMark(); } }
Purpose: Concrete implementations of IWritingInstrument
Pencil.cs- ImplementsIWritingInstrumentBallPen.cs- ImplementsIWritingInstrument(Framework only)FountainPen.cs- ImplementsIWritingInstrumentGelPen.cs- ImplementsIWritingInstrument(Framework only)
Each class implements the interface differently, showing how DI allows you to swap implementations.
Purpose: Console application demonstrating both approaches
Program.cs- Entry point, menu to choose which example to runRunManualDI.cs- Example: Manual dependency injectionRunContainerDI.cs- Example: Using Autofac DI container
Purpose: Console application demonstrating .NET Core built-in DI
Program.cs- Entry point with integrated DI setup using Microsoft.Extensions.DependencyInjection
| Technology | Version | Purpose | Platform |
|---|---|---|---|
| .NET Framework | 4.7.2 | Application framework | net472 |
| .NET Core | 10.0 | Modern framework | netcore |
| C# | 7.3+ | Programming language | Both |
| Autofac | 9.0.0 | DI Container | net472 |
| Microsoft.Extensions.DI | Latest | Built-in DI | netcore |
| Visual Studio | 2019+ | IDE | Both |
After completing this tutorial, you will:
- β Understand the concept of Dependency Injection
- β Recognize tight coupling problems in code
- β Implement manual dependency injection
- β Use DI containers (Autofac & Microsoft.Extensions.DI)
- β Know the differences between .NET Framework and .NET Core DI
- β Know when and how to apply DI in your projects
- β Write more testable and maintainable code
- β Understand modern .NET development practices
One major benefit of DI is testability. Here's how you'd test the Writer class:
// Mock implementation for testing
public class MockPen : IWritingInstrument
{
public void DrawMark()
{
// Test behavior
}
}
// In your test
[TestMethod]
public void Writer_ShouldUseInjectedInstrument()
{
var mockPen = new MockPen();
var writer = new Writer(mockPen);
writer.Write();
// Verify behavior
}Follow along with these videos:
- Part 1: Introduction to Dependency Injection
- Part 2: Understanding the Problem (Tight Coupling)
- Part 3: Manual Dependency Injection (.NET Framework)
- Part 4: Using Autofac DI Container (.NET Framework)
- Part 5: Dependency Injection in .NET Core
- Part 6: Built-in DI in Microsoft.Extensions
- Part 7: Best Practices & Common Mistakes
- Bonus: Framework vs Core Comparison
π Each video corresponds to the code in this repository
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License - see LICENSE.txt for details.
A: Start with .NET Framework (net472) if you're learning DI basics. Then move to .NET Core to see modern practices.
A: No! This tutorial starts from scratch and explains everything. Autofac is introduced in the second approach for Framework.
A: Autofac is a third-party container with advanced features. Microsoft.Extensions.DI is built-in and simpler, perfect for modern .NET Core apps.
A: This is a tutorial project for learning. For production, use industry-standard practices with proper DI containers.
A: To show you that DI concepts are universal, but implementations differ between platforms.
A: Make sure all NuGet packages are restored. Run nuget restore in the Package Manager Console.
- Microsoft Docs: Dependency Injection
- Autofac Documentation
- SOLID Principles
- .NET Framework vs .NET Core
Subrata Mohanta
A passionate software developer and educator dedicated to making complex concepts simple and understandable. This tutorial series is designed to help developers at all levels master Dependency Injection across multiple .NET platforms.
- π LinkedIn: linkedin.com/in/subratamohanta
- πΊ YouTube: TechnicalOdiyaToka
- π» GitHub: @subratamohanta
- Issues: Open an issue on GitHub
- Discussions: Use GitHub Discussions
- YouTube: Comment on the tutorial videos
- LinkedIn: Connect with me on LinkedIn
Happy Learning! π
Last Updated: December 6, 2025
Author: Subrata Mohanta