← Back to list

configuring-dependency-injection
by christian289
ClaudeCode와 함께하는 .NET 개발 튜토리얼
⭐ 1🍴 0📅 Jan 25, 2026
SKILL.md
name: configuring-dependency-injection description: "Configures Dependency Injection using Microsoft.Extensions.DependencyInjection and GenericHost. Use when setting up DI container, registering services, or implementing IoC patterns in .NET projects."
Dependency Injection and GenericHost Usage
A guide on using Dependency Injection and GenericHost in .NET projects.
Core Principles
- Implement dependency injection using Microsoft.Extensions.DependencyInjection
- Use GenericHost (Microsoft.Extensions.Hosting) as the default
- Apply service injection through Constructor Injection
Console and General Projects - Program.cs
// Program.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// Configure DI using GenericHost
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
// Register services
services.AddSingleton<IUserRepository, UserRepository>();
services.AddScoped<IUserService, UserService>();
services.AddTransient<IEmailService, EmailService>();
// Register main application service
services.AddSingleton<App>();
})
.Build();
// Get service through ServiceProvider
var app = host.Services.GetRequiredService<App>();
await app.RunAsync();
// Application class - Constructor Injection
public sealed class App(IUserService userService, IEmailService emailService)
{
private readonly IUserService _userService = userService;
private readonly IEmailService _emailService = emailService;
public async Task RunAsync()
{
// Use injected services
var users = await _userService.GetAllUsersAsync();
foreach (var user in users)
{
await _emailService.SendWelcomeEmailAsync(user.Email);
}
}
}
WPF Project - App.xaml.cs
// App.xaml.cs
namespace MyApp;
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public partial class App : Application
{
private readonly IHost _host;
public App()
{
// Create GenericHost and register services
_host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// Register services
services.AddSingleton<IUserRepository, UserRepository>();
services.AddSingleton<IUserService, UserService>();
services.AddTransient<IDialogService, DialogService>();
// Register ViewModels
services.AddTransient<MainViewModel>();
services.AddTransient<SettingsViewModel>();
// Register Views
services.AddSingleton<MainWindow>();
})
.Build();
}
protected override async void OnStartup(StartupEventArgs e)
{
await _host.StartAsync();
// Get MainWindow from ServiceProvider
var mainWindow = _host.Services.GetRequiredService<MainWindow>();
mainWindow.Show();
base.OnStartup(e);
}
protected override async void OnExit(ExitEventArgs e)
{
using (_host)
{
await _host.StopAsync();
}
base.OnExit(e);
}
}
MainWindow.xaml.cs - Constructor Injection
// MainWindow.xaml.cs
namespace MyApp;
using System.Windows;
public partial class MainWindow : Window
{
// ViewModel injection through Constructor Injection
public MainWindow(MainViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}
ViewModel - Constructor Injection
// ViewModels/MainViewModel.cs
namespace MyApp.ViewModels;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public sealed partial class MainViewModel : ObservableObject
{
private readonly IUserService _userService;
private readonly IDialogService _dialogService;
// Constructor Injection
public MainViewModel(IUserService userService, IDialogService dialogService)
{
_userService = userService;
_dialogService = dialogService;
LoadDataAsync();
}
[ObservableProperty] private ObservableCollection<User> _users = [];
[RelayCommand]
private async Task LoadDataAsync()
{
try
{
var userList = await _userService.GetAllUsersAsync();
Users = new ObservableCollection<User>(userList);
}
catch (Exception ex)
{
await _dialogService.ShowErrorAsync("Error occurred", ex.Message);
}
}
}
Service Lifetime Rules
Singleton
Creates only one instance throughout the application
- Repository, global state management services
services.AddSingleton<IUserRepository, UserRepository>()
Scoped
Creates one instance per request (Scope)
- DbContext, transaction-based services
services.AddScoped<IUserService, UserService>()- ⚠️ Generally not used in WPF (mainly used in Web applications)
Transient
Creates a new instance on every request
- ViewModel, one-time services
services.AddTransient<MainViewModel>()
Direct Use of ServiceProvider (Not Recommended)
Anti-pattern: Service Locator
// Service Locator pattern (anti-pattern)
public sealed class SomeClass
{
private readonly IServiceProvider _serviceProvider;
public SomeClass(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void DoSomething()
{
// ⚠️ Not recommended: Using ServiceProvider directly
var service = _serviceProvider.GetRequiredService<IUserService>();
}
}
Recommended: Constructor Injection
// Correct way: Use Constructor Injection
public sealed class SomeClass
{
private readonly IUserService _userService;
public SomeClass(IUserService userService)
{
_userService = userService;
}
public void DoSomething()
{
// ✅ Recommended: Use service injected through Constructor Injection
_userService.GetAllUsersAsync();
}
}
Required NuGet Packages
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
</ItemGroup>
Score
Total Score
65/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon
