mvvm-toolkit-di
Helps your agent connect parts of .NET applications. It manages how components communicate and are created.
What it does
This 'skill' helps connect parts of your code (called ViewModels) with other parts that provide services (like saving files or sending messages) in an organized way. It uses a system called 'Dependency Injection' so the right parts find each other automatically.
When to use it
- ✓When you're setting up a new app with a graphical interface (WPF, MAUI, etc.) and need to organize how different parts of your program talk to each other.
- ✓To decide how long a service or ViewModel should exist (forever, only when needed, etc.).
- ✓To ensure message communication between app parts is set up correctly and available where needed.
Example of what to ask your AI
“How do I set up my app so it knows how to create and provide my ViewModels and services?”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
It uses a system called 'Dependency Injection' that acts like an organizer. You tell it what services exist and how to create them, and it handles delivering them automatically to where they are needed, usually through the constructors of classes.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add github/awesome-copilot --skill mvvm-toolkit-diOr download just the file:
curl -L https://raw.githubusercontent.com/github/awesome-copilot/main/skills/mvvm-toolkit-di/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
CommunityToolkit.Mvvm + Microsoft.Extensions.DependencyInjection
The MVVM Toolkit deliberately ships no DI container — it composes with
Microsoft.Extensions.DependencyInjection, the same container ASP.NET
Core, Worker services, and the .NET Generic Host use.
TL;DR. Build the service provider once at startup (prefer
Host.CreateDefaultBuilder()). Register services and ViewModels. Inject through constructors. AvoidIoc.Default.GetService<T>()in user code.
When to use this skill
- Standing up the composition root for a new XAML app (WPF, WinUI 3, MAUI, Uno, Avalonia)
- Choosing service/VM lifetimes
- Wiring
IMessengeronce and injecting it intoObservableRecipientViewModels - Resolving a page's ViewModel without coupling to a service locator
- Diagnosing "Unable to resolve service for type X while attempting to activate Y"
For source generators and ViewModel patterns see the mvvm-toolkit
skill. For Messenger pub/sub see mvvm-toolkit-messenger.
Recommended composition root (Generic Host)
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using CommunityToolkit.Mvvm.Messaging;
public partial class App : Application
{
public IHost Host { get; }
public App()
{
Host = Microsoft.Extensions.Hosting.Host
.CreateDefaultBuilder()
.ConfigureServices((_, services) =>
{
services.AddSingleton<IFilesService, FilesService>();
services.AddSingleton<ISettingsService, SettingsService>();
services.AddSingleton<IMessenger>(WeakReferenceMessenger.Default);
services.AddSingleton<ShellViewModel>();
services.AddTransient<ContactViewModel>();
services.AddTransient<EditorViewModel>();
})
.Build();
}
public static T GetService<T>() where T : class =>
((App)Current).Host.Services.GetRequiredService<T>();
}
Generic Host benefits:
appsettings.jsonbinding viaMicrosoft.Extensions.Configuration- Logging via
Microsoft.Extensions.Logging - Hosted services (
IHostedService) for background work - Scope validation in development builds
WPF and Windows Forms must integrate the host lifetime with the app lifetime — see Use the .NET Generic Host in a WPF app.
Without Generic Host
When you only need a service container and want zero extra dependencies:
var services = new ServiceCollection();
services.AddSingleton<IFilesService, FilesService>();
services.AddTransient<ContactViewModel>();
ServiceProvider provider = services.BuildServiceProvider();
Constructor injection
Inject services and child ViewModels through the constructor:
public sealed partial class ContactViewModel(
IFilesService files,
IMessenger messenger,
ILogger<ContactViewModel> logger)
: ObservableRecipient(messenger)
{
[ObservableProperty]
private string? name;
[RelayCommand]
private async Task SaveAsync()
{
logger.LogInformation("Saving {Name}", Name);
await files.SaveAsync(Name!);
}
}
Why constructor injection beats a service locator:
- Dependencies are explicit and visible at the call site
- Unit tests inject fakes/mocks directly
- The DI container validates the dependency graph at startup
- Missing registrations throw immediately, not at first use
Lifetimes
| Lifetime | Method | Typical use in XAML apps |
|---|---|---|
| Singleton | AddSingleton<T> |
Shell/main-window VM, settings, file/HTTP services, the shared IMessenger, app-wide caches |
| Transient | AddTransient<T> |
Per-page or per-document ViewModels (a fresh instance every resolve) |
| Scoped | AddScoped<T> |
Rarely needed in client apps; useful with explicit IServiceScope (e.g., per-window scopes) |
services.AddSingleton<ShellViewModel>(); // 1 instance for app lifetime
services.AddTransient<NoteViewModel>(); // new instance per resolve
services.AddScoped<DialogService>(); // 1 per scope (rare)
Resolving in a View
Resolve the page's root ViewModel in code-behind, then let it pull its own dependencies:
public sealed partial class ContactPage : Page
{
public ContactViewModel ViewModel { get; }
…
FAQ
What is 'Dependency Injection'?
It's a way to organize your code where, instead of a class creating its own dependencies (other classes it needs), those dependencies are 'injected' (provided) from the outside. This makes code more flexible and easier to test.
What's the difference between Singleton, Transient, and Scoped?
Singleton: only one instance exists for the entire app lifetime. Transient: a new instance is created every time it's requested. Scoped: an instance is created per specific 'scope', like a window or a request (less common in desktop apps).
Why shouldn't I create my ViewModels manually?
Manual creation can lead to code that's harder to manage and test. Using 'Dependency Injection' ensures dependencies are resolved correctly, and you don't have to worry about how to create them every time.
Details
Original description by the author
Wire CommunityToolkit.Mvvm ViewModels into Microsoft.Extensions.DependencyInjection. Covers the .NET Generic Host composition root, constructor injection, service lifetimes (Singleton / Transient / Scoped), IMessenger registration, resolving ViewModels in Views, keyed services, testing seams, and the legacy Ioc.Default escape hatch. Use across WPF, WinUI 3, .NET MAUI, Uno, and Avalonia.
repo: github/awesome-copilot
Popularity
- GitHub stars
- 40k
- Ranking position
- #5245
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
acquire-codebase-knowledge
Helps your agent understand and document an existing code project. It's useful for onboarding new people or getting an overview of the architecture.
github/awesome-copilot
acreadiness-assess
Enables your agent to assess a project's readiness for AI and generate a report. It's useful for understanding how well a project is prepared to use AI tools.
github/awesome-copilot
acreadiness-generate-instructions
Helps your agent create instructions for AI tools based on an assessment. It's useful for improving how AI interacts with code and closing identified gaps.
github/awesome-copilot
acreadiness-policy
Enables your agent to help define or apply policies for AI project assessment. It's useful for standardizing how projects are evaluated and ensuring compliance.
github/awesome-copilot
Similar skills
api-connector-builder
Has your agent build new API connections following the existing pattern. Use when you need to add one more integration without creating a new way of doing things.
affaan-m/ECC
api-design
Helps your agent design REST APIs following best practices. It's useful for defining how APIs communicate, how errors are shown, and how to organize data.
affaan-m/ECC
backend-patterns
Helps your agent with server-side architecture patterns and database optimization. It's useful for building or reviewing code that runs on the server.
affaan-m/ECC