WinUI Injector to help Injection of Classes
$ dotnet add package InjectorWinUIThis guide demonstrates how to implement a simple dependency injection (DI) container in a WinUI 3 project. The DI container allows for both singleton and transient instances, enabling flexible and maintainable dependency management.
We created:
DIContainer class to manage dependencies.[InjectSingle] and [Inject] to mark fields for dependency injection.DIHelper class to handle the injection of dependencies.The DIContainer class manages both singleton and transient dependencies. It supports registering factories for creating instances and resolving these instances when needed.
using System;
using System.Collections.Generic;
public class DIContainer
{
private readonly Dictionary<Type, Func<object>> _transientTypes = new();
private readonly Dictionary<Type, object> _singletonInstances = new();
private readonly Dictionary<Type, Type> _singletonTypes = new();
public void RegisterTransient<T>(Func<T> factory) where T : class
{
_transientTypes[typeof(T)] = () => factory();
}
public void RegisterSingleton<T>(Func<T> factory) where T : class
{
_singletonTypes[typeof(T)] = typeof(T);
_singletonInstances[typeof(T)] = factory();
}
public T Resolve<T>() where T : class
{
if (_singletonInstances.ContainsKey(typeof(T)))
{
return (T)_singletonInstances[typeof(T)];
}
if (_transientTypes.ContainsKey(typeof(T)))
{
return (T)_transientTypes[typeof(T)]();
}
throw new InvalidOperationException($"Type {typeof(T)} not registered.");
}
public object Resolve(Type type)
{
if (_singletonInstances.ContainsKey(type))
{
return _singletonInstances[type];
}
if (_transientTypes.ContainsKey(type))
{
return _transientTypes[type]();
}
throw new InvalidOperationException($"Type {type} not registered.");
}
}
Here's how you can use the DI container and inject dependencies in your WinUI 3 application.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
namespace YourNamespace
{
public sealed partial class MainPage : Page
{
[InjectSingle]
private YourSingletonService singletonService;
[Inject]
private YourTransientService transientService;
public MainPage()
{
this.InitializeComponent();
// Setup dependency injection container
var container = new DIContainer();
container.RegisterSingleton(() => new YourSingletonService());
container.RegisterTransient(() => new YourTransientService());
// Inject dependencies
DIHelper.InjectDependencies(this, container);
// Use the injected dependencies
Initialize();
}
private void Initialize()
{
// Use the singletonService and transientService
}
}
}
� DIContainer: Manages both singleton and transient dependencies. Supports registering factories and resolving instances. � Inject Attributes: Custom attributes [InjectSingle] and [Inject] mark fields for dependency injection. � DIHelper: Scans fields in a target object and injects dependencies based on the custom attributes. � Example Usage: Demonstrates how to set up the DI container, register dependencies, and inject them into a WinUI 3 page.
This approach provides a basic but functional dependency injection mechanism in your WinUI 3 project, allowing for better code organization and maintainability.