diff options
| author | Rob Mensching <rob@firegiant.com> | 2017-11-11 12:41:56 -0800 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2017-11-11 12:41:56 -0800 |
| commit | b6bf1604c32259757f75b4c35444cfe4ecc21a86 (patch) | |
| tree | eb573ffb95d99228dbb40968814ac3eaa01271f7 /src | |
| parent | 9f8cb5374481b6c8a06eb2739858332350f72666 (diff) | |
| download | wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.tar.gz wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.tar.bz2 wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.zip | |
Introduce IExtensionFactory as mechanism to create extensions
Diffstat (limited to 'src')
| -rw-r--r-- | src/WixToolset.BuildTasks/DoIt.cs | 2 | ||||
| -rw-r--r-- | src/WixToolset.Core.Burn/BurnBackendFactory.cs (renamed from src/WixToolset.Core.Burn/BackendFactory.cs) | 2 | ||||
| -rw-r--r-- | src/WixToolset.Core.Burn/BurnExtensionFactory.cs | 22 | ||||
| -rw-r--r-- | src/WixToolset.Core.Burn/WixToolsetStandardBackend.cs (renamed from src/WixToolset.Core.Burn/StandardBackend.cs) | 2 | ||||
| -rw-r--r-- | src/WixToolset.Core.WindowsInstaller/WindowsInstallerExtensionFactory.cs | 22 | ||||
| -rw-r--r-- | src/WixToolset.Core.WindowsInstaller/WixToolsetStandardBackend.cs (renamed from src/WixToolset.Core.WindowsInstaller/StandardBackend.cs) | 2 | ||||
| -rw-r--r-- | src/WixToolset.Core/ExtensionManager.cs | 65 | ||||
| -rw-r--r-- | src/wix/Program.cs | 2 |
8 files changed, 75 insertions, 44 deletions
diff --git a/src/WixToolset.BuildTasks/DoIt.cs b/src/WixToolset.BuildTasks/DoIt.cs index 924bf92f..dddf433c 100644 --- a/src/WixToolset.BuildTasks/DoIt.cs +++ b/src/WixToolset.BuildTasks/DoIt.cs | |||
| @@ -181,7 +181,7 @@ namespace WixToolset.BuildTasks | |||
| 181 | { | 181 | { |
| 182 | var extensionManager = serviceProvider.GetService<IExtensionManager>(); | 182 | var extensionManager = serviceProvider.GetService<IExtensionManager>(); |
| 183 | 183 | ||
| 184 | foreach (var type in new[] { typeof(WixToolset.Core.Burn.StandardBackend), typeof(WixToolset.Core.WindowsInstaller.StandardBackend) }) | 184 | foreach (var type in new[] { typeof(WixToolset.Core.Burn.WixToolsetStandardBackend), typeof(WixToolset.Core.WindowsInstaller.WixToolsetStandardBackend) }) |
| 185 | { | 185 | { |
| 186 | extensionManager.Add(type.Assembly); | 186 | extensionManager.Add(type.Assembly); |
| 187 | } | 187 | } |
diff --git a/src/WixToolset.Core.Burn/BackendFactory.cs b/src/WixToolset.Core.Burn/BurnBackendFactory.cs index a69c47b5..8e2b3ce2 100644 --- a/src/WixToolset.Core.Burn/BackendFactory.cs +++ b/src/WixToolset.Core.Burn/BurnBackendFactory.cs | |||
| @@ -7,7 +7,7 @@ namespace WixToolset.Core.Burn | |||
| 7 | using WixToolset.Extensibility; | 7 | using WixToolset.Extensibility; |
| 8 | using WixToolset.Extensibility.Services; | 8 | using WixToolset.Extensibility.Services; |
| 9 | 9 | ||
| 10 | internal class BackendFactory : IBackendFactory | 10 | internal class BurnBackendFactory : IBackendFactory |
| 11 | { | 11 | { |
| 12 | public bool TryCreateBackend(string outputType, string outputFile, IBindContext context, out IBackend backend) | 12 | public bool TryCreateBackend(string outputType, string outputFile, IBindContext context, out IBackend backend) |
| 13 | { | 13 | { |
diff --git a/src/WixToolset.Core.Burn/BurnExtensionFactory.cs b/src/WixToolset.Core.Burn/BurnExtensionFactory.cs new file mode 100644 index 00000000..b34d12c1 --- /dev/null +++ b/src/WixToolset.Core.Burn/BurnExtensionFactory.cs | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.Burn | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using WixToolset.Extensibility; | ||
| 7 | |||
| 8 | internal class BurnExtensionFactory : IExtensionFactory | ||
| 9 | { | ||
| 10 | public bool TryCreateExtension(Type extensionType, out object extension) | ||
| 11 | { | ||
| 12 | extension = null; | ||
| 13 | |||
| 14 | if (extensionType == typeof(IBackendFactory)) | ||
| 15 | { | ||
| 16 | extension = new BurnBackendFactory(); | ||
| 17 | } | ||
| 18 | |||
| 19 | return extension != null; | ||
| 20 | } | ||
| 21 | } | ||
| 22 | } | ||
diff --git a/src/WixToolset.Core.Burn/StandardBackend.cs b/src/WixToolset.Core.Burn/WixToolsetStandardBackend.cs index 2ab30776..5f589d71 100644 --- a/src/WixToolset.Core.Burn/StandardBackend.cs +++ b/src/WixToolset.Core.Burn/WixToolsetStandardBackend.cs | |||
| @@ -6,7 +6,7 @@ namespace WixToolset.Core.Burn | |||
| 6 | /// Denotes this assembly contains a backend that is considered | 6 | /// Denotes this assembly contains a backend that is considered |
| 7 | /// a standard part of the WiX Toolset. | 7 | /// a standard part of the WiX Toolset. |
| 8 | /// </summary> | 8 | /// </summary> |
| 9 | public static class StandardBackend | 9 | public static class WixToolsetStandardBackend |
| 10 | { | 10 | { |
| 11 | } | 11 | } |
| 12 | } | 12 | } |
diff --git a/src/WixToolset.Core.WindowsInstaller/WindowsInstallerExtensionFactory.cs b/src/WixToolset.Core.WindowsInstaller/WindowsInstallerExtensionFactory.cs new file mode 100644 index 00000000..7b12fc8c --- /dev/null +++ b/src/WixToolset.Core.WindowsInstaller/WindowsInstallerExtensionFactory.cs | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.WindowsInstaller | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using WixToolset.Extensibility; | ||
| 7 | |||
| 8 | internal class WindowsInstallerExtensionFactory : IExtensionFactory | ||
| 9 | { | ||
| 10 | public bool TryCreateExtension(Type extensionType, out object extension) | ||
| 11 | { | ||
| 12 | extension = null; | ||
| 13 | |||
| 14 | if (extensionType == typeof(IBackendFactory)) | ||
| 15 | { | ||
| 16 | extension = new WindowsInstallerBackendFactory(); | ||
| 17 | } | ||
| 18 | |||
| 19 | return extension != null; | ||
| 20 | } | ||
| 21 | } | ||
| 22 | } | ||
diff --git a/src/WixToolset.Core.WindowsInstaller/StandardBackend.cs b/src/WixToolset.Core.WindowsInstaller/WixToolsetStandardBackend.cs index f1ae2017..3751cb54 100644 --- a/src/WixToolset.Core.WindowsInstaller/StandardBackend.cs +++ b/src/WixToolset.Core.WindowsInstaller/WixToolsetStandardBackend.cs | |||
| @@ -6,7 +6,7 @@ namespace WixToolset.Core.WindowsInstaller | |||
| 6 | /// Denotes this assembly contains a backend that is considered | 6 | /// Denotes this assembly contains a backend that is considered |
| 7 | /// a standard part of the WiX Toolset. | 7 | /// a standard part of the WiX Toolset. |
| 8 | /// </summary> | 8 | /// </summary> |
| 9 | public static class StandardBackend | 9 | public static class WixToolsetStandardBackend |
| 10 | { | 10 | { |
| 11 | } | 11 | } |
| 12 | } | 12 | } |
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) |
diff --git a/src/wix/Program.cs b/src/wix/Program.cs index bebd80d5..21a158d2 100644 --- a/src/wix/Program.cs +++ b/src/wix/Program.cs | |||
| @@ -49,7 +49,7 @@ namespace WixToolset.Core | |||
| 49 | { | 49 | { |
| 50 | var extensionManager = serviceProvider.GetService<IExtensionManager>(); | 50 | var extensionManager = serviceProvider.GetService<IExtensionManager>(); |
| 51 | 51 | ||
| 52 | foreach (var type in new[] { typeof(WixToolset.Core.Burn.StandardBackend), typeof(WixToolset.Core.WindowsInstaller.StandardBackend) }) | 52 | foreach (var type in new[] { typeof(WixToolset.Core.Burn.WixToolsetStandardBackend), typeof(WixToolset.Core.WindowsInstaller.WixToolsetStandardBackend) }) |
| 53 | { | 53 | { |
| 54 | extensionManager.Add(type.Assembly); | 54 | extensionManager.Add(type.Assembly); |
| 55 | } | 55 | } |
