internal static Type FindBuiltInTypeBySID(XUri sid) { Assembly assembly = Assembly.GetCallingAssembly(); foreach (Type type in assembly.GetTypes()) { DreamServiceAttribute attr = (DreamServiceAttribute)Attribute.GetCustomAttribute(type, typeof(DreamServiceAttribute), false); XUri[] sids = (attr != null) ? attr.GetSIDAsUris() : new XUri[0]; if (sids.Length > 0) { foreach (XUri tmp in sids) { if (tmp == sid) { return(type); } } } } return(null); }
//--- Class Methods --- /// <summary> /// Create a service blueprint from reflection and attribute meta-data for an <see cref="IDreamService"/> implementation. /// </summary> /// <param name="type">Type of examine.</param> /// <returns>Xml formatted blueprint.</returns> public static XDoc CreateServiceBlueprint(Type type) { if (type == null) { throw new ArgumentNullException("type"); } XDoc result = new XDoc("blueprint"); // load assembly Dictionary <string, string> assemblySettings = new Dictionary <string, string>(StringComparer.Ordinal); string[] assemblyParts = type.Assembly.FullName.Split(','); foreach (string parts in assemblyParts) { string[] assign = parts.Trim().Split(new char[] { '=' }, 2); if (assign.Length == 2) { assemblySettings[assign[0].Trim()] = assign[1].Trim(); } } result.Start("assembly"); foreach (KeyValuePair <string, string> entry in assemblySettings) { result.Attr(entry.Key, entry.Value); } result.Value(assemblyParts[0]); result.End(); result.Elem("class", type.FullName); // retrieve DreamService attribute on class definition DreamServiceAttribute serviceAttrib = (DreamServiceAttribute)Attribute.GetCustomAttribute(type, typeof(DreamServiceAttribute), false); result.Elem("name", serviceAttrib.Name); result.Elem("copyright", serviceAttrib.Copyright); result.Elem("info", serviceAttrib.Info); // retrieve DreamServiceUID attributes foreach (XUri sid in serviceAttrib.GetSIDAsUris()) { result.Elem("sid", sid); } // check if service has blueprint settings foreach (DreamServiceBlueprintAttribute blueprintAttrib in Attribute.GetCustomAttributes(type, typeof(DreamServiceBlueprintAttribute), true)) { result.InsertValueAt(blueprintAttrib.Name, blueprintAttrib.Value); } // check if service has configuration information DreamServiceConfigAttribute[] configAttributes = (DreamServiceConfigAttribute[])Attribute.GetCustomAttributes(type, typeof(DreamServiceConfigAttribute), true); if (!ArrayUtil.IsNullOrEmpty(configAttributes)) { result.Start("configuration"); foreach (DreamServiceConfigAttribute configAttr in configAttributes) { result.Start("entry") .Elem("name", configAttr.Name) .Elem("valuetype", configAttr.ValueType) .Elem("description", configAttr.Description) .End(); } result.End(); } // retrieve DreamFeature attributes on method definitions result.Start("features"); MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo method in methods) { // retrieve feature description Attribute[] featureAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureAttribute), false); if (featureAttributes.Length == 0) { continue; } if (method.IsGenericMethod || method.IsGenericMethodDefinition) { throw new NotSupportedException(string.Format("generic methods are not supported ({0})", method.Name)); } // determine access level string access; if (method.IsPublic) { access = "public"; } else if (method.IsAssembly) { access = "internal"; } else if (method.IsPrivate || method.IsFamily) { access = "private"; } else { throw new NotSupportedException(string.Format("access level is not supported ({0})", method.Name)); } // retrieve feature parameter descriptions, filters, prologues, and epilogues Attribute[] paramAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureParamAttribute), false); var pathAttributes = method.GetParameters().Select(p => { var attr = (PathAttribute)p.GetCustomAttributes(typeof(PathAttribute), false).FirstOrDefault(); return(((attr != null) && (attr.Name == null)) ? new PathAttribute { Description = attr.Description, Name = p.Name } : attr); }).Where(p => p != null); var queryAttributes = method.GetParameters().Select(q => { var attr = (QueryAttribute)q.GetCustomAttributes(typeof(QueryAttribute), false).FirstOrDefault(); return(((attr != null) && (attr.Name == null)) ? new QueryAttribute { Description = attr.Description, Name = q.Name } : attr); }).Where(q => q != null); Attribute[] statusAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureStatusAttribute), false); foreach (DreamFeatureAttribute featureAttrib in featureAttributes) { result.Start("feature"); result.Elem("obsolete", featureAttrib.Obsolete); result.Elem("pattern", featureAttrib.Pattern); result.Elem("description", featureAttrib.Description); string info = featureAttrib.Info ?? serviceAttrib.Info; if (info != null) { result.Elem("info", info); } result.Elem("method", method.Name); // add parameter descriptions (as seen on the method definition) foreach (DreamFeatureParamAttribute paramAttrib in paramAttributes) { result.Start("param"); result.Elem("name", paramAttrib.Name); if (!string.IsNullOrEmpty(paramAttrib.ValueType)) { result.Elem("valuetype", paramAttrib.ValueType); } result.Elem("description", paramAttrib.Description); result.End(); } // add parameter descriptions (as seen on the method parameters) foreach (PathAttribute pathAttrib in pathAttributes) { result.Start("param") .Elem("name", "{" + pathAttrib.Name + "}") .Elem("description", pathAttrib.Description) .End(); } // add parameter descriptions (as seen on the method parameters) foreach (QueryAttribute queryAttrib in queryAttributes) { result.Start("param") .Elem("name", queryAttrib.Name) .Elem("description", queryAttrib.Description) .End(); } // add status codes foreach (DreamFeatureStatusAttribute paramAttrib in statusAttributes) { result.Start("status"); result.Attr("value", (int)paramAttrib.Status); result.Value(paramAttrib.Description); result.End(); } // add access level result.Elem("access", access); result.End(); } } result.End(); return(result.EndAll()); }