public virtual Assembly LoadAssembly(AssemblyName assemblyName,
                                             Func <IPluginLoadContext, AssemblyName, ValueOrProceed <Assembly> > loadFromDependencyContext,
                                             Func <IPluginLoadContext, AssemblyName, ValueOrProceed <Assembly> > loadFromRemote,
                                             Func <IPluginLoadContext, AssemblyName, ValueOrProceed <Assembly> > loadFromAppDomain)
        {
            if (assemblyName.Name == null)
            {
                return(null);
            }

            ValueOrProceed <Assembly> valueOrProceed = ValueOrProceed <Assembly> .FromValue(null, true);

            if (IsHostAssembly(assemblyName) && !IsRemoteAssembly(assemblyName)) // Load from Default App Domain (host)
            {
                valueOrProceed = loadFromAppDomain(this.pluginLoadContext, assemblyName);
                if (valueOrProceed.Value != null)
                {
                    return(null); // fallback to default loading mechanism
                }
            }

            if (valueOrProceed.CanProceed)
            {
                valueOrProceed = loadFromDependencyContext(this.pluginLoadContext, assemblyName);
            }

            if (valueOrProceed.CanProceed)
            {
                valueOrProceed = loadFromRemote(this.pluginLoadContext, assemblyName);
            }

            return(valueOrProceed.Value);
        }
Esempio n. 2
0
 public void LoadedUnmanagedFromRemote(string unmanagedDllName, ValueOrProceed <string> valueOrProceed)
 {
     if (valueOrProceed.Value != null)
     {
         Log($"Plugin<{this.pluginType}> unmananged assembly {unmanagedDllName} was loaded from the Remote Location");
     }
 }
        public virtual NativeAssembly LoadUnmanagedDll(string unmanagedDllName,
                                                       Func <IPluginLoadContext, string, ValueOrProceed <string> > loadFromDependencyContext,
                                                       Func <IPluginLoadContext, string, ValueOrProceed <string> > loadFromRemote,
                                                       Func <IPluginLoadContext, string, ValueOrProceed <IntPtr> > loadFromAppDomain)
        {
            ValueOrProceed <string> valueOrProceed = ValueOrProceed <string> .FromValue(String.Empty, true);

            ValueOrProceed <IntPtr> ptrValueOrProceed = ValueOrProceed <IntPtr> .FromValue(IntPtr.Zero, true);

            valueOrProceed = loadFromDependencyContext(this.pluginLoadContext, unmanagedDllName);
            this.logger.LoadedUnmanagedFromDependencyContext(unmanagedDllName, valueOrProceed);

            if (valueOrProceed.CanProceed)
            {
                ptrValueOrProceed = loadFromAppDomain(this.pluginLoadContext, unmanagedDllName);
                this.logger.LoadedUnmanagedFromAppDomain(unmanagedDllName, ptrValueOrProceed);
            }

            if (valueOrProceed.CanProceed && ptrValueOrProceed.CanProceed)
            {
                valueOrProceed = loadFromRemote(this.pluginLoadContext, unmanagedDllName);
                this.logger.LoadedUnmanagedFromRemote(unmanagedDllName, valueOrProceed);
            }

            return(NativeAssembly.Create(valueOrProceed.Value, ptrValueOrProceed.Value));
        }
