/// <summary> /// Loads a Sharpmake extension assembly. /// </summary> /// <param name="assemblyPath">The path of the assembly that contains the Sharpmake extension.</param> /// <param name="fastLoad">Whether this method should load the assembly remotely first. See remarks.</param> /// <returns>The loaded extension's <see cref="Assembly"/>.</returns> /// <remarks> /// Because loading an extension in a remote assembly for validation is expensive, this /// method provides the <paramref name="fastLoad"/> argument which, when `false`, will load /// the extension in the current <see cref="AppDomain"/> instead of doing so in a remote /// <see cref="AppDomain"/>, testing whether it contains /// <see cref="SharpmakeExtensionAttribute"/>, and then loading it again in /// <see cref="AppDomain.CurrentDomain"/>. However, because it is impossible to unload a /// loaded assembly from the CLR, if this method fail you have essentially polluted the /// process' address space with an assembly that you may not need. /// </remarks> public Assembly LoadExtension(string assemblyPath, bool fastLoad) { if (assemblyPath == null) { throw new ArgumentNullException(nameof(assemblyPath)); } if (fastLoad) { if (!IsExtension(assemblyPath)) { return(null); } } Assembly assembly = Assembly.LoadFrom(assemblyPath); if (!fastLoad) { if (!ExtensionChecker.IsSharpmakeExtension(assembly)) { return(null); } } return(assembly); }
/// <summary> /// Loads a Sharpmake extension assembly. /// </summary> /// <param name="assemblyPath">The path of the assembly that contains the Sharpmake extension.</param> /// <param name="fastLoad">Whether this method should load the assembly remotely first. See remarks.</param> /// <returns>The loaded extension's <see cref="Assembly"/>.</returns> /// <remarks> /// Because loading an extension in a remote assembly for validation is expensive, this /// method provides the <paramref name="fastLoad"/> argument which, when `false`, will load /// the extension in the current <see cref="AppDomain"/> instead of doing so in a remote /// <see cref="AppDomain"/>, testing whether it contains /// <see cref="SharpmakeExtensionAttribute"/>, and then loading it again in /// <see cref="AppDomain.CurrentDomain"/>. However, because it is impossible to unload a /// loaded assembly from the CLR, if this method fail you have essentially polluted the /// process' address space with an assembly that you may not need. /// </remarks> public Assembly LoadExtension(string assemblyPath, bool fastLoad) { if (assemblyPath == null) { throw new ArgumentNullException(nameof(assemblyPath)); } if (fastLoad) { if (!IsExtension(assemblyPath)) { throw new Error($"{assemblyPath} is not a Sharpmake extension."); } } Assembly assembly = Assembly.LoadFrom(assemblyPath); if (!fastLoad) { var validator = new ExtensionChecker(); if (!validator.IsSharpmakeExtension(assembly)) { throw new Error($"{assemblyPath} is not a Sharpmake extension."); } } return(assembly); }
private void CreateRemoteExtensionCheckerIfNeeded() { lock (_mutex) { if (_validator == null) { _remoteDomain = AppDomain.CreateDomain("ExtensionHelperDomain"); _validator = _remoteDomain.Load(typeof(ExtensionChecker).Assembly.FullName).CreateInstance(typeof(ExtensionChecker).FullName) as ExtensionChecker; } } }
private void CreateRemoteExtensionCheckerIfNeeded() { lock (_mutex) { if (_validator == null) { _remoteDomain = AppDomain.CreateDomain("ExtensionHelperDomain", new Evidence(AppDomain.CurrentDomain.Evidence)); _validator = _remoteDomain.CreateInstanceAndUnwrap(typeof(ExtensionChecker).Assembly.FullName, typeof(ExtensionChecker).FullName) as ExtensionChecker; } } }
protected void Dispose(bool disposing) { if (disposing) { if (_remoteDomain != null) { AppDomain.Unload(_remoteDomain); _remoteDomain = null; _validator = null; } } }