public MethodBase ResolvePlug(MethodBase aMethod, Type[] aParamTypes) { MethodBase xResult = null; var xMethodKey = BuildMethodKeyName(aMethod); if (ResolvedPlugs.Contains(xMethodKey, out xResult)) { return(xResult); } else { // TODO: Right now plugs are compiled in, even if they are not needed. // Maybe change this so plugs that are not needed are not compiled in? // To do so, maybe plugs could be marked as they are used List <Type> xImpls; // Check for exact type plugs first, they have precedence if (mPlugImpls.TryGetValue(aMethod.DeclaringType, out xImpls)) { xResult = ResolvePlug(aMethod.DeclaringType, xImpls, aMethod, aParamTypes); } // Check for inheritable plugs second. // We also need to fall through at method level, not just type. // That is a exact type plug could exist, but not method match. // In such a case the Inheritable methods should still be searched // if there is a inheritable type match. if (xResult == null) { foreach (var xInheritable in mPlugImplsInhrt) { if (aMethod.DeclaringType.IsSubclassOf(xInheritable.Key)) { xResult = ResolvePlug(aMethod.DeclaringType /*xInheritable.Key*/, xInheritable.Value, aMethod, aParamTypes); if (xResult != null) { // prevent key overriding. break; } } } } ResolvedPlugs.Add(xMethodKey, xResult); return(xResult); } }
public MethodBase ResolvePlug(MethodBase aMethod, Type[] aParamTypes) { MethodBase xResult = null; if (aMethod.Name == "CreateComparer") { ; } var xMethodKey = BuildMethodKeyName(aMethod); if (ResolvedPlugs.Contains(xMethodKey, out xResult)) { return(xResult); } else { List <Type> xImpls; // Check for exact type plugs first, they have precedence if (mPlugImpls.TryGetValue(aMethod.DeclaringType, out xImpls)) { xResult = ResolvePlug(aMethod.DeclaringType, xImpls, aMethod, aParamTypes); } // Check for inheritable plugs second. // We also need to fall through at method level, not just type. // That is a exact type plug could exist, but not method match. // In such a case the Inheritable methods should still be searched // if there is a inheritable type match. if (xResult == null) { foreach (var xInheritable in mPlugImplsInhrt) { if (aMethod.DeclaringType.IsSubclassOf(xInheritable.Key)) { xResult = ResolvePlug(aMethod.DeclaringType /*xInheritable.Key*/, xInheritable.Value, aMethod, aParamTypes); if (xResult != null) { // prevent key overriding. break; } } } } if (xResult == null) { xImpls = null; if (aMethod.DeclaringType.IsGenericType) { var xMethodDeclaringTypeDef = aMethod.DeclaringType.GetGenericTypeDefinition(); if (mGenericPlugImpls.TryGetValue(xMethodDeclaringTypeDef, out xImpls)) { var xBindingFlagsToFindMethod = BindingFlags.Default; if (aMethod.IsPublic) { xBindingFlagsToFindMethod = BindingFlags.Public; } else { // private xBindingFlagsToFindMethod = BindingFlags.NonPublic; } if (aMethod.IsStatic) { xBindingFlagsToFindMethod |= BindingFlags.Static; } else { xBindingFlagsToFindMethod |= BindingFlags.Instance; } var xGenericMethod = (from item in xMethodDeclaringTypeDef.GetMethods(xBindingFlagsToFindMethod) where item.Name == aMethod.Name && item.GetParameters().Length == aParamTypes.Length select item).SingleOrDefault(); if (xGenericMethod != null) { var xTempResult = ResolvePlug(xMethodDeclaringTypeDef, xImpls, xGenericMethod, aParamTypes); if (xTempResult != null) { if (xTempResult.DeclaringType.IsGenericTypeDefinition) { var xConcreteTempResultType = xTempResult.DeclaringType.MakeGenericType(aMethod.DeclaringType.GetGenericArguments()); xResult = (from item in xConcreteTempResultType.GetMethods(BindingFlags.Static | BindingFlags.Public) where item.Name == aMethod.Name && item.GetParameters().Length == aParamTypes.Length select item).SingleOrDefault(); } } ; ; ; ; } /// } } } ResolvedPlugs.Add(xMethodKey, xResult); return(xResult); } }