| File: DependencyResolver.cs | Web Access |
| Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls) |
#nullable disable using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; namespace Microsoft.Maui.Controls.Internals { /// <include file="../../docs/Microsoft.Maui.Controls.Internals/DependencyResolver.xml" path="Type[@FullName='Microsoft.Maui.Controls.Internals.DependencyResolver']/Docs/*" /> public static class DependencyResolver { static Type _defaultVisualType = typeof(VisualMarker.DefaultVisual); static Func<Type, object[], object> Resolver { get; set; } /// <include file="../../docs/Microsoft.Maui.Controls.Internals/DependencyResolver.xml" path="//Member[@MemberName='ResolveUsing'][1]/Docs/*" /> public static void ResolveUsing(Func<Type, object[], object> resolver) { Resolver = resolver; } /// <include file="../../docs/Microsoft.Maui.Controls.Internals/DependencyResolver.xml" path="//Member[@MemberName='ResolveUsing'][2]/Docs/*" /> public static void ResolveUsing(Func<Type, object> resolver) { Resolver = (type, objects) => resolver.Invoke(type); } internal static object Resolve(Type type, params object[] args) { var result = Resolver?.Invoke(type, args); if (result != null) { if (!type.IsInstanceOfType(result)) { throw new InvalidCastException("Resolved instance is not of the correct type."); } } return result; } internal static object ResolveOrCreate( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) => ResolveOrCreate(type, null, null); internal static object ResolveOrCreate( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type, object source, Type visualType, params object[] args) { visualType = visualType ?? _defaultVisualType; var result = Resolve(type, args); if (result != null) return result; if (args.Length > 0) { if (visualType != _defaultVisualType) if (type.GetTypeInfo().DeclaredConstructors.Any(info => info.GetParameters().Length == 2)) return Activator.CreateInstance(type, new[] { args[0], source }); // This is by no means a general solution to matching with the correct constructor, but it'll // do for finding Android renderers which need Context (vs older custom renderers which may still use // parameterless constructors) if (type.GetTypeInfo().DeclaredConstructors.Any(info => info.GetParameters().Length == args.Length)) { return Activator.CreateInstance(type, args); } } return Activator.CreateInstance(type); } } }