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 | |
parent | 9f8cb5374481b6c8a06eb2739858332350f72666 (diff) | |
download | wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.tar.gz wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.tar.bz2 wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.zip |
Introduce IExtensionFactory as mechanism to create extensions
-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 | } |