// Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.Loader; namespace BTCPayServer.Plugins.Dotnet { /// /// Represents the configuration for a .NET Core plugin. /// public class PluginConfig { /// /// Initializes a new instance of /// /// The full file path to the main assembly for the plugin. public PluginConfig(string mainAssemblyPath) { if (string.IsNullOrEmpty(mainAssemblyPath)) { throw new ArgumentException("Value must be null or not empty", nameof(mainAssemblyPath)); } if (!Path.IsPathRooted(mainAssemblyPath)) { throw new ArgumentException("Value must be an absolute file path", nameof(mainAssemblyPath)); } MainAssemblyPath = mainAssemblyPath; } /// /// The file path to the main assembly. /// public string MainAssemblyPath { get; } /// /// A list of assemblies which should be treated as private. /// public ICollection PrivateAssemblies { get; protected set; } = new List(); /// /// A list of assemblies which should be unified between the host and the plugin. /// /// /// https://github.com/natemcmaster/DotNetCorePlugins/blob/main/docs/what-are-shared-types.md /// public ICollection SharedAssemblies { get; protected set; } = new List(); /// /// Attempt to unify all types from a plugin with the host. /// /// This does not guarantee types will unify. /// /// /// https://github.com/natemcmaster/DotNetCorePlugins/blob/main/docs/what-are-shared-types.md /// /// public bool PreferSharedTypes { get; set; } /// /// If enabled, will lazy load dependencies of all shared assemblies. /// Reduces plugin load time at the expense of non-determinism in how transitive dependencies are loaded /// between the plugin and the host. /// /// Please be aware of the danger of using this option: /// /// https://github.com/natemcmaster/DotNetCorePlugins/pull/164#issuecomment-751557873 /// /// public bool IsLazyLoaded { get; set; } = false; /// /// If set, replaces the default used by the . /// Use this feature if the of the is not the Runtime's default load context. /// i.e. (AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly) != /// public AssemblyLoadContext DefaultContext { get; set; } = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()) ?? AssemblyLoadContext.Default; private bool _isUnloadable; /// /// The plugin can be unloaded from memory. /// public bool IsUnloadable { get => _isUnloadable || EnableHotReload; set => _isUnloadable = value; } private bool _loadInMemory; /// /// Loads assemblies into memory in order to not lock files. /// As example use case here would be: no hot reloading but able to /// replace files and reload manually at later time /// public bool LoadInMemory { get => _loadInMemory || EnableHotReload; set => _loadInMemory = value; } /// /// When any of the loaded files changes on disk, the plugin will be reloaded. /// Use the event to be notified of changes. /// /// /// It will load assemblies into memory in order to not lock files /// /// public bool EnableHotReload { get; set; } /// /// Specifies the delay to reload a plugin, after file changes have been detected. /// Default value is 200 milliseconds. /// public TimeSpan ReloadDelay { get; set; } = TimeSpan.FromMilliseconds(200); } }