public virtual NativeAssembly LoadUnmanagedDll( string initialPluginLoadDirectory, string unmanagedDllName, IPluginDependencyContext pluginDependencyContext, Func <string, string, ValueOrProceed <string> > loadFromDependencyContext, Func <string, string, ValueOrProceed <string> > loadFromRemote, Func <string, string, ValueOrProceed <IntPtr> > loadFromAppDomain) { ValueOrProceed <string> valueOrProceed = ValueOrProceed <string> .FromValue(String.Empty, true); ValueOrProceed <IntPtr> ptrValueOrProceed = ValueOrProceed <IntPtr> .FromValue(IntPtr.Zero, true); valueOrProceed = loadFromDependencyContext(initialPluginLoadDirectory, unmanagedDllName); if (valueOrProceed.CanProceed) { ptrValueOrProceed = loadFromAppDomain(initialPluginLoadDirectory, unmanagedDllName); } if (valueOrProceed.CanProceed && ptrValueOrProceed.CanProceed) { valueOrProceed = loadFromRemote(initialPluginLoadDirectory, unmanagedDllName); } return(NativeAssembly.Create(valueOrProceed.Value, ptrValueOrProceed.Value)); }
protected virtual ValueOrProceed <AssemblyFromStrategy> LoadFromRemote(string initialPluginLoadDirectory, AssemblyName assemblyName) { var assemblyFileName = $"{assemblyName.Name}.dll"; if (this.fileSystemUtilities.DoesFileExist(Path.Combine(initialPluginLoadDirectory, assemblyFileName))) { return(LoadDependencyFromLocalDisk(initialPluginLoadDirectory, assemblyFileName)); } return(ValueOrProceed <AssemblyFromStrategy> .Proceed()); }
protected virtual ValueOrProceed <IntPtr> LoadUnmanagedFromDefault(string initialPluginLoadDirectory, string unmanagedDllName) { var resolution = base.LoadUnmanagedDll(unmanagedDllName); if (resolution == default(IntPtr)) { return(ValueOrProceed <IntPtr> .Proceed()); } return(ValueOrProceed <IntPtr> .FromValue(resolution, false)); }
protected virtual ValueOrProceed <string> LoadUnmanagedFromRemote(string initialPluginLoadDirectory, string unmanagedDllName) { var assemblyFileName = $"{unmanagedDllName}.dll"; var pathToDependency = Path.Combine(initialPluginLoadDirectory, assemblyFileName); if (this.fileSystemUtilities.DoesFileExist(pathToDependency)) { return(ValueOrProceed <string> .FromValue(pathToDependency, false)); } return(ValueOrProceed <string> .FromValue(String.Empty, true)); }
protected virtual ValueOrProceed <AssemblyFromStrategy> LoadDependencyFromLocalDisk(string directory, string assemblyFileName) { var dependency = this.fileSystemUtilities.ReadDependencyFileFromDisk(directory, assemblyFileName); if (dependency == null) { return(ValueOrProceed <AssemblyFromStrategy> .Proceed()); } return(ValueOrProceed <AssemblyFromStrategy> .FromValue(AssemblyFromStrategy.Releasable(Assembly.Load(this.fileSystemUtilities.ToByteArray(dependency))), false)); }
public virtual AssemblyFromStrategy LoadAssembly( string initialPluginLoadDirectory, AssemblyName assemblyName, IPluginDependencyContext pluginDependencyContext, Func <string, AssemblyName, ValueOrProceed <AssemblyFromStrategy> > loadFromDependencyContext, Func <string, AssemblyName, ValueOrProceed <AssemblyFromStrategy> > loadFromRemote, Func <string, AssemblyName, ValueOrProceed <RuntimeAssemblyShim> > loadFromAppDomain) { if (assemblyName.Name == null) { return(null); } Debug.WriteLine($"{initialPluginLoadDirectory} Loading {assemblyName.Name} {assemblyName.Version}"); ValueOrProceed <AssemblyFromStrategy> valueOrProceed = ValueOrProceed <AssemblyFromStrategy> .FromValue(null, true); var isHostAssembly = IsHostAssembly(assemblyName, pluginDependencyContext); var isRemoteAssembly = IsRemoteAssembly(assemblyName, pluginDependencyContext); if (isHostAssembly && !isRemoteAssembly) // Load from Default App Domain (host) { Debug.WriteLine($"{initialPluginLoadDirectory} Loading {assemblyName.Name} {assemblyName.Version} from appDomain"); var assemblyShim = loadFromAppDomain(initialPluginLoadDirectory, assemblyName); if (assemblyShim.Value != null) { switch (assemblyShim.Value.RuntimeLoadFlag) { case RuntimeLoadFlag.FromRequestedVersion: return(null); // fallback to default loading mechanism case RuntimeLoadFlag.FromRuntimeVersion: return(AssemblyFromStrategy.NotReleasable(assemblyShim.Value.Assembly)); } } } if (valueOrProceed.CanProceed) { valueOrProceed = loadFromDependencyContext(initialPluginLoadDirectory, assemblyName); } Debug.WriteLineIf(!valueOrProceed.CanProceed, $"{initialPluginLoadDirectory} Loaded {assemblyName.Name} {assemblyName.Version} from dependency context"); if (valueOrProceed.CanProceed) { valueOrProceed = loadFromRemote(initialPluginLoadDirectory, assemblyName); Debug.WriteLineIf(!valueOrProceed.CanProceed, $"{initialPluginLoadDirectory} Loaded {assemblyName.Name} {assemblyName.Version} from remote"); } return(valueOrProceed.Value); }
// <summary> /// This override includes the netcore 3.0 resolver /// </summary> /// <param name="assemblyName"></param> /// <returns></returns> protected ValueOrProceed <AssemblyFromStrategy> LoadFromDependencyContext(string initialPluginLoadDirectory, AssemblyName assemblyName) { var assemblyPath = this.resolver.ResolveAssemblyToPath(assemblyName); if (!String.IsNullOrEmpty(assemblyPath) && this.fileSystemUtilities.DoesFileExist(assemblyPath)) { return(ValueOrProceed <AssemblyFromStrategy> .FromValue(AssemblyFromStrategy.Releasable(LoadFromAssemblyPath(assemblyPath)), false)); } if (IsResourceAssembly(assemblyName)) { foreach (var resourceDependency in this.pluginDependencyContext.PluginResourceDependencies) { var resourcePath = Path.Combine(resourceDependency.Path, assemblyName.CultureName, assemblyName.Name + ".dll"); if (this.fileSystemUtilities.DoesFileExist(resourcePath)) { return(ValueOrProceed <AssemblyFromStrategy> .FromValue(AssemblyFromStrategy.Releasable(LoadFromAssemblyPath(resourcePath)), false)); } } // Do not proceed probing return(ValueOrProceed <AssemblyFromStrategy> .FromValue(null, false)); } var pluginDependency = this.pluginDependencyContext.PluginDependencies.FirstOrDefault(d => d.DependencyNameWithoutExtension == assemblyName.Name); if (pluginDependency != null) { var dependency = this.pluginDependencyResolver.ResolvePluginDependencyToPath(initialPluginLoadDirectory, pluginDependency, this.pluginDependencyContext.AdditionalProbingPaths); if (dependency != null) { return(ValueOrProceed <AssemblyFromStrategy> .FromValue(AssemblyFromStrategy.Releasable(LoadFromStream(dependency)), false)); } } var localFile = Path.Combine(initialPluginLoadDirectory, assemblyName.Name + ".dll"); if (this.fileSystemUtilities.DoesFileExist(localFile)) { return(ValueOrProceed <AssemblyFromStrategy> .FromValue(AssemblyFromStrategy.Releasable(LoadFromAssemblyPath(localFile)), false)); } return(ValueOrProceed <AssemblyFromStrategy> .Proceed()); }
/// <summary> /// This override includes the netcore 3.0 resolver /// </summary> /// <param name="unmanagedDllName"></param> /// <returns></returns> protected ValueOrProceed <string> LoadUnmanagedFromDependencyContext(string initialPluginLoadDirectory, string unmanagedDllName) { string libraryPath = this.resolver.ResolveUnmanagedDllToPath(unmanagedDllName); if (!String.IsNullOrEmpty(libraryPath)) { string runtimeCandidate = null; if (this.nativeDependencyLoadPreference == NativeDependencyLoadPreference.PreferInstalledRuntime) { // Prefer loading from runtime folder runtimeCandidate = this.pluginDependencyResolver.ResolvePlatformDependencyPathToRuntime(this.pluginPlatformVersion, libraryPath); } return(ValueOrProceed <string> .FromValue(runtimeCandidate ?? libraryPath, false)); } var unmanagedDllNameWithoutFileExtension = Path.GetFileNameWithoutExtension(unmanagedDllName); var platformDependency = this.pluginDependencyContext.PlatformDependencies.FirstOrDefault(d => d.DependencyNameWithoutExtension == unmanagedDllNameWithoutFileExtension); if (platformDependency != null) { var pathToDependency = this.pluginDependencyResolver.ResolvePlatformDependencyToPath(initialPluginLoadDirectory, platformDependency, this.pluginDependencyContext.AdditionalProbingPaths); if (!String.IsNullOrEmpty(pathToDependency)) { string runtimeCandidate = null; if (this.nativeDependencyLoadPreference == NativeDependencyLoadPreference.PreferInstalledRuntime) { // Prefer loading from runtime folder runtimeCandidate = this.pluginDependencyResolver.ResolvePlatformDependencyPathToRuntime(this.pluginPlatformVersion, pathToDependency); } return(ValueOrProceed <string> .FromValue(runtimeCandidate ?? pathToDependency, false)); } } return(ValueOrProceed <string> .FromValue(String.Empty, true)); }
protected virtual ValueOrProceed <RuntimeAssemblyShim> LoadFromDefaultContext(string initialPluginLoadDirectory, AssemblyName assemblyName) { try { var assemblyShim = this.runtimeDefaultAssemblyLoadContext.LoadFromDefaultContext(assemblyName); if (assemblyShim != null) { return(ValueOrProceed <RuntimeAssemblyShim> .FromValue(assemblyShim, false)); } } catch (FileNotFoundException) { } // This can happen if the plugin uses a newer version of a package referenced in the host var hostAssembly = this.pluginDependencyContext.HostDependencies.FirstOrDefault(h => h.DependencyName.Name == assemblyName.Name); if (hostAssembly != null && !hostAssembly.AllowDowngrade) { if (!hostAssembly.AllowDowngrade) { throw new AssemblyLoadingException($"Plugin Assembly reference {assemblyName.Name} with version {assemblyName.Version} was requested but not found in the host. The version from the host is {hostAssembly.DependencyName.Version}. Possible version mismatch. Please downgrade your plugin or add {assemblyName.Name} to downgradableHostAssemblies."); } } return(ValueOrProceed <RuntimeAssemblyShim> .Proceed()); }