[ResourceConsumption(ResourceScope.Assembly | ResourceScope.Machine)] // FindType method call. internal MappedFunction(MappedMetaModel model, FunctionMapping map, MethodInfo method) { this.model = model; this.map = map; this.method = method; this.rowTypes = _emptyTypes; if(map.Types.Count == 0 && this.method.ReturnType == typeof(IMultipleResults)) { throw Error.NoResultTypesDeclaredForFunction(method.Name); } else if(map.Types.Count > 1 && this.method.ReturnType != typeof(IMultipleResults)) { throw Error.TooManyResultTypesDeclaredForFunction(method.Name); } else if(map.Types.Count == 1 && this.method.ReturnType != typeof(IMultipleResults)) { Type elementType = TypeSystem.GetElementType(method.ReturnType); this.rowTypes = new List<MetaType>(1) { this.GetMetaType(map.Types[0], elementType) }.AsReadOnly(); } else if(map.Types.Count > 0) { List<MetaType> rowTypes = new List<MetaType>(); foreach(TypeMapping rtm in map.Types) { Type elementType = model.FindType(rtm.Name); if(elementType == null) { throw Error.CouldNotFindElementTypeInModel(rtm.Name); } MetaType mt = this.GetMetaType(rtm, elementType); // Only add unique meta types if(!rowTypes.Contains(mt)) { rowTypes.Add(mt); } } this.rowTypes = rowTypes.AsReadOnly(); } else if(map.FunReturn != null) { this.returnParameter = new MappedReturnParameter(method.ReturnParameter, map.FunReturn); } // Parameters. ParameterInfo[] pis = this.method.GetParameters(); if(pis.Length > 0) { List<MetaParameter> mps = new List<MetaParameter>(pis.Length); if(this.map.Parameters.Count != pis.Length) { throw Error.IncorrectNumberOfParametersMappedForMethod(this.map.MethodName); } for(int i = 0; i < pis.Length; i++) { mps.Add(new MappedParameter(pis[i], this.map.Parameters[i])); } this.parameters = mps.AsReadOnly(); } else { this.parameters = _emptyParameters; } }
internal static FunctionMapping ReadFunctionMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Function) { throw Error.UnexpectedElement(XmlMappingConstant.Function, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.Method, XmlMappingConstant.IsComposable }); FunctionMapping fm = new FunctionMapping(); fm.MethodName = RequiredAttribute(reader, XmlMappingConstant.Method); fm.Name = OptionalAttribute(reader, XmlMappingConstant.Name); fm.IsComposable = OptionalBoolAttribute(reader, XmlMappingConstant.IsComposable, false); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Parameter: fm.Parameters.Add(ReadParameterMapping(reader)); break; case XmlMappingConstant.ElementType: fm.Types.Add(ReadElementTypeMapping(null, reader)); break; case XmlMappingConstant.Return: fm.FunReturn = ReadReturnMapping(reader); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } reader.ReadEndElement(); } else { // no content is okay reader.Skip(); } return fm; }