aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2017-11-11 12:41:56 -0800
committerRob Mensching <rob@firegiant.com>2017-11-11 12:41:56 -0800
commitb6bf1604c32259757f75b4c35444cfe4ecc21a86 (patch)
treeeb573ffb95d99228dbb40968814ac3eaa01271f7
parent9f8cb5374481b6c8a06eb2739858332350f72666 (diff)
downloadwix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.tar.gz
wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.tar.bz2
wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.zip
Introduce IExtensionFactory as mechanism to create extensions
-rw-r--r--src/WixToolset.BuildTasks/DoIt.cs2
-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.cs22
-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.cs22
-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.cs65
-rw-r--r--src/wix/Program.cs2
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
3namespace 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
3namespace 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 }