File: MarkupExtensions\StaticResourceExtension.cs
Web Access
Project: src\src\Controls\src\Xaml\Controls.Xaml.csproj (Microsoft.Maui.Controls.Xaml)
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Maui.Controls.Xaml.Internals;
 
namespace Microsoft.Maui.Controls.Xaml
{
	[ContentProperty(nameof(Key))]
	[RequireService([typeof(IXmlLineInfoProvider), typeof(IProvideParentValues)])]
	[ProvideCompiled("Microsoft.Maui.Controls.Build.Tasks.StaticResourceExtension")]
	public sealed class StaticResourceExtension : IMarkupExtension
	{
		public string Key { get; set; }
 
		public object ProvideValue(IServiceProvider serviceProvider)
		{
			if (serviceProvider is null)
				throw new ArgumentNullException(nameof(serviceProvider));
			if (Key is null)
				throw new XamlParseException("you must specify a key in {StaticResource}", serviceProvider);
			if (serviceProvider.GetService(typeof(IProvideValueTarget)) is not IProvideParentValues valueProvider)
				throw new ArgumentException(null, nameof(serviceProvider));
 
			if (!TryGetResource(Key, valueProvider.ParentObjects, out var resource, out var resourceDictionary)
				&& !TryGetApplicationLevelResource(Key, out resource, out resourceDictionary))
			{
				var xmlLineInfo = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) is IXmlLineInfoProvider xmlLineInfoProvider ? xmlLineInfoProvider.XmlLineInfo : null;
				throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo);
			}
 
			Diagnostics.ResourceDictionaryDiagnostics.OnStaticResourceResolved(resourceDictionary, Key, valueProvider.TargetObject, valueProvider.TargetProperty);
 
			return CastTo(resource, valueProvider.TargetProperty);
		}
 
		//used by X.HR.F
		internal static object CastTo(object value, object targetProperty)
		{
			var bp = targetProperty as BindableProperty;
			var pi = targetProperty as PropertyInfo;
 
			Type valueType = value.GetType();
			var propertyType = bp?.ReturnType ?? pi?.PropertyType;
			if (propertyType is null || propertyType.IsAssignableFrom(valueType))
				return value;
 
			if (TypeConversionHelper.TryConvert(value, propertyType, out var convertedValue))
			{
				return convertedValue;
			}
 
			return value;
		}
 
		static bool TryGetResource(string key, IEnumerable<object> parentObjects, out object resource, out ResourceDictionary resourceDictionary)
		{
			resource = null;
			resourceDictionary = null;
 
			foreach (var p in parentObjects)
			{
				var resDict = p is IResourcesProvider irp && irp.IsResourcesCreated ? irp.Resources : p as ResourceDictionary;
				if (resDict == null)
					continue;
				if (resDict.TryGetValueAndSource(key, out resource, out resourceDictionary))
					return true;
			}
			return false;
		}
 
		static bool TryGetApplicationLevelResource(string key, out object resource, out ResourceDictionary resourceDictionary)
		{
			resource = null;
			resourceDictionary = null;
			return Application.Current != null
				&& ((IResourcesProvider)Application.Current).IsResourcesCreated
				&& Application.Current.Resources.TryGetValueAndSource(key, out resource, out resourceDictionary);
		}
	}
}