protected LoadableClassAttributeBase(string summary, Type instType, Type loaderType, Type argType, Type[] sigTypes, string userName, params string[] loadNames) { Contracts.CheckValueOrNull(summary); Contracts.CheckValue(instType, nameof(instType)); Contracts.CheckValue(loaderType, nameof(loaderType)); Contracts.CheckNonEmpty(sigTypes, nameof(sigTypes)); if (Utils.Size(loadNames) == 0) { loadNames = new string[] { userName } } ; if (loadNames.Any(s => string.IsNullOrWhiteSpace(s))) { throw Contracts.ExceptEmpty(nameof(loadNames), "LoadableClass loadName parameter can't be empty"); } var sigType = sigTypes[0]; Contracts.CheckValue(sigType, nameof(sigTypes)); Type[] types; Contracts.CheckParam(sigType.BaseType == typeof(System.MulticastDelegate), nameof(sigTypes), "LoadableClass signature type must be a delegate type"); var meth = sigType.GetMethod("Invoke"); Contracts.CheckParam(meth != null, nameof(sigTypes), "LoadableClass signature type must be a delegate type"); Contracts.CheckParam(meth.ReturnType == typeof(void), nameof(sigTypes), "LoadableClass signature type must be a delegate type with void return"); var parms = meth.GetParameters(); int itypeBase = 0; if (argType != null) { types = new Type[1 + parms.Length]; types[itypeBase++] = argType; } else if (parms.Length > 0) { types = new Type[parms.Length]; } else { types = Type.EmptyTypes; } for (int itype = 0; itype < parms.Length; itype++) { var parm = parms[itype]; if ((parm.Attributes & (ParameterAttributes.Out | ParameterAttributes.Retval)) != 0) { throw Contracts.Except("Invalid signature parameter attributes"); } types[itypeBase + itype] = parm.ParameterType; } for (int i = 1; i < sigTypes.Length; i++) { sigType = sigTypes[i]; Contracts.CheckValue(sigType, nameof(sigTypes)); Contracts.Check(sigType.BaseType == typeof(System.MulticastDelegate), "LoadableClass signature type must be a delegate type"); meth = sigType.GetMethod("Invoke"); Contracts.CheckParam(meth != null, nameof(sigTypes), "LoadableClass signature type must be a delegate type"); Contracts.CheckParam(meth.ReturnType == typeof(void), nameof(sigTypes), "LoadableClass signature type must be a delegate type with void return"); parms = meth.GetParameters(); Contracts.CheckParam(parms.Length + itypeBase == types.Length, nameof(sigTypes), "LoadableClass signatures must have the same number of parameters"); for (int itype = 0; itype < parms.Length; itype++) { var parm = parms[itype]; if ((parm.Attributes & (ParameterAttributes.Out | ParameterAttributes.Retval)) != 0) { throw Contracts.ExceptParam(nameof(sigTypes), "Invalid signature parameter attributes"); } Contracts.CheckParam(types[itypeBase + itype] == parm.ParameterType, nameof(sigTypes), "LoadableClass signatures must have the same set of parameters"); } } InstanceType = instType; LoaderType = loaderType; ArgType = argType; SigTypes = sigTypes; CtorTypes = types; Summary = summary; UserName = userName; LoadNames = loadNames; } }
/// <summary> /// Make sure the given assemblies are loaded and that their loadable classes have been catalogued. /// </summary> public static void LoadAndRegister(IHostEnvironment env, string[] assemblies) { Contracts.AssertValue(env); if (Utils.Size(assemblies) > 0) { foreach (string path in assemblies) { Exception ex = null; try { // REVIEW: Will LoadFrom ever return null? Contracts.CheckNonEmpty(path, nameof(path)); if (!File.Exists(path)) { throw Contracts.ExceptParam(nameof(path), "File does not exist at path: {0}", path); } var assem = LoadAssembly(env, path); if (assem != null) { continue; } } catch (Exception e) { ex = e; } // If it is a zip file, load it that way. ZipArchive zip; try { zip = ZipFile.OpenRead(path); } catch (Exception e) { // Couldn't load as an assembly and not a zip, so warn the user. ex = ex ?? e; Console.Error.WriteLine("Warning: Could not load '{0}': {1}", path, ex.Message); continue; } string dir; try { dir = CreateTempDirectory(); } catch (Exception e) { throw Contracts.ExceptIO(e, "Creating temp directory for extra assembly zip extraction failed: '{0}'", path); } try { zip.ExtractToDirectory(dir); } catch (Exception e) { throw Contracts.ExceptIO(e, "Extracting extra assembly zip failed: '{0}'", path); } LoadAssembliesInDir(env, dir, false); } } }