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/WixToolset.Core | |
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/WixToolset.Core')
-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) |