Esempio n. 4
0
        protected virtual ValueOrProceed <AssemblyFromStrategy> LoadFromDefaultContext(IPluginLoadContext pluginLoadContext, AssemblyName assemblyName)
        {
            try
            {
                var assembly = Default.LoadFromAssemblyName(assemblyName);
                if (assembly != null)
                {
                    return(ValueOrProceed <AssemblyFromStrategy> .FromValue(AssemblyFromStrategy.NotReleasable(assembly), 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 PrisePluginException($"Plugin<{typeof(T)}> 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.");
                }
                this.logger.VersionMismatch(assemblyName, hostAssembly.DependencyName);
            }

            return(ValueOrProceed <AssemblyFromStrategy> .Proceed());
        }
        protected virtual ValueOrProceed <string> LoadUnmanagedFromDependencyContext(IPluginLoadContext pluginLoadContext, string unmanagedDllName)
        {
            var unmanagedDllNameWithoutFileExtension = Path.GetFileNameWithoutExtension(unmanagedDllName);
            var platformDependency = this.pluginDependencyContext.PlatformDependencies.FirstOrDefault(d => d.DependencyNameWithoutExtension == unmanagedDllNameWithoutFileExtension);

            if (platformDependency != null)
            {
                var dependencyPath = this.dependencyPathProvider.GetDependencyPath();

                if (String.IsNullOrEmpty(dependencyPath))
                {
                    dependencyPath = pluginLoadContext.PluginAssemblyPath;
                }

                var probingPaths     = this.probingPathsProvider.GetProbingPaths();
                var pathToDependency = this.pluginDependencyResolver.ResolvePlatformDependencyToPath(dependencyPath, probingPaths, platformDependency);
                if (!String.IsNullOrEmpty(pathToDependency))
                {
                    string runtimeCandidate = null;
                    if (this.options.NativeDependencyLoadPreference == NativeDependencyLoadPreference.PreferInstalledRuntime)
                    {
                        // Prefer loading from runtime folder
                        runtimeCandidate = this.pluginDependencyResolver.ResolvePlatformDependencyPathToRuntime(this.options.PluginPlatformVersion, pathToDependency);
                    }

                    return(ValueOrProceed <string> .FromValue(runtimeCandidate ?? pathToDependency, false));
                }
            }

            return(ValueOrProceed <string> .FromValue(String.Empty, true));
        }
Esempio n. 6
0
 public void LoadedUnmanagedFromAppDomain(string unmanagedDllName, ValueOrProceed <IntPtr> valueOrProceed)
 {
     if (valueOrProceed.Value != IntPtr.Zero)
     {
         Log($"Plugin<{this.pluginType}> unmananged assembly {unmanagedDllName} was loaded from the ApplicationLoadContext.Default");
     }
 }
Esempio n. 7
0
 public void LoadedUnmanagedFromDependencyContext(string unmanagedDllName, ValueOrProceed <string> valueOrProceed)
 {
     if (valueOrProceed.Value != null)
     {
         Log($"Plugin<{this.pluginType}> unmananged assembly {unmanagedDllName} was loaded from the Dependency Context");
     }
 }
Esempio n. 8
0
 public void LoadedFromRemote(AssemblyName assemblyName, ValueOrProceed <AssemblyFromStrategy> valueOrProceed)
 {
     if (valueOrProceed.Value != null)
     {
         Log($"Plugin<{this.pluginType}> assembly {assemblyName.Name} was loaded from the Remote Location");
     }
 }
Esempio n. 9
0
 public void LoadedFromDependencyContext(AssemblyName assemblyName, ValueOrProceed <AssemblyFromStrategy> valueOrProceed)
 {
     if (valueOrProceed.Value != null)
     {
         Log($"Plugin<{this.pluginType}> assembly {assemblyName.Name} was loaded from the Dependency Context");
     }
 }
Esempio n. 10
0
        protected virtual ValueOrProceed <Assembly> LoadFromRemote(IPluginLoadContext pluginLoadContext, AssemblyName assemblyName)
        {
            var assemblyFileName = $"{assemblyName.Name}.dll";

            if (File.Exists(Path.Combine(pluginLoadContext.PluginAssemblyPath, assemblyFileName)))
            {
                return(LoadDependencyFromLocalDisk(pluginLoadContext, assemblyFileName));
            }
            return(ValueOrProceed <Assembly> .Proceed());
        }
Esempio n. 11
0
        protected virtual ValueOrProceed <string> LoadUnmanagedFromRemote(IPluginLoadContext pluginLoadContext, string unmanagedDllName)
        {
            var assemblyFileName = $"{unmanagedDllName}.dll";
            var pathToDependency = Path.Combine(pluginLoadContext.PluginAssemblyPath, assemblyFileName);

            if (File.Exists(pathToDependency))
            {
                return(ValueOrProceed <string> .FromValue(pathToDependency, false));
            }
            return(ValueOrProceed <string> .FromValue(String.Empty, true));
        }
        /// <summary>
        /// This override includes the netcore 3.0 resolver
        /// </summary>
        /// <param name="assemblyName"></param>
        /// <returns></returns>
        protected override ValueOrProceed <Assembly> LoadFromDependencyContext(IPluginLoadContext pluginLoadContext, AssemblyName assemblyName)
        {
            var assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);

            if (!String.IsNullOrEmpty(assemblyPath) && File.Exists(assemblyPath))
            {
                return(ValueOrProceed <Assembly> .FromValue(LoadFromAssemblyPath(assemblyPath), false));
            }

            return(base.LoadFromDependencyContext(pluginLoadContext, assemblyName));
        }
        protected override ValueOrProceed <Assembly> LoadFromRemote(IPluginLoadContext pluginLoadContext, AssemblyName assemblyName)
        {
            var networkAssembly = LoadDependencyFromNetwork(assemblyName);

            if (networkAssembly != null)
            {
                return(ValueOrProceed <Assembly> .FromValue(networkAssembly, false));
            }

            return(ValueOrProceed <Assembly> .Proceed());
        }
Esempio n. 14
0
        protected virtual ValueOrProceed <IntPtr> LoadUnmanagedFromDefault(IPluginLoadContext pluginLoadContext, string unmanagedDllName)
        {
            var resolution = base.LoadUnmanagedDll(unmanagedDllName);

            if (resolution == default(IntPtr))
            {
                return(ValueOrProceed <IntPtr> .Proceed());
            }

            return(ValueOrProceed <IntPtr> .FromValue(resolution, false));
        }
Esempio n. 15
0
        protected virtual ValueOrProceed <Assembly> LoadDependencyFromLocalDisk(IPluginLoadContext pluginLoadContext, string assemblyFileName)
        {
            var dependency = LoadFileFromLocalDisk(pluginLoadContext.PluginAssemblyPath, assemblyFileName);

            if (dependency == null)
            {
                return(ValueOrProceed <Assembly> .Proceed());
            }

            return(ValueOrProceed <Assembly> .FromValue(Assembly.Load(ToByteArray(dependency)), false));
        }
        protected override ValueOrProceed <string> LoadUnmanagedFromRemote(IPluginLoadContext pluginLoadContext, string unmanagedDllName)
        {
            var networkUrl  = $"{this.baseUrl}/{unmanagedDllName}";
            var networkFile = NetworkUtil.Download(this.httpClient, networkUrl);

            if (networkFile != null)
            {
                return(ValueOrProceed <string> .FromValue(NetworkUtil.SaveToTempFolder(this.tempPathProvider.ProvideTempPath($"{unmanagedDllName}.dll"), networkFile), false));
            }

            return(ValueOrProceed <string> .FromValue(String.Empty, true));
        }
Esempio n. 17
0
        protected virtual ValueOrProceed <Assembly> LoadFromDefaultContext(IPluginLoadContext pluginLoadContext, AssemblyName assemblyName)
        {
            try
            {
                var assembly = Default.LoadFromAssemblyName(assemblyName);
                if (assembly != null)
                {
                    return(ValueOrProceed <Assembly> .FromValue(assembly, false));
                }
            }
            catch (FileNotFoundException) { }

            return(ValueOrProceed <Assembly> .Proceed());
        }
        /// <summary>
        /// This override includes the netcore 3.0 resolver
        /// </summary>
        /// <param name="unmanagedDllName"></param>
        /// <returns></returns>
        protected override ValueOrProceed <string> LoadUnmanagedFromDependencyContext(IPluginLoadContext pluginLoadContext, string unmanagedDllName)
        {
            string libraryPath = resolver.ResolveUnmanagedDllToPath(unmanagedDllName);

            if (!String.IsNullOrEmpty(libraryPath))
            {
                string runtimeCandidate = null;
                if (this.options.NativeDependencyLoadPreference == NativeDependencyLoadPreference.PreferInstalledRuntime)
                {
                    // Prefer loading from runtime folder
                    runtimeCandidate = this.pluginDependencyResolver.ResolvePlatformDependencyPathToRuntime(this.options.PluginPlatformVersion, libraryPath);
                }

                return(ValueOrProceed <string> .FromValue(runtimeCandidate ?? libraryPath, false));
            }

            return(base.LoadUnmanagedFromDependencyContext(pluginLoadContext, unmanagedDllName));
        }
Esempio n. 19
0
        protected virtual ValueOrProceed <Assembly> LoadFromDependencyContext(IPluginLoadContext pluginLoadContext, AssemblyName assemblyName)
        {
            if (IsResourceAssembly(assemblyName))
            {
                foreach (var resourceDependency in this.pluginDependencyContext.PluginResourceDependencies)
                {
                    var resourcePath = Path.Combine(resourceDependency.Path, assemblyName.CultureName, assemblyName.Name + ".dll");
                    if (File.Exists(resourcePath))
                    {
                        return(ValueOrProceed <Assembly> .FromValue(LoadFromAssemblyPath(resourcePath), false));
                    }
                }

                // Do not proceed probing
                return(ValueOrProceed <Assembly> .FromValue(null, false));
            }

            var pluginDependency = this.pluginDependencyContext.PluginDependencies.FirstOrDefault(d => d.DependencyNameWithoutExtension == assemblyName.Name);

            if (pluginDependency != null)
            {
                var dependencyPath = this.dependencyPathProvider.GetDependencyPath();
                if (String.IsNullOrEmpty(dependencyPath))
                {
                    dependencyPath = pluginLoadContext.PluginAssemblyPath;
                }
                var probingPaths = this.probingPathsProvider.GetProbingPaths();
                var dependency   = this.pluginDependencyResolver.ResolvePluginDependencyToPath(dependencyPath, probingPaths, pluginDependency);
                if (dependency != null)
                {
                    return(ValueOrProceed <Assembly> .FromValue(LoadFromStream(dependency), false));
                }
            }

            var localFile = Path.Combine(this.dependencyPathProvider.GetDependencyPath(), assemblyName.Name + ".dll");

            if (File.Exists(localFile))
            {
                return(ValueOrProceed <Assembly> .FromValue(LoadFromAssemblyPath(localFile), false));
            }

            return(ValueOrProceed <Assembly> .Proceed());
        }
        protected override ValueOrProceed <Assembly> LoadFromDependencyContext(IPluginLoadContext pluginLoadContext, AssemblyName assemblyName)
        {
            if (IsResourceAssembly(assemblyName))
            {
                foreach (var resourceDependency in this.pluginDependencyContext.PluginResourceDependencies)
                {
                    var resourceNetworkPathToAssembly = Path.Combine(this.baseUrl, Path.Combine(resourceDependency.Path, assemblyName.CultureName, $"{assemblyName.Name}.dll"));
                    var resourceNetworkAssembly       = LoadDependencyFromNetwork(resourceNetworkPathToAssembly);
                    if (resourceNetworkAssembly != null)
                    {
                        return(ValueOrProceed <Assembly> .FromValue(resourceNetworkAssembly, false));
                    }
                }

                // Do not proceed probing
                return(ValueOrProceed <Assembly> .FromValue(null, false));
            }

            var pluginDependency = this.pluginDependencyContext.PluginDependencies.FirstOrDefault(d => d.DependencyNameWithoutExtension == assemblyName.Name);

            if (pluginDependency != null)
            {
                var dependencyPath          = this.dependencyPathProvider.GetDependencyPath();
                var probingPaths            = this.probingPathsProvider.GetProbingPaths();
                var resolvedNetworkAssembly = this.pluginDependencyResolver.ResolvePluginDependencyToPath(dependencyPath, probingPaths, pluginDependency);
                if (resolvedNetworkAssembly != null)
                {
                    return(ValueOrProceed <Assembly> .FromValue(LoadFromStream(resolvedNetworkAssembly), false));
                }
            }

            var networkPathToAssembly = $"{baseUrl}/{Path.Combine(this.dependencyPathProvider.GetDependencyPath(), assemblyName.Name)}.dll";
            var networkAssembly       = LoadDependencyFromNetwork(networkPathToAssembly);

            if (networkAssembly != null)
            {
                return(ValueOrProceed <Assembly> .FromValue(networkAssembly, false));
            }

            return(ValueOrProceed <Assembly> .Proceed());
        }
        protected virtual ValueOrProceed <Assembly> LoadFromDefaultContext(IPluginLoadContext pluginLoadContext, AssemblyName assemblyName)
        {
            try
            {
                var assembly = Default.LoadFromAssemblyName(assemblyName);
                if (assembly != null)
                {
                    return(ValueOrProceed <Assembly> .FromValue(assembly, 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)
            {
                this.logger.VersionMismatch(assemblyName, hostAssembly.DependencyName);
            }

            return(ValueOrProceed <Assembly> .Proceed());
        }