Browse Source

Make MarkupExtension.ProvideValue method inlinable for StaticResourceExtension and ResolveByNameExtension (#17659)

release/11.2.3
Max Katz 1 year ago
parent
commit
476ee2be62
  1. 10
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs
  2. 20
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs

10
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs

@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
using Avalonia.Controls;
using Avalonia.Data.Core;
@ -13,14 +14,17 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public string Name { get; }
public object? ProvideValue(IServiceProvider serviceProvider)
public object? ProvideValue(IServiceProvider serviceProvider) => ProvideValue(serviceProvider, Name);
[MethodImpl(MethodImplOptions.NoInlining)]
private static object? ProvideValue(IServiceProvider serviceProvider, string name)
{
var nameScope = serviceProvider.GetService<INameScope>();
if (nameScope is null)
return null;
var value = nameScope.FindAsync(Name);
var value = nameScope.FindAsync(name);
if(value.IsCompleted)
return value.GetResult();

20
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using Avalonia.Controls;
using Avalonia.Markup.Data;
using Avalonia.Markup.Xaml.Converters;
@ -22,9 +23,14 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public object? ResourceKey { get; set; }
public object? ProvideValue(IServiceProvider serviceProvider)
// Keep instance method ProvideValue as simple as possible, increasing chance to inline it.
// With modern runtimes, inlining this method also helps to eliminate extension allocation completely.
public object? ProvideValue(IServiceProvider serviceProvider) => ProvideValue(serviceProvider, ResourceKey);
[MethodImpl(MethodImplOptions.NoInlining)]
private static object? ProvideValue(IServiceProvider serviceProvider, object? resourceKey)
{
if (ResourceKey is not { } resourceKey)
if (resourceKey is null)
{
throw new ArgumentException("StaticResourceExtension.ResourceKey must be set.");
}
@ -87,20 +93,16 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
{
// This is stored locally to avoid allocating closure in the outer scope.
var localTargetType = targetType;
var localInstance = this;
var localKeyInstance = resourceKey;
DelayedBinding.Add(target, property, x => localInstance.GetValue(x, localTargetType));
DelayedBinding.Add(target, property, x =>
ColorToBrushConverter.Convert(x.FindResource(localKeyInstance), localTargetType));
return AvaloniaProperty.UnsetValue;
}
throw new KeyNotFoundException($"Static resource '{resourceKey}' not found.");
}
private object? GetValue(StyledElement control, Type? targetType)
{
return ColorToBrushConverter.Convert(control.FindResource(ResourceKey!), targetType);
}
internal static ThemeVariant? GetDictionaryVariant(IAvaloniaXamlIlParentStackProvider? stack)
{
switch (stack)

Loading…
Cancel
Save