MethodMetaInspector
Base for inspectors that want configuration associated with methods.
For each child a MethodMetaModel is created
and added to ComponentModel's methods collection
using Castle.Core;
using Castle.Core.Configuration;
using Castle.MicroKernel.SubSystems.Conversion;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Reflection;
namespace Castle.MicroKernel.ModelBuilder.Inspectors
{
public abstract class MethodMetaInspector : IContributeComponentModelConstruction
{
private static readonly BindingFlags AllMethods = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
private ITypeConverter converter;
protected virtual bool ShouldUseMetaModel => false;
protected abstract string ObtainNodeName();
public virtual void ProcessModel(IKernel kernel, ComponentModel model)
{
if (model == null)
throw new ArgumentNullException("model");
if ((object)model.Configuration != null && !(model.Implementation == (Type)null)) {
IConfiguration val = model.Configuration.get_Children().get_Item(ObtainNodeName());
if (val != null) {
EnsureHasReferenceToConverter(kernel);
foreach (IConfiguration item in (List<IConfiguration>)val.get_Children()) {
string text = item.get_Name();
if ("method".Equals(text))
text = ((NameValueCollection)item.get_Attributes())["name"];
AssertNameIsNotNull(text, model);
MethodMetaModel metaModel = new MethodMetaModel(item);
if (IsValidMeta(model, metaModel)) {
bool shouldUseMetaModel = ShouldUseMetaModel;
string signature = ((NameValueCollection)item.get_Attributes())["signature"];
IList<MethodInfo> methods = GetMethods(model.Implementation, text, signature);
if (methods.Count == 0)
throw new Exception($"""{model.Implementation.FullName}""{text}""");
ProcessMeta(model, methods, metaModel);
bool shouldUseMetaModel2 = ShouldUseMetaModel;
}
}
}
}
}
protected virtual bool IsValidMeta(ComponentModel model, MethodMetaModel metaModel)
{
return true;
}
protected virtual void ProcessMeta(ComponentModel model, IList<MethodInfo> methods, MethodMetaModel metaModel)
{
}
private void AssertNameIsNotNull(string name, ComponentModel model)
{
if (name == null)
throw new Exception($"""{model.Name}""");
}
private Type[] ConvertSignature(string signature)
{
string[] array = signature.Split(new char[1] {
';'
});
List<Type> list = new List<Type>();
string[] array2 = array;
foreach (string text in array2) {
try {
list.Add(converter.PerformConversion<Type>(text));
} catch (Exception) {
throw new Exception($"""{signature}""{text}""");
}
}
return list.ToArray();
}
private void EnsureHasReferenceToConverter(IKernel kernel)
{
if (converter == null)
converter = (ITypeConverter)kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);
}
private IList<MethodInfo> GetMethods(Type implementation, string name, string signature)
{
if (string.IsNullOrEmpty(signature)) {
MethodInfo[] methods = implementation.GetMethods(AllMethods);
List<MethodInfo> list = new List<MethodInfo>();
MethodInfo[] array = methods;
foreach (MethodInfo methodInfo in array) {
if (CultureInfo.InvariantCulture.CompareInfo.Compare(methodInfo.Name, name, CompareOptions.IgnoreCase) == 0)
list.Add(methodInfo);
}
return list;
}
MethodInfo method = implementation.GetMethod(name, AllMethods, null, ConvertSignature(signature), null);
if (method == (MethodInfo)null)
return new MethodInfo[0];
return new List<MethodInfo> {
method
};
}
}
}