A Spring.Core.ICriteria implementation that represents a composed collection of Spring.Core.ICriteria instances.
Inheritance: ICriteria
            /// <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;
        }
Exemplo n.º 6
0
		/// <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();
            }
        }