2.2 KiB
Composition & Mapping
Ensuring your ViewModels are correctly instantiated and mapped to their corresponding Views is crucial for a maintainable application.
ViewModel-to-View Mapping
Zafiro uses the DataTypeViewLocator to automatically map ViewModels to Views based on their data type.
Integration in App.axaml
Register the DataTypeViewLocator in your application's data templates:
<Application.DataTemplates>
<DataTypeViewLocator />
<DataTemplateInclude Source="avares://Zafiro.Avalonia/DataTemplates.axaml" />
</Application.DataTemplates>
Registration
Mappings can be registered globally or locally. Common practice in Zafiro projects is to use naming conventions or explicit registrations made by source generators.
Composition Root
Use a central CompositionRoot to manage dependency injection and service registration.
public static class CompositionRoot
{
public static IShellViewModel CreateMainViewModel(Control topLevelView)
{
var services = new ServiceCollection();
services
.AddViewModels()
.AddUIServices(topLevelView);
var serviceProvider = services.BuildServiceProvider();
return serviceProvider.GetRequiredService<IShellViewModel>();
}
}
Registering ViewModels
Register ViewModels with appropriate scopes (Transient, Scoped, or Singleton).
public static IServiceCollection AddViewModels(this IServiceCollection services)
{
return services
.AddTransient<IHomeSectionViewModel, HomeSectionSectionViewModel>()
.AddSingleton<IShellViewModel, ShellViewModel>();
}
View Injection
Use the Connect helper (if available) or manual instantiation in OnFrameworkInitializationCompleted:
public override void OnFrameworkInitializationCompleted()
{
this.Connect(
() => new ShellView(),
view => CompositionRoot.CreateMainViewModel(view),
() => new MainWindow());
base.OnFrameworkInitializationCompleted();
}
Tip
Use
ActivatorUtilities.CreateInstancewhen you need to manually instantiate a class while still resolving its dependencies from theIServiceProvider.