A C# source generator that automatically implements static view locator for Avalonia without using reflection.
Add NuGet package reference to project.
<PackageReference Include="StaticViewLocator" Version="0.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>Annotate view locator class with [StaticViewLocator] attribute, make class partial and imlement Build using s_views dictionary to retrieve views for data objects.
[StaticViewLocator]
public partial class ViewLocator : IDataTemplate
{
public Control? Build(object? data)
{
if (data is null)
{
return null;
}
var type = data.GetType();
if (s_views.TryGetValue(type, out var func))
{
return func.Invoke();
}
throw new Exception($"Unable to create view for type: {type}");
}
public bool Match(object? data)
{
return data is ViewModelBase;
}
}Source generator will generate the s_views dictionary similar to below code using convention based on ViewModel suffix for view models subsituted to View suffix.
public partial class ViewLocator
{
private static Dictionary<Type, Func<Control>> s_views = new()
{
[typeof(StaticViewLocatorDemo.ViewModels.MainWindowViewModel)] = () => new TextBlock() { Text = "Not Found: StaticViewLocatorDemo.Views.MainWindowView" },
[typeof(StaticViewLocatorDemo.ViewModels.TestViewModel)] = () => new StaticViewLocatorDemo.Views.TestView(),
};
}You can scope which view model namespaces are considered and opt into additional behaviors.
<PropertyGroup>
<StaticViewLocatorViewModelNamespacePrefixes>MyApp.ViewModels;MyApp.Modules</StaticViewLocatorViewModelNamespacePrefixes>
<StaticViewLocatorIncludeInternalViewModels>false</StaticViewLocatorIncludeInternalViewModels>
<StaticViewLocatorIncludeReferencedAssemblies>false</StaticViewLocatorIncludeReferencedAssemblies>
<StaticViewLocatorAdditionalViewBaseTypes>MyApp.Controls.ToolWindowBase</StaticViewLocatorAdditionalViewBaseTypes>
</PropertyGroup>Defaults and behavior:
StaticViewLocatorViewModelNamespacePrefixesuses;or,separators and defaults to all namespaces.StaticViewLocatorIncludeReferencedAssembliesdefaults tofalse. Whentrue, view models from referenced assemblies are included.StaticViewLocatorIncludeInternalViewModelsdefaults tofalse. Whentrue, internal view models from referenced assemblies are included only if the referenced assembly exposes them viaInternalsVisibleTo.StaticViewLocatorAdditionalViewBaseTypesuses;or,separators and extends the default view base type list.
These properties are exported as CompilerVisibleProperty by the package, so analyzers can read them without extra project configuration.
Default view base types:
Avalonia.Controls.UserControlAvalonia.Controls.Window
Accessibility rules:
- View models in the current compilation are always eligible (subject to namespace prefixes).
- Referenced assembly view models must be public unless
StaticViewLocatorIncludeInternalViewModelsis enabled andInternalsVisibleTois configured.
StaticViewLocator is licensed under the MIT license. See LICENSE file for details.