From 32536d61c68cad779801e7d52e24625c3a259555 Mon Sep 17 00:00:00 2001 From: almostchristian Date: Tue, 11 Oct 2022 16:48:16 +0800 Subject: [PATCH] Improve discovery of executable methods to include implemented interfaces --- .../Implementation/Extensions.cs | 7 ++++--- src/Directory.Build.props | 4 +++- tests/TestDummies/IChildValue.cs | 5 +---- tests/TestDummies/IRootChildValue.cs | 13 +++++++++++++ 4 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 tests/TestDummies/IRootChildValue.cs diff --git a/src/ConfigurationProcessor.Core/Implementation/Extensions.cs b/src/ConfigurationProcessor.Core/Implementation/Extensions.cs index 698dbae..63c91be 100644 --- a/src/ConfigurationProcessor.Core/Implementation/Extensions.cs +++ b/src/ConfigurationProcessor.Core/Implementation/Extensions.cs @@ -113,7 +113,7 @@ public static void CallConfigurationMethods( IEnumerable? GetCollection(MethodInfo method) { var argValue = new ObjectArgumentValue(configSection!); - var collectionType = method.GetParameters().ElementAt(1).ParameterType; + var collectionType = method.GetParameters().ElementAt(method.IsStatic ? 1 : 0).ParameterType; return argValue.ConvertTo(method, collectionType, resolutionContext) as ICollection; } @@ -185,15 +185,16 @@ private static List FindConfigurationExtensionMethods( MethodFilter? filter) { IReadOnlyCollection configurationAssemblies = resolutionContext.ConfigurationAssemblies; - + var interfaces = configType.GetInterfaces(); var candidateMethods = configurationAssemblies .SelectMany(a => SafeGetExportedTypes(a) .Select(t => t.GetTypeInfo()) .Where(t => t.IsSealed && t.IsAbstract && !t.IsNested)) .Union(new[] { configType.GetTypeInfo() }) + .Concat(interfaces.Select(t => t.GetTypeInfo())) .SelectMany(t => candidateNames != null ? candidateNames.SelectMany(n => t.GetDeclaredMethods(n)) : t.DeclaredMethods) .Where(m => filter == null || filter(m, key)) - .Where(m => !m.IsDefined(typeof(CompilerGeneratedAttribute), false) && m.IsPublic && ((m.IsStatic && m.IsDefined(typeof(ExtensionAttribute), false)) || m.DeclaringType == configType)) + .Where(m => !m.IsDefined(typeof(CompilerGeneratedAttribute), false) && m.IsPublic && ((m.IsStatic && m.IsDefined(typeof(ExtensionAttribute), false)) || m.DeclaringType == configType || interfaces.Contains(m.DeclaringType))) .Where(m => !m.IsStatic || SafeGetParameters(m).ElementAtOrDefault(0)?.ParameterType.IsAssignableFrom(configType) == true) // If static method, checks that the first parameter is same as the extension type .ToList(); diff --git a/src/Directory.Build.props b/src/Directory.Build.props index e0017ba..3fb5225 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -5,7 +5,7 @@ - 1.3.0 + 1.4.0 $(Version).$([System.DateTime]::Now.ToString(yy))$([System.DateTime]::Now.DayOfYear.ToString(000)) $(Version) $(FileVersion)-$(GIT_VERSION) @@ -23,6 +23,8 @@ dependencyinjection;configuration;ioc;di; README.md +v1.4.0 + - Improve discovery of executable methods to include implemented interfaces v1.3.0 - Add support for disambiguating overloads with different array types. - Prefer overloads with the most matching parameters diff --git a/tests/TestDummies/IChildValue.cs b/tests/TestDummies/IChildValue.cs index 824dc9b..164f412 100644 --- a/tests/TestDummies/IChildValue.cs +++ b/tests/TestDummies/IChildValue.cs @@ -6,14 +6,11 @@ namespace TestDummies { - public interface IChildValue + public interface IChildValue : IRootChildValue { - string Child { get; set; } Type ContextType { get; set; } Uri Location { get; set; } Delegate OnError { get; set; } TimeSpan? Time { get; set; } - - void Reset(); } } \ No newline at end of file diff --git a/tests/TestDummies/IRootChildValue.cs b/tests/TestDummies/IRootChildValue.cs new file mode 100644 index 0000000..d3a517d --- /dev/null +++ b/tests/TestDummies/IRootChildValue.cs @@ -0,0 +1,13 @@ +// ------------------------------------------------------------------------------------------------- +// Copyright (c) Integrated Health Information Systems Pte Ltd. All rights reserved. +// ------------------------------------------------------------------------------------------------- + +namespace TestDummies +{ + public interface IRootChildValue + { + string Child { get; set; } + + void Reset(); + } +} \ No newline at end of file