IServiceProvider Patterns in Markup ExtensionsPrimary APIs:
AvaloniaRuntimeXamlLoader.Load(...)AvaloniaRuntimeXamlLoader.LoadGroup(...)RuntimeXamlLoaderDocumentRuntimeXamlLoaderConfigurationIProvideValueTargetIRootObjectProviderIUriContextIXamlTypeResolverIAvaloniaXamlIlParentStackProviderIAvaloniaXamlIlEagerParentStackProviderXamlSourceInfoReference source files:
src/Markup/Avalonia.Markup.Xaml/RuntimeXamlLoaderDocument.cssrc/Markup/Avalonia.Markup.Xaml/RuntimeXamlLoaderConfiguration.cssrc/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cssrc/Markup/Avalonia.Markup.Xaml/XamlTypes.cssrc/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/IAvaloniaXamlIlParentStackProvider.cssrc/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cssrc/Markup/Avalonia.Markup.Xaml/Diagnostics/XamlSourceInfo.cstests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlSourceInfoTests.csUse three explicit layers:
RootInstance, BaseUri, diagnostics config).There is no supported public API for injecting custom XamlIl AST transformers from application code.
For dynamic scenarios, mutate XAML text before calling runtime loader.
using System.Xml.Linq;
using Avalonia.Markup.Xaml;
var doc = XDocument.Parse(rawXaml);
// Example: mutate root attributes based on plugin settings.
doc.Root?.SetAttributeValue("Opacity", "0.8");
var loaded = AvaloniaRuntimeXamlLoader.Load(doc.ToString());
Use this when plugin metadata or feature flags must alter markup before load.
RootInstance lets you populate an existing object instead of constructing a new one.
using Avalonia.Markup.Xaml;
var existing = new MyControl();
var runtimeDoc = new RuntimeXamlLoaderDocument(
baseUri: new Uri("avares://MyPlugin/Views/MyControl.axaml"),
rootInstance: existing,
xaml: xamlText)
{
Document = "/plugins/MyControl.axaml"
};
AvaloniaRuntimeXamlLoader.Load(runtimeDoc, new RuntimeXamlLoaderConfiguration
{
LocalAssembly = typeof(MyControl).Assembly,
UseCompiledBindingsByDefault = true
});
This pattern is useful for hot-reload-like replacement without replacing the outer object identity.
After load, manipulate standard Avalonia object graph APIs:
ResourceDictionary,For include-heavy runtime sets, prefer LoadGroup so cross-document references resolve consistently in one pass.
IServiceProvider Patterns in Markup ExtensionsCustom markup extensions can inspect loader context through public services.
using System;
using Avalonia.Markup.Xaml;
public sealed class DebugContextExtension
{
public object? ProvideValue(IServiceProvider serviceProvider)
{
var target = (IProvideValueTarget?)serviceProvider.GetService(typeof(IProvideValueTarget));
var root = (IRootObjectProvider?)serviceProvider.GetService(typeof(IRootObjectProvider));
var uri = (IUriContext?)serviceProvider.GetService(typeof(IUriContext));
return $"Target={target?.TargetObject?.GetType().Name}; " +
$"Root={root?.RootObject?.GetType().Name}; " +
$"BaseUri={uri?.BaseUri}";
}
}
Context services are particularly useful when extension behavior depends on target property or root scope.
For runtime tooling/debugging:
RuntimeXamlLoaderDocument.Document,RuntimeXamlLoaderConfiguration.CreateSourceInfo = true.Then inspect XamlSourceInfo on loaded objects for file/line mapping.
using Avalonia.Markup.Xaml.Diagnostics;
var info = XamlSourceInfo.GetXamlSourceInfo(loadedControl);
Not intended as app-level extension points:
AvaloniaXamlIlCompiler and transformer pipeline classes,Avalonia.Markup.Xaml.Extensions,For app/library code, stay on public runtime loader, markup extension interfaces, and standard control/resource APIs.
RuntimeXamlLoaderDocument.BaseUri is set.CreateSourceInfo=true and provide Document path.