/// <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; #if NET_2_0 GenericArgumentsHolder genericInfo = new GenericArgumentsHolder(TargetMethod); #endif // 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(); #if NET_2_0 searchCriteria.Add(new MethodNameMatchCriteria(genericInfo.GenericMethodName)); searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); searchCriteria.Add(new MethodGenericArgumentsCountCriteria( genericInfo.GetGenericArguments().Length)); #else searchCriteria.Add(new MethodNameMatchCriteria(TargetMethod)); searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); #endif 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(); #if NET_2_0 searchCriteria.Add(new MethodNameMatchCriteria(genericInfo.GenericMethodName)); searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); searchCriteria.Add(new MethodGenericArgumentsCountCriteria( genericInfo.GetGenericArguments().Length)); #else searchCriteria.Add(new MethodNameMatchCriteria(TargetMethod)); searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); #endif MemberInfo[] matchingMethods = targetType.FindMembers( MemberTypes.Method, MethodSearchingFlags, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), searchCriteria); if (matchingMethods == null || 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 NET_2_0 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); } #endif return(theMethod); }
/// <summary> /// Instantiate an object instance using a named factory method. /// </summary> /// <remarks> /// <p> /// The method may be static, if the <paramref name="definition"/> /// parameter specifies a class, rather than a /// <see cref="Spring.Objects.Factory.IFactoryObject"/> instance, or an /// instance variable on a factory object itself configured using Dependency /// Injection. /// </p> /// <p> /// Implementation requires iterating over the static or instance methods /// with the name specified in the supplied <paramref name="definition"/> /// (the method may be overloaded) and trying to match with the parameters. /// We don't have the types attached to constructor args, so trial and error /// is the only way to go here. /// </p> /// </remarks> /// <param name="name"> /// The name associated with the supplied <paramref name="definition"/>. /// </param> /// <param name="definition"> /// The definition describing the instance that is to be instantiated. /// </param> /// <param name="arguments"> /// Any arguments to the factory method that is to be invoked. /// </param> /// <returns> /// The result of the factory method invocation (the instance). /// </returns> public virtual IObjectWrapper InstantiateUsingFactoryMethod(string name, RootObjectDefinition definition, object[] arguments) { ObjectWrapper wrapper = new ObjectWrapper(); Type factoryClass = null; bool isStatic = true; ConstructorArgumentValues cargs = definition.ConstructorArgumentValues; ConstructorArgumentValues resolvedValues = new ConstructorArgumentValues(); int expectedArgCount = 0; // we don't have arguments passed in programmatically, so we need to resolve the // arguments specified in the constructor arguments held in the object definition... if (arguments == null || arguments.Length == 0) { expectedArgCount = cargs.ArgumentCount; ResolveConstructorArguments(name, definition, wrapper, cargs, resolvedValues); } else { // if we have constructor args, don't need to resolve them... expectedArgCount = arguments.Length; } if (StringUtils.HasText(definition.FactoryObjectName)) { // it's an instance method on the factory object's class... factoryClass = objectFactory.GetObject(definition.FactoryObjectName).GetType(); isStatic = false; } else { // it's a static factory method on the object class... factoryClass = definition.ObjectType; } GenericArgumentsHolder genericArgsInfo = new GenericArgumentsHolder(definition.FactoryMethodName); IList <MethodInfo> factoryMethodCandidates = FindMethods(genericArgsInfo.GenericMethodName, expectedArgCount, isStatic, factoryClass); bool autowiring = (definition.AutowireMode == AutoWiringMode.Constructor); // try all matching methods to see if they match the constructor arguments... for (int i = 0; i < factoryMethodCandidates.Count; i++) { MethodInfo factoryMethodCandidate = factoryMethodCandidates[i]; if (genericArgsInfo.ContainsGenericArguments) { string[] unresolvedGenericArgs = genericArgsInfo.GetGenericArguments(); if (factoryMethodCandidate.GetGenericArguments().Length != unresolvedGenericArgs.Length) { continue; } Type[] paramTypes = new Type[unresolvedGenericArgs.Length]; for (int j = 0; j < unresolvedGenericArgs.Length; j++) { paramTypes[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); } factoryMethodCandidate = factoryMethodCandidate.MakeGenericMethod(paramTypes); } if (arguments == null || arguments.Length == 0) { Type[] paramTypes = ReflectionUtils.GetParameterTypes(factoryMethodCandidate.GetParameters()); // try to create the required arguments... UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; ArgumentsHolder args = CreateArgumentArray(name, definition, resolvedValues, wrapper, paramTypes, factoryMethodCandidate, autowiring, out unsatisfiedDependencyExceptionData); if (args == null) { arguments = null; // if we failed to match this method, keep // trying new overloaded factory methods... continue; } else { arguments = args.arguments; } } // if we get here, we found a usable candidate factory method - check, if arguments match //arguments = (arguments.Length == 0 ? null : arguments); if (ReflectionUtils.GetMethodByArgumentValues(new MethodInfo[] { factoryMethodCandidate }, arguments) == null) { continue; } object objectInstance = instantiationStrategy.Instantiate(definition, name, objectFactory, factoryMethodCandidate, arguments); wrapper.WrappedInstance = objectInstance; if (log.IsDebugEnabled) { log.Debug(string.Format(CultureInfo.InvariantCulture, "Object '{0}' instantiated via factory method [{1}].", name, factoryMethodCandidate)); } return(wrapper); } // if we get here, we didn't match any method... throw new ObjectDefinitionStoreException( string.Format(CultureInfo.InvariantCulture, "Cannot find matching factory method '{0} on Type [{1}].", definition.FactoryMethodName, factoryClass)); }
/// <summary> /// Resolves this managed collection at runtime. /// </summary> /// <param name="objectName"> /// The name of the top level object that is having the value of one of it's /// collection properties resolved. /// </param> /// <param name="definition"> /// The definition of the named top level object. /// </param> /// <param name="propertyName"> /// The name of the property the value of which is being resolved. /// </param> /// <param name="resolver"> /// The callback that will actually do the donkey work of resolving /// this managed collection. /// </param> /// <returns>A fully resolved collection.</returns> public ICollection Resolve( string objectName, IObjectDefinition definition, string propertyName, ManagedCollectionElementResolver resolver) { IDictionary dictionary; Type keyType = null; if (StringUtils.HasText(this.keyTypeName)) { keyType = TypeResolutionUtils.ResolveType(this.keyTypeName); } Type valueType = null; if (StringUtils.HasText(this.valueTypeName)) { valueType = TypeResolutionUtils.ResolveType(this.valueTypeName); } #if NET_2_0 if ((keyType == null) && (valueType == null)) { dictionary = new HybridDictionary(); } else { Type type = typeof(Dictionary <,>); Type[] genericArgs = new Type[2] { (keyType == null) ? typeof(object) : keyType, (valueType == null) ? typeof(object) : valueType }; type = type.MakeGenericType(genericArgs); dictionary = (IDictionary)ObjectUtils.InstantiateType(type); } #else dictionary = new HybridDictionary(); #endif foreach (object key in this.Keys) { string elementName = string.Format(CultureInfo.InvariantCulture, "{0}[{1}]", propertyName, key); object resolvedKey = resolver(objectName, definition, elementName, key); object resolvedValue = resolver(objectName, definition, elementName, this[key]); if (keyType != null) { try { resolvedKey = TypeConversionUtils.ConvertValueIfNecessary(keyType, resolvedKey, propertyName); } catch (TypeMismatchException) { throw new TypeMismatchException( String.Format( "Unable to convert managed dictionary key '{0}' from [{1}] into [{2}] during initialization" + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", resolvedKey, resolvedKey.GetType(), keyType, propertyName, objectName)); } } if (valueType != null) { try { resolvedValue = TypeConversionUtils.ConvertValueIfNecessary(valueType, resolvedValue, propertyName + "[" + resolvedKey + "]"); } catch (TypeMismatchException) { throw new TypeMismatchException( String.Format( "Unable to convert managed dictionary value '{0}' from [{1}] into [{2}] during initialization" + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", resolvedValue, resolvedValue.GetType(), valueType, propertyName, objectName)); } } dictionary.Add(resolvedKey, resolvedValue); } return(dictionary); }
/// <summary> /// Reads the specified configuration section from the given <see cref="XmlDocument"/> /// </summary> /// <param name="document"></param> /// <param name="configSectionName"></param> /// <returns></returns> public static object GetSectionFromXmlDocument(XmlDocument document, string configSectionName) { string[] sectionNameParts = configSectionName.Split('/'); string sectionHandlerPath = string.Format("//{0}/{1}", ConfigurationElement, ConfigSectionsElement); if (sectionNameParts.Length > 1) { // deal with sectionGroups for (int i = 0; i < sectionNameParts.Length - 1; i++) { sectionHandlerPath = string.Format("{0}/{1}[@{2}='{3}']", sectionHandlerPath, ConfigSectionGroupElement, ConfigSectionNameAttribute, sectionNameParts[i]); } } sectionHandlerPath = string.Format("{0}/{1}[@{2}='{3}']", sectionHandlerPath, ConfigSectionElement, ConfigSectionNameAttribute, sectionNameParts[sectionNameParts.Length - 1]); XmlNode xmlConfig = document.SelectSingleNode(sectionHandlerPath); // create appropriate configuration section handler... Type handlerType = null; if (xmlConfig == null) { // none specified, use machine inherited XmlDocument machineConfig = new XmlDocument(); machineConfig.Load(RuntimeEnvironment.SystemConfigurationFile); xmlConfig = machineConfig.SelectSingleNode(sectionHandlerPath); if (xmlConfig == null) { // TOOD: better throw a sensible exception in case of a missing handler configuration? handlerType = typeof(NameValueFileSectionHandler); } } if (xmlConfig != null) { XmlAttribute xmlConfigType = xmlConfig.Attributes[ConfigSectionTypeAttribute]; handlerType = TypeResolutionUtils.ResolveType(xmlConfigType.Value); } if (handlerType == null) { throw new ConfigurationException(string.Format("missing 'type' attribute on section definition for '{0}'", configSectionName)); } // obtain Xml node with section content XmlNode sectionContent = document.SelectSingleNode(string.Format("//{0}/{1}", ConfigurationElement, configSectionName)); if (sectionContent == null) { throw ConfigurationUtils.CreateConfigurationException("Cannot read properties; config section '" + configSectionName + "' not found."); } // IConfigurationSectionHandler if (typeof(IConfigurationSectionHandler).IsAssignableFrom(handlerType)) { IConfigurationSectionHandler handler = (IConfigurationSectionHandler)ObjectUtils.InstantiateType(handlerType); return(((IConfigurationSectionHandler)handler).Create(null, null, sectionContent)); } #if !NET_1_0 && !NET_1_1 // NET 2.0 ConfigurationSection if (typeof(ConfigurationSection).IsAssignableFrom(handlerType)) { ConfigurationSection section = CreateConfigurationSection(handlerType, new XmlNodeReader(sectionContent)); return(section); } #endif // Not supported throw ConfigurationUtils.CreateConfigurationException("Configuration section '" + configSectionName + "' is neither of type IConfigurationSectionHandler nor ConfigurationSection."); }
/// <summary> /// Determines the type of object that should be instantiated. /// </summary> /// <param name="typeName"> /// The type name to resolve. /// </param> /// <returns> /// The type of object that should be instantiated. /// </returns> /// <exception cref="TypeLoadException"> /// If the type cannot be resolved. /// </exception> protected virtual Type GetObjectType(string typeName) { return(TypeResolutionUtils.ResolveType(typeName)); }
public ClassInfo GetClassInfo(string fullClassName, bool throwExceptionIfDoesNotExist) { var type = TypeResolutionUtils.ResolveType(fullClassName); return(GetClassInfo(type, throwExceptionIfDoesNotExist)); }