diff options
Diffstat (limited to 'src/WixToolset.Core/ExtensionManager.cs')
| -rw-r--r-- | src/WixToolset.Core/ExtensionManager.cs | 65 |
1 files changed, 26 insertions, 39 deletions
diff --git a/src/WixToolset.Core/ExtensionManager.cs b/src/WixToolset.Core/ExtensionManager.cs index b9038c6a..993c21cb 100644 --- a/src/WixToolset.Core/ExtensionManager.cs +++ b/src/WixToolset.Core/ExtensionManager.cs | |||
| @@ -8,53 +8,36 @@ namespace WixToolset.Core | |||
| 8 | using System.Linq; | 8 | using System.Linq; |
| 9 | using System.Reflection; | 9 | using System.Reflection; |
| 10 | using WixToolset.Data; | 10 | using WixToolset.Data; |
| 11 | using WixToolset.Extensibility; | ||
| 11 | using WixToolset.Extensibility.Services; | 12 | using WixToolset.Extensibility.Services; |
| 12 | 13 | ||
| 13 | public class ExtensionManager : IExtensionManager | 14 | internal class ExtensionManager : IExtensionManager |
| 14 | { | 15 | { |
| 15 | private List<Assembly> extensionAssemblies = new List<Assembly>(); | 16 | private List<IExtensionFactory> extensionFactories = new List<IExtensionFactory>(); |
| 16 | 17 | ||
| 17 | /// <summary> | 18 | public void Add(Assembly extensionAssembly) |
| 18 | /// Adds an assembly. | ||
| 19 | /// </summary> | ||
| 20 | /// <param name="assembly">Assembly to add to the extension manager.</param> | ||
| 21 | /// <returns>The assembly added.</returns> | ||
| 22 | public Assembly Add(Assembly assembly) | ||
| 23 | { | 19 | { |
| 24 | this.extensionAssemblies.Add(assembly); | 20 | var types = extensionAssembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && typeof(IExtensionFactory).IsAssignableFrom(t)); |
| 25 | return assembly; | 21 | var factories = types.Select(t => (IExtensionFactory)Activator.CreateInstance(t)).ToList(); |
| 22 | |||
| 23 | this.extensionFactories.AddRange(factories); | ||
| 26 | } | 24 | } |
| 27 | 25 | ||
| 28 | /// <summary> | 26 | public void Load(string extensionPath) |
| 29 | /// Loads an assembly from a type description string. | ||
| 30 | /// </summary> | ||
| 31 | /// <param name="extension">The assembly type description string.</param> | ||
| 32 | /// <returns>The loaded assembly. This assembly can be ignored since the extension manager maintains the list of loaded assemblies internally.</returns> | ||
| 33 | /// <remarks> | ||
| 34 | /// <paramref name="extension"/> can be in several different forms: | ||
| 35 | /// <list type="number"> | ||
| 36 | /// <item><term>AssemblyName (MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089)</term></item> | ||
| 37 | /// <item><term>Absolute path to an assembly (C:\MyExtensions\ExtensionAssembly.dll)</term></item> | ||
| 38 | /// <item><term>Filename of an assembly in the application directory (ExtensionAssembly.dll)</term></item> | ||
| 39 | /// <item><term>Relative path to an assembly (..\..\MyExtensions\ExtensionAssembly.dll)</term></item> | ||
| 40 | /// </list> | ||
| 41 | /// </remarks> | ||
| 42 | public Assembly Load(string extension) | ||
| 43 | { | 27 | { |
| 44 | string assemblyName = extension; | ||
| 45 | Assembly assembly; | 28 | Assembly assembly; |
| 46 | 29 | ||
| 47 | // Absolute path to an assembly which means only "load from" will work even though we'd prefer to | 30 | // Absolute path to an assembly which means only "load from" will work even though we'd prefer to |
| 48 | // use Assembly.Load (see the documentation for Assembly.LoadFrom why). | 31 | // use Assembly.Load (see the documentation for Assembly.LoadFrom why). |
| 49 | if (Path.IsPathRooted(assemblyName)) | 32 | if (Path.IsPathRooted(extensionPath)) |
| 50 | { | 33 | { |
| 51 | assembly = ExtensionManager.ExtensionLoadFrom(assemblyName); | 34 | assembly = ExtensionManager.ExtensionLoadFrom(extensionPath); |
| 52 | } | 35 | } |
| 53 | else if (ExtensionManager.TryExtensionLoad(assemblyName, out assembly)) | 36 | else if (ExtensionManager.TryExtensionLoad(extensionPath, out assembly)) |
| 54 | { | 37 | { |
| 55 | // Loaded the assembly by name from the probing path. | 38 | // Loaded the assembly by name from the probing path. |
| 56 | } | 39 | } |
| 57 | else if (ExtensionManager.TryExtensionLoad(Path.GetFileNameWithoutExtension(assemblyName), out assembly)) | 40 | else if (ExtensionManager.TryExtensionLoad(Path.GetFileNameWithoutExtension(extensionPath), out assembly)) |
| 58 | { | 41 | { |
| 59 | // Loaded the assembly by filename alone along the probing path. | 42 | // Loaded the assembly by filename alone along the probing path. |
| 60 | } | 43 | } |
| @@ -65,21 +48,25 @@ namespace WixToolset.Core | |||
| 65 | // path, so we should try Assembly.LoadFrom one last time. We could have detected a directory | 48 | // path, so we should try Assembly.LoadFrom one last time. We could have detected a directory |
| 66 | // separator character and used Assembly.LoadFrom directly, but dealing with path canonicalization | 49 | // separator character and used Assembly.LoadFrom directly, but dealing with path canonicalization |
| 67 | // issues is something we don't want to deal with if we don't have to. | 50 | // issues is something we don't want to deal with if we don't have to. |
| 68 | assembly = ExtensionManager.ExtensionLoadFrom(assemblyName); | 51 | assembly = ExtensionManager.ExtensionLoadFrom(extensionPath); |
| 69 | } | 52 | } |
| 70 | 53 | ||
| 71 | return this.Add(assembly); | 54 | this.Add(assembly); |
| 72 | } | 55 | } |
| 73 | 56 | ||
| 74 | /// <summary> | ||
| 75 | /// Creates extension of specified type from assemblies loaded into the extension manager. | ||
| 76 | /// </summary> | ||
| 77 | /// <typeparam name="T">Type of extension to create.</typeparam> | ||
| 78 | /// <returns>Extensions created of the specified type.</returns> | ||
| 79 | public IEnumerable<T> Create<T>() where T : class | 57 | public IEnumerable<T> Create<T>() where T : class |
| 80 | { | 58 | { |
| 81 | var types = this.extensionAssemblies.SelectMany(a => a.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && typeof(T).IsAssignableFrom(t))); | 59 | var extensions = new List<T>(); |
| 82 | return types.Select(t => (T)Activator.CreateInstance(t)).ToList(); | 60 | |
| 61 | foreach (var factory in this.extensionFactories) | ||
| 62 | { | ||
| 63 | if (factory.TryCreateExtension(typeof(T), out var obj) && obj is T extension) | ||
| 64 | { | ||
| 65 | extensions.Add(extension); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | return extensions; | ||
| 83 | } | 70 | } |
| 84 | 71 | ||
| 85 | private static Assembly ExtensionLoadFrom(string assemblyName) | 72 | private static Assembly ExtensionLoadFrom(string assemblyName) |
