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.BuildTasks/DoIt.cs | 2 +- src/WixToolset.Core.Burn/BackendFactory.cs | 31 ----------- src/WixToolset.Core.Burn/BurnBackendFactory.cs | 31 +++++++++++ src/WixToolset.Core.Burn/BurnExtensionFactory.cs | 22 ++++++++ src/WixToolset.Core.Burn/StandardBackend.cs | 12 ---- .../WixToolsetStandardBackend.cs | 12 ++++ .../StandardBackend.cs | 12 ---- .../WindowsInstallerExtensionFactory.cs | 22 ++++++++ .../WixToolsetStandardBackend.cs | 12 ++++ src/WixToolset.Core/ExtensionManager.cs | 65 +++++++++------------- src/wix/Program.cs | 2 +- 11 files changed, 127 insertions(+), 96 deletions(-) delete mode 100644 src/WixToolset.Core.Burn/BackendFactory.cs create mode 100644 src/WixToolset.Core.Burn/BurnBackendFactory.cs create mode 100644 src/WixToolset.Core.Burn/BurnExtensionFactory.cs delete mode 100644 src/WixToolset.Core.Burn/StandardBackend.cs create mode 100644 src/WixToolset.Core.Burn/WixToolsetStandardBackend.cs delete mode 100644 src/WixToolset.Core.WindowsInstaller/StandardBackend.cs create mode 100644 src/WixToolset.Core.WindowsInstaller/WindowsInstallerExtensionFactory.cs create mode 100644 src/WixToolset.Core.WindowsInstaller/WixToolsetStandardBackend.cs (limited to 'src') 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 { var extensionManager = serviceProvider.GetService(); - foreach (var type in new[] { typeof(WixToolset.Core.Burn.StandardBackend), typeof(WixToolset.Core.WindowsInstaller.StandardBackend) }) + foreach (var type in new[] { typeof(WixToolset.Core.Burn.WixToolsetStandardBackend), typeof(WixToolset.Core.WindowsInstaller.WixToolsetStandardBackend) }) { extensionManager.Add(type.Assembly); } diff --git a/src/WixToolset.Core.Burn/BackendFactory.cs b/src/WixToolset.Core.Burn/BackendFactory.cs deleted file mode 100644 index a69c47b5..00000000 --- a/src/WixToolset.Core.Burn/BackendFactory.cs +++ /dev/null @@ -1,31 +0,0 @@ -// 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. - -namespace WixToolset.Core.Burn -{ - using System; - using System.IO; - using WixToolset.Extensibility; - using WixToolset.Extensibility.Services; - - internal class BackendFactory : IBackendFactory - { - public bool TryCreateBackend(string outputType, string outputFile, IBindContext context, out IBackend backend) - { - if (String.IsNullOrEmpty(outputType)) - { - outputType = Path.GetExtension(outputFile); - } - - switch (outputType.ToLowerInvariant()) - { - case "bundle": - case ".exe": - backend = new BundleBackend(); - return true; - } - - backend = null; - return false; - } - } -} diff --git a/src/WixToolset.Core.Burn/BurnBackendFactory.cs b/src/WixToolset.Core.Burn/BurnBackendFactory.cs new file mode 100644 index 00000000..8e2b3ce2 --- /dev/null +++ b/src/WixToolset.Core.Burn/BurnBackendFactory.cs @@ -0,0 +1,31 @@ +// 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. + +namespace WixToolset.Core.Burn +{ + using System; + using System.IO; + using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; + + internal class BurnBackendFactory : IBackendFactory + { + public bool TryCreateBackend(string outputType, string outputFile, IBindContext context, out IBackend backend) + { + if (String.IsNullOrEmpty(outputType)) + { + outputType = Path.GetExtension(outputFile); + } + + switch (outputType.ToLowerInvariant()) + { + case "bundle": + case ".exe": + backend = new BundleBackend(); + return true; + } + + backend = null; + return false; + } + } +} 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 @@ +// 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. + +namespace WixToolset.Core.Burn +{ + using System; + using WixToolset.Extensibility; + + internal class BurnExtensionFactory : IExtensionFactory + { + public bool TryCreateExtension(Type extensionType, out object extension) + { + extension = null; + + if (extensionType == typeof(IBackendFactory)) + { + extension = new BurnBackendFactory(); + } + + return extension != null; + } + } +} diff --git a/src/WixToolset.Core.Burn/StandardBackend.cs b/src/WixToolset.Core.Burn/StandardBackend.cs deleted file mode 100644 index 2ab30776..00000000 --- a/src/WixToolset.Core.Burn/StandardBackend.cs +++ /dev/null @@ -1,12 +0,0 @@ -// 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. - -namespace WixToolset.Core.Burn -{ - /// - /// Denotes this assembly contains a backend that is considered - /// a standard part of the WiX Toolset. - /// - public static class StandardBackend - { - } -} diff --git a/src/WixToolset.Core.Burn/WixToolsetStandardBackend.cs b/src/WixToolset.Core.Burn/WixToolsetStandardBackend.cs new file mode 100644 index 00000000..5f589d71 --- /dev/null +++ b/src/WixToolset.Core.Burn/WixToolsetStandardBackend.cs @@ -0,0 +1,12 @@ +// 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. + +namespace WixToolset.Core.Burn +{ + /// + /// Denotes this assembly contains a backend that is considered + /// a standard part of the WiX Toolset. + /// + public static class WixToolsetStandardBackend + { + } +} diff --git a/src/WixToolset.Core.WindowsInstaller/StandardBackend.cs b/src/WixToolset.Core.WindowsInstaller/StandardBackend.cs deleted file mode 100644 index f1ae2017..00000000 --- a/src/WixToolset.Core.WindowsInstaller/StandardBackend.cs +++ /dev/null @@ -1,12 +0,0 @@ -// 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. - -namespace WixToolset.Core.WindowsInstaller -{ - /// - /// Denotes this assembly contains a backend that is considered - /// a standard part of the WiX Toolset. - /// - public static class StandardBackend - { - } -} 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 @@ +// 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. + +namespace WixToolset.Core.WindowsInstaller +{ + using System; + using WixToolset.Extensibility; + + internal class WindowsInstallerExtensionFactory : IExtensionFactory + { + public bool TryCreateExtension(Type extensionType, out object extension) + { + extension = null; + + if (extensionType == typeof(IBackendFactory)) + { + extension = new WindowsInstallerBackendFactory(); + } + + return extension != null; + } + } +} diff --git a/src/WixToolset.Core.WindowsInstaller/WixToolsetStandardBackend.cs b/src/WixToolset.Core.WindowsInstaller/WixToolsetStandardBackend.cs new file mode 100644 index 00000000..3751cb54 --- /dev/null +++ b/src/WixToolset.Core.WindowsInstaller/WixToolsetStandardBackend.cs @@ -0,0 +1,12 @@ +// 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. + +namespace WixToolset.Core.WindowsInstaller +{ + /// + /// Denotes this assembly contains a backend that is considered + /// a standard part of the WiX Toolset. + /// + public static class WixToolsetStandardBackend + { + } +} 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) 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 { var extensionManager = serviceProvider.GetService(); - foreach (var type in new[] { typeof(WixToolset.Core.Burn.StandardBackend), typeof(WixToolset.Core.WindowsInstaller.StandardBackend) }) + foreach (var type in new[] { typeof(WixToolset.Core.Burn.WixToolsetStandardBackend), typeof(WixToolset.Core.WindowsInstaller.WixToolsetStandardBackend) }) { extensionManager.Add(type.Assembly); } -- cgit v1.2.3-55-g6feb