C#
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C#
-
Section 4: Working with Data
-
Section 5: Error Handling
-
Section 6: Delegates and Events
-
Section 7: Async Programming
-
Section 8: More Language Features
-
Section 9: File I/O and Serialization
-
Section 10: Networking in .NET
-
Section 11: The .NET Ecosystem
-
Section 12: Memory and Performance
-
Section 13: Concurrency Beyond Async
-
Section 14: Reflection and Attributes
-
Section 15: Testing and Best Practices
-
Section 16: Design Patterns in C#
-
Section 17: Standard Library Deep Dive
-
Section 18: Data Structures and Algorithms in C#
-
Section 19: GUI and Desktop Development Overview
-
Section 20: Practical Projects
-
Section 21: More Practice Exercises
-
Section 22: More Standard Library and Text Processing
-
Section 23: More Design Patterns
-
Section 24: More Projects
-
Section 25: Interview Practice
-
Section 26: C# Keywords Reference (Modifiers)
-
Section 27: C# Keywords Reference (Statements)
-
Section 28: C# Keywords Reference (Operators)
-
Section 29: BCL: System.Collections.Generic
-
Section 30: BCL: System.Linq
-
Section 31: BCL: System.Threading
-
Section 32: BCL: System.IO
-
Section 33: BCL: System.Text and System.Text.Json
-
Section 34: BCL: System.Net.Http
-
Section 35: C# Language Specification Topics
-
Section 36: More Practice Exercises
-
Section 37: More Async Patterns
-
Section 38: More BCL: System.Reflection and System.Diagnostics
-
Section 39: Nullable Reference Types In Depth
-
Section 40: C# Records and Pattern Matching In Depth
-
Section 41: Dependency Injection Deep Dive
-
Section 42: More Interview and Whiteboard Practice
81: The Microsoft.Extensions Ecosystem
Imagine you're building a modular home. Instead of wiring the electricity and plumbing directly into the walls in a way that can never be changed, you install a standardized "utility hub." This hub has specific sockets for power, water, and gas. Because everything follows a standard interface, it doesn't matter if your water heater is a gas model from one brand or an electric model from another; as long as it plugs into the standard "water heater" socket, the rest of the house just works.
The Microsoft.Extensions ecosystem is exactly that utility hub for your .NET applications. For a long time, these tools were locked inside ASP.NET Core, but Microsoft eventually realized that every app—whether it's a tiny console tool, a background worker, or a massive web API—needs the same basic "utilities": a way to handle settings, a way to log errors, and a way to manage object lifetimes (Dependency Injection).
Here is how that analogy maps to the code you'll actually use:
- The Utility Hub is the
IServiceCollection. It's the central registry where you define which "appliances" your app will use. - The Standard Sockets are the interfaces like
ILogger,IConfiguration, andIHost. Your business logic doesn't care how a log is written; it just knows there's a socket it can plug into to send a message. - The Appliances are the NuGet packages (like
Microsoft.Extensions.Logging.Console). You can swap a Console logger for a File logger or an Azure Application Insights logger without changing a single line of your core logic.
The Engine Room: IServiceCollection
When you see IServiceCollection, you're looking at the heart of the ecosystem. I've seen too many developers try to manually instantiate their dependencies using the new keyword everywhere. That's like hard-wiring your toaster into the house's main electrical panel. If you want to change the toaster, you have to call an electrician and rip open the wall.
By using the Extensions ecosystem, you register your services at the start of the application. This allows you to decouple the definition of a service from its implementation.
// This is the "plugging in" phase var services = new ServiceCollection(); // I'm telling the app: "Whenever someone asks for IWeatherService, give them the OpenWeather implementation" services.AddTransient<IWeatherService, OpenWeatherService>(); // Now we build the provider (the hub is now live) var serviceProvider = services.BuildServiceProvider();Handling Settings with the Options Pattern
One of the most powerful parts of this ecosystem is how it handles configuration. In the old days, we'd read a
web.configfile and manually parse strings. It was brittle and a nightmare to test. The modern approach usesIConfigurationand the Options pattern.The magic here is that you can map a section of a JSON file directly to a plain old C# class (POCO). I personally love this because it gives you strongly-typed settings with IntelliSense, rather than hunting through a config file for a typo in a key name like "SmtpServerPort".
// A simple class to hold our settings public class SmtpSettings { public string Server { get; set; } public int Port { get; set; } } // In your setup code: services.Configure<SmtpSettings>(configuration.GetSection("Smtp")); // In your actual service: public class EmailSender { private readonly SmtpSettings _settings; // We inject IOptions<T>, which is the standard "socket" for settings public EmailSender(IOptions<SmtpSettings> options) { _settings = options.Value; } }Tying it Together with the Generic Host
If you're tired of manually setting up the
ServiceCollection,ConfigurationBuilder, andLoggerFactoryevery time, you use theIHost. The Generic Host is essentially a "pre-packaged house" that comes with the utility hub already installed.When you use
Host.CreateDefaultBuilder(), .NET does a lot of heavy lifting for you: it loadsappsettings.json, sets up environment variables, and configures the default logging providers. It's the gold standard for any professional C# application today, regardless of whether it has a user interface or not.
📋 Practical Task
Build a Configurable Background Stock-Ticker Service
Your goal is to create a console application that simulates a stock price ticker. Instead of hard-coding the settings, you will use the Microsoft.Extensions ecosystem to make it professional and modular.
Requirements:
- Configuration: Create an
appsettings.jsonfile containing a section called"TickerSettings"with two properties:Symbol(string) andRefreshIntervalSeconds(int). - Options Pattern: Create a
TickerSettingsclass and useservices.Configure<TickerSettings>(...)to bind it. - Dependency Injection: Create an
IStockProviderinterface and aMockStockProviderimplementation that returns a random price for the configured symbol. - The Host: Use
Host.CreateDefaultBuilderto wire everything together. Your main logic should reside in a class that implementsIHostedService(or simply a class that is resolved from theIServiceProviderinMain). - Logging: Use
ILogger<T>to log the stock price to the console every time it refreshes, rather than usingConsole.WriteLine.
Success Criteria: Changing the Symbol or RefreshIntervalSeconds in the JSON file should change the behavior of the program without requiring a re-compile of the C# code.
There are no comments for now.