aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core
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 /src/WixToolset.Core
parent9f8cb5374481b6c8a06eb2739858332350f72666 (diff)
downloadwix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.tar.gz
wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.tar.bz2
wix-b6bf1604c32259757f75b4c35444cfe4ecc21a86.zip
Introduce IExtensionFactory as mechanism to create extensions
Diffstat (limited to 'src/WixToolset.Core')
-rw-r--r--src/WixToolset.Core/ExtensionManager.cs65
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)