From wpf-dev-pack
Configures Dependency Injection using Microsoft.Extensions.DependencyInjection and GenericHost in .NET console and WPF apps. Use for DI container setup, service registration, and IoC patterns.
npx claudepluginhub christian289/dotnet-with-claudecode --plugin wpf-dev-packThis skill uses the workspace's default tool permissions.
> **MVVM Framework Rule**: `.claude/rules/dotnet/wpf/mvvm-framework.md` 설정에 따라 코드 스타일이 결정됩니다.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
MVVM Framework Rule:
.claude/rules/dotnet/wpf/mvvm-framework.md설정에 따라 코드 스타일이 결정됩니다. Prism 9 사용 시 → PRISM.md 참조
A guide on using Dependency Injection and GenericHost in .NET projects.
// 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);
}
}
}
// 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
namespace MyApp;
using System.Windows;
public partial class MainWindow : Window
{
// ViewModel injection through Constructor Injection
public MainWindow(MainViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}
// 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);
}
}
}
Creates only one instance throughout the application
services.AddSingleton<IUserRepository, UserRepository>()Creates one instance per request (Scope)
services.AddScoped<IUserService, UserService>()Creates a new instance on every request
services.AddTransient<MainViewModel>()// 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>();
}
}
// 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();
}
}
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
</ItemGroup>