// Interrogate the assembly for any classes to add to the list of file formats. They: // 1. Must be nested in a class that // 1a. ends with "Format" // 1b. derives from FormatBase // 1c. contains the method public static CreateModel (Stream, byte[], string) // 2. Must be named "Model" and derive from a FormatBase.ModelBase // 4. Must contain the property public static string[] Names { get; } // 5. May contain the property public static string Subname { get; } #if NETFX_CORE private void LoadFormats() { foreach (var type in typeof(FormatBase).GetTypeInfo().Assembly.DefinedTypes) { if (type.IsClass && type.IsSubclassOf(typeof(FormatBase)) && type.Name.EndsWith("Format")) { MethodInfo createrInfo = null, namesInfo = null, subnameInfo = null; foreach (var meth in type.DeclaredMethods) { if ((meth.Attributes & MethodAttributes.Public | MethodAttributes.Static) == (MethodAttributes.Public | MethodAttributes.Static)) { Type ret = meth.ReturnType; if (!meth.IsSpecialName) { var x2 = ret.Name; if (meth.Name == "CreateModel") { var parm = meth.GetParameters(); var bt = ret.GetTypeInfo().BaseType; while (ret.GetTypeInfo().BaseType != typeof(object)) { ret = ret.GetTypeInfo().BaseType; } if (ret == typeof(FormatBase.ModelBase) && parm.Length == 3 && parm[0].ParameterType == typeof(Stream) && parm[1].ParameterType == typeof(byte[]) && parm[2].ParameterType == typeof(string)) { createrInfo = meth; } } } else if (meth.Name == "get_Names" && ret == typeof(string[])) { namesInfo = meth; } else if (meth.IsSpecialName && meth.Name == "get_Subname" && ret == typeof(string)) { subnameInfo = meth; } } } if (namesInfo != null && createrInfo != null) { var factorySignature = new Type[] { typeof(Stream), typeof(byte[]), typeof(string) }; MethodInfo runInfo = RuntimeReflectionExtensions.GetRuntimeMethod(type.AsType(), "Create", factorySignature); var creater = (FormatModelFactory)createrInfo.CreateDelegate(typeof(FormatModelFactory)); var names = (string[])namesInfo.Invoke(null, null); var subname = (string)(subnameInfo == null ? null : subnameInfo.Invoke(null, null)); FormatModel.Add(creater, names, subname); } } } FormatModel.Sort(); }
// Interrogate the assembly for any classes to add to the list of file formats. // Acceptable formats: // 1. Must be named "Model" // 2. Must derive from FormatBase.ModelBase // 3. Must contain the property public static string[] SNames { get; } // 4. May contain the property public static string SSubname { get; } // 5. Must be nested. Outer class: // 5a. Must end with "Format" // 5b. Must derive from FormatBase // 5c. Must contain the method public static CreateModel (Stream, byte[], string) private void LoadFormats() { // Load known formats into the static table via duck typing. foreach (var duck in Assembly.GetAssembly(typeof(FormatBase)).GetTypes()) { if (duck.IsClass && duck.Name.EndsWith("Format")) { MethodInfo createrInfo = null, namesInfo = null, subnameInfo = null; Type modelType = duck.GetNestedType("Model"); foreach (var meth in duck.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) { Type ret = meth.ReturnType; if (!meth.IsSpecialName) { if (meth.Name == "CreateModel") { ParameterInfo[] parm = meth.GetParameters(); while (ret.BaseType != typeof(System.Object)) { ret = ret.BaseType; } if (ret == typeof(FormatBase.Model) && parm.Length == 3 && parm[0].ParameterType == typeof(Stream) && parm[1].ParameterType == typeof(System.Byte[]) && parm[2].ParameterType == typeof(String)) { createrInfo = meth; } } } else if (meth.Name == "get_SNames" && ret == typeof(System.String[])) { namesInfo = meth; } else if (meth.IsSpecialName && meth.Name == "get_SSubname" && ret == typeof(System.String)) { subnameInfo = meth; } } if (namesInfo != null && createrInfo != null) { var names = (string[])namesInfo.Invoke(null, null); var subname = (string)subnameInfo?.Invoke(null, null); var creater = (FormatModelFactory)Delegate.CreateDelegate(typeof(FormatModelFactory), createrInfo); FormatModel.Add(creater, names, subname); } } } FormatModel.Sort(); }