/// <summary> /// Detects whether the caller is under the supplied <see cref="System.Type"/> /// and <paramref name="methodName"/>, according to the current stacktrace. /// </summary> /// <remarks> /// <p> /// Matches the whole method name. /// </p> /// </remarks> /// <seealso cref="Spring.Core.IControlFlow.Under(Type, string)"/> bool IControlFlow.Under(Type type, string methodName) { ComposedCriteria criteria = new ComposedCriteria(); criteria.Add(new MethodsDeclaredTypeCriteria(type)); criteria.Add(new RegularExpressionMethodNameCriteria(methodName)); return(IsMatch(criteria)); }
/// <summary> /// Queries the input type for a <see cref="MethodInfo" /> signature matching the input /// <see cref="MethodInfo"/> signature. /// </summary> /// <remarks> /// Typically used to query a potential subscriber to see if they implement an event handler. /// </remarks> /// <param name="invoke"><see cref="MethodInfo"/> to match against</param> /// <param name="subscriberType"><see cref="Type"/> to query</param> /// <returns> /// <see cref="MethodInfo"/> matching input <see cref="MethodInfo"/> /// signature, or <see langword="null"/> if there is no match. /// </returns> public static MethodInfo GetMethodInfoMatchingSignature( MethodInfo invoke, Type subscriberType) { ParameterInfo[] parameters = invoke.GetParameters(); ComposedCriteria criteria = new ComposedCriteria(); criteria.Add(new MethodReturnTypeCriteria(invoke.ReturnType)); criteria.Add(new MethodParametersCountCriteria(parameters.Length)); criteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(parameters))); MemberInfo[] methods = subscriberType.FindMembers( MemberTypes.Method, ReflectionUtils.AllMembersCaseInsensitiveFlags, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), criteria); if (methods != null && methods.Length > 0) { return methods[0] as MethodInfo; } return null; }
/// <summary> /// Returns an array of all of those /// <see cref="System.Reflection.MethodInfo">methods</see> exposed on the /// <paramref name="searchType"/> that match the supplied criteria. /// </summary> /// <param name="methodName"> /// Methods that have this name (can be in the form of a regular expression). /// </param> /// <param name="expectedArgumentCount"> /// Methods that have exactly this many arguments. /// </param> /// <param name="isStatic"> /// Methods that are static / instance. /// </param> /// <param name="searchType"> /// The <see cref="System.Type"/> on which the methods (if any) are to be found. /// </param> /// <returns> /// An array of all of those /// <see cref="System.Reflection.MethodInfo">methods</see> exposed on the /// <paramref name="searchType"/> that match the supplied criteria. /// </returns> private static IList<MethodInfo> FindMethods(string methodName, int expectedArgumentCount, bool isStatic, Type searchType) { ComposedCriteria methodCriteria = new ComposedCriteria(); methodCriteria.Add(new MethodNameMatchCriteria(methodName)); methodCriteria.Add(new MethodParametersCountCriteria(expectedArgumentCount)); BindingFlags methodFlags = BindingFlags.Public | BindingFlags.IgnoreCase | (isStatic ? BindingFlags.Static : BindingFlags.Instance); MemberInfo[] methods = searchType.FindMembers(MemberTypes.Method, methodFlags, new CriteriaMemberFilter().FilterMemberByCriteria, methodCriteria); return methods.Cast<MethodInfo>().ToArray(); }
/// <summary> /// Return the <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> for this /// method. /// </summary> /// <param name="method">The method to check.</param> /// <param name="targetType"> /// The target <see cref="System.Type"/>. May be null, in which case the declaring /// class of the supplied <paramref name="method"/> must be used. /// </param> /// <returns> /// A <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> or /// null if the method is non-transactional. /// </returns> public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) { //Might have registered MethodInfo objects whose declaring type is the interface, so 'downcast' //to the most specific method which is typically what is passed in as the first method argument. foreach (DictionaryEntry dictionaryEntry in _methodMap) { MethodInfo currentMethod = (MethodInfo)dictionaryEntry.Key; MethodInfo specificMethod; if (targetType == null) { specificMethod = currentMethod; } else { ParameterInfo[] parameters = currentMethod.GetParameters(); ComposedCriteria searchCriteria = new ComposedCriteria(); searchCriteria.Add(new MethodNameMatchCriteria(currentMethod.Name)); searchCriteria.Add(new MethodParametersCountCriteria(parameters.Length)); #if NET_2_0 searchCriteria.Add(new MethodGenericArgumentsCountCriteria( currentMethod.GetGenericArguments().Length)); #endif searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(parameters))); MemberInfo[] matchingMethods = targetType.FindMembers( MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), searchCriteria); if (matchingMethods != null && matchingMethods.Length == 1) { specificMethod = matchingMethods[0] as MethodInfo; } else { specificMethod = currentMethod; } } if (method == specificMethod) { return (ITransactionAttribute)dictionaryEntry.Value; } } return (ITransactionAttribute)_methodMap[method]; }
private ITransactionAttribute computeTransactionAttribute(MethodInfo method, Type targetType) { MethodInfo specificMethod; if (targetType == null) { specificMethod = method; } else { ParameterInfo[] parameters = method.GetParameters(); ComposedCriteria searchCriteria = new ComposedCriteria(); searchCriteria.Add(new MethodNameMatchCriteria(method.Name)); searchCriteria.Add(new MethodParametersCountCriteria(parameters.Length)); #if NET_2_0 searchCriteria.Add(new MethodGenericArgumentsCountCriteria( method.GetGenericArguments().Length)); #endif searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(parameters))); MemberInfo[] matchingMethods = targetType.FindMembers( MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), searchCriteria); if (matchingMethods != null && matchingMethods.Length == 1) { specificMethod = matchingMethods[0] as MethodInfo; } else { specificMethod = method; } } ITransactionAttribute transactionAttribute = getTransactionAttribute(specificMethod); if (null != transactionAttribute) { return transactionAttribute; } else if (specificMethod != method) { transactionAttribute = getTransactionAttribute(method); } return null; }
/// <summary> /// Searches for and returns the method that is to be invoked. /// </summary> /// <remarks> /// The return value of this method call will subsequently be returned from the /// <see cref="Spring.Objects.Support.MethodInvoker.GetPreparedMethod()"/>. /// </remarks> /// <returns>The method that is to be invoked.</returns> /// <exception cref="System.MissingMethodException"> /// If no method could be found. /// </exception> /// <exception cref="System.ArgumentException"> /// If more than one method was found. /// </exception> protected virtual MethodInfo FindTheMethodToInvoke() { MethodInfo theMethod = null; Type targetType = (TargetObject != null) ? TargetObject.GetType() : TargetType; GenericArgumentsHolder genericInfo = new GenericArgumentsHolder(TargetMethod); // if we don't have any named arguments, we can try to get the exact method first... if (NamedArguments.Count == 0) { ComposedCriteria searchCriteria = new ComposedCriteria(); searchCriteria.Add(new MethodNameMatchCriteria(genericInfo.GenericMethodName)); searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); searchCriteria.Add(new MethodGenericArgumentsCountCriteria(genericInfo.GetGenericArguments().Length)); searchCriteria.Add(new MethodArgumentsCriteria(Arguments)); MemberInfo[] matchingMethods = targetType.FindMembers( MemberTypes.Method, MethodSearchingFlags, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), searchCriteria); if (matchingMethods != null && matchingMethods.Length == 1) { theMethod = matchingMethods[0] as MethodInfo; } } if (theMethod == null) { // search for a method with a matching signature... ComposedCriteria searchCriteria = new ComposedCriteria(); searchCriteria.Add(new MethodNameMatchCriteria(genericInfo.GenericMethodName)); searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); searchCriteria.Add(new MethodGenericArgumentsCountCriteria(genericInfo.GetGenericArguments().Length)); MemberInfo[] matchingMethods = targetType.FindMembers( MemberTypes.Method, MethodSearchingFlags, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), searchCriteria); if (matchingMethods.Length == 0) { throw new MissingMethodException(targetType.Name, TargetMethod); } if (matchingMethods.Length > 1) { throw new ArgumentException(string.Format( CultureInfo.InvariantCulture, "Unable to determine which exact method to call; found '{0}' matches.", matchingMethods.Length)); } theMethod = matchingMethods[0] as MethodInfo; } if (genericInfo.ContainsGenericArguments) { string[] unresolvedGenericArgs = genericInfo.GetGenericArguments(); Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; for (int j = 0; j < unresolvedGenericArgs.Length; j++) { genericArgs[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); } theMethod = theMethod.MakeGenericMethod(genericArgs); } return theMethod; }
/// <summary> /// Wires up the supplied event to any handler methods that match the event /// signature. /// </summary> /// <param name="theEvent">The event being wired up.</param> private void WireEvent(EventInfo theEvent) { // grab some info (such as the delegate's method signature) about the event DelegateInfo eventDelegate = new DelegateInfo(theEvent); // if the method name needs to be customised on a per event basis, do so string customMethodName = GetMethodNameCustomisedForEvent(theEvent.Name); // create the criteria for the handler method search... ComposedCriteria methodCriteria = new ComposedCriteria(); // a candidate handlers method name must match the custom method name methodCriteria.Add(new RegularExpressionMethodNameCriteria(customMethodName)); // the return Type of a candidate handlers method must be the same as the return type of the event methodCriteria.Add(new MethodReturnTypeCriteria(eventDelegate.GetReturnType())); // a candidate handlers method parameters must match the event's parameters methodCriteria.Add(new MethodParametersCriteria(eventDelegate.GetParameterTypes())); // and grab the methods that satisfy the criteria... BindingFlags methodFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public; MemberInfo[] methods = HandlerType.FindMembers( MemberTypes.Method, methodFlags, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), methodCriteria); // and for each method that satisfied the criteria... foreach (MethodInfo method in methods) { #region Instrumentation if (log.IsDebugEnabled) { log.Debug(string.Format( CultureInfo.InvariantCulture, "Wiring up this method '{0}' to this event '{1}'", method.Name, theEvent.Name)); } #endregion IEventHandlerValue myHandler = method.IsStatic ? (IEventHandlerValue) new StaticEventHandlerValue() : (IEventHandlerValue) new InstanceEventHandlerValue(); myHandler.EventName = theEvent.Name; myHandler.MethodName = method.Name; myHandler.Wire(Source, Handler); } }
/// <summary> /// Detects whether the caller is under the supplied <see cref="System.Type"/> /// and <paramref name="methodName"/>, according to the current stacktrace. /// </summary> /// <remarks> /// <p> /// Matches the whole method name. /// </p> /// </remarks> /// <seealso cref="Spring.Core.IControlFlow.Under(Type, string)"/> bool IControlFlow.Under(Type type, string methodName) { ComposedCriteria criteria = new ComposedCriteria(); criteria.Add(new MethodsDeclaredTypeCriteria(type)); criteria.Add(new RegularExpressionMethodNameCriteria(methodName)); return IsMatch(criteria); }
private MethodInfo FindProxyMethod(Type targetType, MethodInfo method) { ParameterInfo[] parameters = method.GetParameters(); ComposedCriteria searchCriteria = new ComposedCriteria(); searchCriteria.Add(new MethodNameMatchCriteria("proxy_" + method.Name)); searchCriteria.Add(new MethodParametersCountCriteria(parameters.Length)); #if NET_2_0 searchCriteria.Add(new MethodGenericArgumentsCountCriteria( method.GetGenericArguments().Length)); #endif searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(parameters))); MemberInfo[] matchingMethods = targetType.FindMembers( MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), searchCriteria); if (matchingMethods != null && matchingMethods.Length == 1) { return matchingMethods[0] as MethodInfo; } else { throw new AmbiguousMatchException(); } }