From b6bf1604c32259757f75b4c35444cfe4ecc21a86 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sat, 11 Nov 2017 12:41:56 -0800 Subject: Introduce IExtensionFactory as mechanism to create extensions --- src/WixToolset.Core/ExtensionManager.cs | 65 +++++++++++++-------------------- 1 file changed, 26 insertions(+), 39 deletions(-) (limited to 'src/WixToolset.Core') 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 using System.Linq; using System.Reflection; using WixToolset.Data; + using WixToolset.Extensibility; using WixToolset.Extensibility.Services; - public class ExtensionManager : IExtensionManager + internal class ExtensionManager : IExtensionManager { - private List extensionAssemblies = new List(); + private List extensionFactories = new List(); - /// - /// Adds an assembly. - /// - /// Assembly to add to the extension manager. - /// The assembly added. - public Assembly Add(Assembly assembly) + public void Add(Assembly extensionAssembly) { - this.extensionAssemblies.Add(assembly); - return assembly; + var types = extensionAssembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && typeof(IExtensionFactory).IsAssignableFrom(t)); + var factories = types.Select(t => (IExtensionFactory)Activator.CreateInstance(t)).ToList(); + + this.extensionFactories.AddRange(factories); } - /// - /// Loads an assembly from a type description string. - /// - /// The assembly type description string. - /// The loaded assembly. This assembly can be ignored since the extension manager maintains the list of loaded assemblies internally. - /// - /// can be in several different forms: - /// - /// AssemblyName (MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089) - /// Absolute path to an assembly (C:\MyExtensions\ExtensionAssembly.dll) - /// Filename of an assembly in the application directory (ExtensionAssembly.dll) - /// Relative path to an assembly (..\..\MyExtensions\ExtensionAssembly.dll) - /// - /// - public Assembly Load(string extension) + public void Load(string extensionPath) { - string assemblyName = extension; Assembly assembly; // Absolute path to an assembly which means only "load from" will work even though we'd prefer to // use Assembly.Load (see the documentation for Assembly.LoadFrom why). - if (Path.IsPathRooted(assemblyName)) + if (Path.IsPathRooted(extensionPath)) { - assembly = ExtensionManager.ExtensionLoadFrom(assemblyName); + assembly = ExtensionManager.ExtensionLoadFrom(extensionPath); } - else if (ExtensionManager.TryExtensionLoad(assemblyName, out assembly)) + else if (ExtensionManager.TryExtensionLoad(extensionPath, out assembly)) { // Loaded the assembly by name from the probing path. } - else if (ExtensionManager.TryExtensionLoad(Path.GetFileNameWithoutExtension(assemblyName), out assembly)) + else if (ExtensionManager.TryExtensionLoad(Path.GetFileNameWithoutExtension(extensionPath), out assembly)) { // Loaded the assembly by filename alone along the probing path. } @@ -65,21 +48,25 @@ namespace WixToolset.Core // path, so we should try Assembly.LoadFrom one last time. We could have detected a directory // separator character and used Assembly.LoadFrom directly, but dealing with path canonicalization // issues is something we don't want to deal with if we don't have to. - assembly = ExtensionManager.ExtensionLoadFrom(assemblyName); + assembly = ExtensionManager.ExtensionLoadFrom(extensionPath); } - return this.Add(assembly); + this.Add(assembly); } - /// - /// Creates extension of specified type from assemblies loaded into the extension manager. - /// - /// Type of extension to create. - /// Extensions created of the specified type. public IEnumerable Create() where T : class { - var types = this.extensionAssemblies.SelectMany(a => a.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && typeof(T).IsAssignableFrom(t))); - return types.Select(t => (T)Activator.CreateInstance(t)).ToList(); + var extensions = new List(); + + foreach (var factory in this.extensionFactories) + { + if (factory.TryCreateExtension(typeof(T), out var obj) && obj is T extension) + { + extensions.Add(extension); + } + } + + return extensions; } private static Assembly ExtensionLoadFrom(string assemblyName) -- cgit v1.2.3-55-g6feb