|
1 | | -// Copyright (c) Nate McMaster. |
2 | | -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. |
3 | | - |
4 | | -using System; |
5 | | -using System.Collections.Generic; |
6 | | -using System.IO; |
7 | | -using System.Reflection; |
8 | | -using System.Runtime.Loader; |
9 | | - |
10 | | -namespace McMaster.NETCore.Plugins |
11 | | -{ |
12 | | - /// <summary> |
13 | | - /// Represents the configuration for a .NET Core plugin. |
14 | | - /// </summary> |
15 | | - public class PluginConfig |
16 | | - { |
17 | | - /// <summary> |
18 | | - /// Initializes a new instance of <see cref="PluginConfig" /> |
19 | | - /// </summary> |
20 | | - /// <param name="mainAssemblyPath">The full file path to the main assembly for the plugin.</param> |
21 | | - public PluginConfig(string mainAssemblyPath) |
22 | | - { |
23 | | - if (string.IsNullOrEmpty(mainAssemblyPath)) |
24 | | - { |
25 | | - throw new ArgumentException("Value must be null or not empty", nameof(mainAssemblyPath)); |
26 | | - } |
27 | | - |
28 | | - if (!Path.IsPathRooted(mainAssemblyPath)) |
29 | | - { |
30 | | - throw new ArgumentException("Value must be an absolute file path", nameof(mainAssemblyPath)); |
31 | | - } |
32 | | - |
33 | | - MainAssemblyPath = mainAssemblyPath; |
34 | | - } |
35 | | - |
36 | | - /// <summary> |
37 | | - /// The file path to the main assembly. |
38 | | - /// </summary> |
39 | | - public string MainAssemblyPath { get; } |
40 | | - |
41 | | - /// <summary> |
42 | | - /// A list of assemblies which should be treated as private. |
43 | | - /// </summary> |
44 | | - public ICollection<AssemblyName> PrivateAssemblies { get; protected set; } = new List<AssemblyName>(); |
45 | | - |
46 | | - /// <summary> |
47 | | - /// A list of assemblies which should be unified between the host and the plugin. |
48 | | - /// </summary> |
49 | | - /// <seealso href="https://github.com/natemcmaster/DotNetCorePlugins/blob/master/docs/what-are-shared-types.md"> |
50 | | - /// https://github.com/natemcmaster/DotNetCorePlugins/blob/master/docs/what-are-shared-types.md |
51 | | - /// </seealso> |
52 | | - public ICollection<AssemblyName> SharedAssemblies { get; protected set; } = new List<AssemblyName>(); |
53 | | - |
54 | | - /// <summary> |
55 | | - /// Attempt to unify all types from a plugin with the host. |
56 | | - /// <para> |
57 | | - /// This does not guarantee types will unify. |
58 | | - /// </para> |
59 | | - /// <seealso href="https://github.com/natemcmaster/DotNetCorePlugins/blob/master/docs/what-are-shared-types.md"> |
60 | | - /// https://github.com/natemcmaster/DotNetCorePlugins/blob/master/docs/what-are-shared-types.md |
61 | | - /// </seealso> |
62 | | - /// </summary> |
63 | | - public bool PreferSharedTypes { get; set; } |
64 | | - |
65 | | - /// <summary> |
66 | | - /// If enabled, will lazy load dependencies of all shared assemblies. |
67 | | - /// Reduces plugin load time at the expense of non-determinism in how transitive dependencies are loaded |
68 | | - /// between the plugin and the host. |
69 | | - /// |
70 | | - /// Please be aware of the danger of using this option: |
71 | | - /// <seealso href="https://github.com/natemcmaster/DotNetCorePlugins/pull/164#issuecomment-751557873"> |
72 | | - /// https://github.com/natemcmaster/DotNetCorePlugins/pull/164#issuecomment-751557873 |
73 | | - /// </seealso> |
74 | | - /// </summary> |
75 | | - public bool IsLazyLoaded { get; set; } = false; |
76 | | - |
77 | | - /// <summary> |
78 | | - /// If set, replaces the default <see cref="AssemblyLoadContext"/> used by the <see cref="PluginLoader"/>. |
79 | | - /// Use this feature if the <see cref="AssemblyLoadContext"/> of the <see cref="Assembly"/> is not the Runtime's default load context. |
80 | | - /// i.e. (AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly) != <see cref="AssemblyLoadContext.Default"/> |
81 | | - /// </summary> |
82 | | - public AssemblyLoadContext DefaultContext { get; set; } = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()) ?? AssemblyLoadContext.Default; |
83 | | - |
84 | | -#if FEATURE_UNLOAD |
85 | | - private bool _isUnloadable; |
86 | | - |
87 | | - /// <summary> |
88 | | - /// The plugin can be unloaded from memory. |
89 | | - /// </summary> |
90 | | - public bool IsUnloadable |
91 | | - { |
92 | | - get => _isUnloadable || EnableHotReload; |
93 | | - set => _isUnloadable = value; |
94 | | - } |
95 | | - |
96 | | - private bool _loadInMemory; |
97 | | - |
98 | | - /// <summary> |
99 | | - /// Loads assemblies into memory in order to not lock files. |
100 | | - /// As example use case here would be: no hot reloading but able to |
101 | | - /// replace files and reload manually at later time |
102 | | - /// </summary> |
103 | | - public bool LoadInMemory |
104 | | - { |
105 | | - get => _loadInMemory || EnableHotReload; |
106 | | - set => _loadInMemory = value; |
107 | | - } |
108 | | - |
109 | | - /// <summary> |
110 | | - /// When any of the loaded files changes on disk, the plugin will be reloaded. |
111 | | - /// Use the event <see cref="PluginLoader.Reloaded" /> to be notified of changes. |
112 | | - /// </summary> |
113 | | - /// <remarks> |
114 | | - /// It will load assemblies into memory in order to not lock files |
115 | | - /// <see cref="LoadInMemory"/> |
116 | | - /// </remarks> |
117 | | - public bool EnableHotReload { get; set; } |
118 | | - |
119 | | - /// <summary> |
120 | | - /// Specifies the delay to reload a plugin, after file changes have been detected. |
121 | | - /// Default value is 200 milliseconds. |
122 | | - /// </summary> |
123 | | - public TimeSpan ReloadDelay { get; set; } = TimeSpan.FromMilliseconds(200); |
124 | | -#endif |
125 | | - } |
126 | | -} |
| 1 | +// Copyright (c) Nate McMaster. |
| 2 | +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. |
| 3 | + |
| 4 | +using System; |
| 5 | +using System.Collections.Generic; |
| 6 | +using System.IO; |
| 7 | +using System.Reflection; |
| 8 | +using System.Runtime.Loader; |
| 9 | + |
| 10 | +namespace McMaster.NETCore.Plugins |
| 11 | +{ |
| 12 | + /// <summary> |
| 13 | + /// Represents the configuration for a .NET Core plugin. |
| 14 | + /// </summary> |
| 15 | + public class PluginConfig |
| 16 | + { |
| 17 | + /// <summary> |
| 18 | + /// Initializes a new instance of <see cref="PluginConfig" /> |
| 19 | + /// </summary> |
| 20 | + /// <param name="mainAssemblyPath">The full file path to the main assembly for the plugin.</param> |
| 21 | + public PluginConfig(string mainAssemblyPath) |
| 22 | + { |
| 23 | + if (string.IsNullOrEmpty(mainAssemblyPath)) |
| 24 | + { |
| 25 | + throw new ArgumentException("Value must be null or not empty", nameof(mainAssemblyPath)); |
| 26 | + } |
| 27 | + |
| 28 | + if (!Path.IsPathRooted(mainAssemblyPath)) |
| 29 | + { |
| 30 | + throw new ArgumentException("Value must be an absolute file path", nameof(mainAssemblyPath)); |
| 31 | + } |
| 32 | + |
| 33 | + MainAssemblyPath = mainAssemblyPath; |
| 34 | + } |
| 35 | + |
| 36 | + /// <summary> |
| 37 | + /// The file path to the main assembly. |
| 38 | + /// </summary> |
| 39 | + public string MainAssemblyPath { get; } |
| 40 | + |
| 41 | + /// <summary> |
| 42 | + /// A list of assemblies which should be treated as private. |
| 43 | + /// </summary> |
| 44 | + public ICollection<AssemblyName> PrivateAssemblies { get; protected set; } = new List<AssemblyName>(); |
| 45 | + |
| 46 | + /// <summary> |
| 47 | + /// A list of assemblies which should be unified between the host and the plugin. |
| 48 | + /// </summary> |
| 49 | + /// <seealso href="https://github.com/natemcmaster/DotNetCorePlugins/blob/master/docs/what-are-shared-types.md"> |
| 50 | + /// https://github.com/natemcmaster/DotNetCorePlugins/blob/master/docs/what-are-shared-types.md |
| 51 | + /// </seealso> |
| 52 | + public ICollection<AssemblyName> SharedAssemblies { get; protected set; } = new List<AssemblyName>(); |
| 53 | + |
| 54 | + /// <summary> |
| 55 | + /// Attempt to unify all types from a plugin with the host. |
| 56 | + /// <para> |
| 57 | + /// This does not guarantee types will unify. |
| 58 | + /// </para> |
| 59 | + /// <seealso href="https://github.com/natemcmaster/DotNetCorePlugins/blob/master/docs/what-are-shared-types.md"> |
| 60 | + /// https://github.com/natemcmaster/DotNetCorePlugins/blob/master/docs/what-are-shared-types.md |
| 61 | + /// </seealso> |
| 62 | + /// </summary> |
| 63 | + public bool PreferSharedTypes { get; set; } |
| 64 | + |
| 65 | + /// <summary> |
| 66 | + /// If enabled, will lazy load dependencies of all shared assemblies. |
| 67 | + /// Reduces plugin load time at the expense of non-determinism in how transitive dependencies are loaded |
| 68 | + /// between the plugin and the host. |
| 69 | + /// |
| 70 | + /// Please be aware of the danger of using this option: |
| 71 | + /// <seealso href="https://github.com/natemcmaster/DotNetCorePlugins/pull/164#issuecomment-751557873"> |
| 72 | + /// https://github.com/natemcmaster/DotNetCorePlugins/pull/164#issuecomment-751557873 |
| 73 | + /// </seealso> |
| 74 | + /// </summary> |
| 75 | + public bool IsLazyLoaded { get; set; } = false; |
| 76 | + |
| 77 | + /// <summary> |
| 78 | + /// If set, replaces the default <see cref="AssemblyLoadContext"/> used by the <see cref="PluginLoader"/>. |
| 79 | + /// Use this feature if the <see cref="AssemblyLoadContext"/> of the <see cref="Assembly"/> is not the Runtime's default load context. |
| 80 | + /// i.e. (AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly) != <see cref="AssemblyLoadContext.Default"/> |
| 81 | + /// </summary> |
| 82 | + public AssemblyLoadContext DefaultContext { get; set; } = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()) ?? AssemblyLoadContext.Default; |
| 83 | + |
| 84 | +#if FEATURE_UNLOAD |
| 85 | + private bool _isUnloadable; |
| 86 | + |
| 87 | + /// <summary> |
| 88 | + /// The plugin can be unloaded from memory. |
| 89 | + /// </summary> |
| 90 | + public bool IsUnloadable |
| 91 | + { |
| 92 | + get => _isUnloadable || EnableHotReload; |
| 93 | + set => _isUnloadable = value; |
| 94 | + } |
| 95 | + |
| 96 | + private bool _loadInMemory; |
| 97 | + |
| 98 | + /// <summary> |
| 99 | + /// Loads assemblies into memory in order to not lock files. |
| 100 | + /// As example use case here would be: no hot reloading but able to |
| 101 | + /// replace files and reload manually at later time |
| 102 | + /// </summary> |
| 103 | + public bool LoadInMemory |
| 104 | + { |
| 105 | + get => _loadInMemory || EnableHotReload; |
| 106 | + set => _loadInMemory = value; |
| 107 | + } |
| 108 | + |
| 109 | + /// <summary> |
| 110 | + /// When any of the loaded files changes on disk, the plugin will be reloaded. |
| 111 | + /// Use the event <see cref="PluginLoader.Reloaded" /> to be notified of changes. |
| 112 | + /// </summary> |
| 113 | + /// <remarks> |
| 114 | + /// It will load assemblies into memory in order to not lock files |
| 115 | + /// <see cref="LoadInMemory"/> |
| 116 | + /// </remarks> |
| 117 | + public bool EnableHotReload { get; set; } |
| 118 | + |
| 119 | + /// <summary> |
| 120 | + /// Specifies the delay to reload a plugin, after file changes have been detected. |
| 121 | + /// Default value is 200 milliseconds. |
| 122 | + /// </summary> |
| 123 | + public TimeSpan ReloadDelay { get; set; } = TimeSpan.FromMilliseconds(200); |
| 124 | +#endif |
| 125 | + } |
| 126 | +} |
0 commit comments