From c08fd0aefeea1628fe93c818ca4dde63fd6ac2e1 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 17 Oct 2017 02:47:44 -0700 Subject: Introduce WixToolsetServiceProvider Using a service provider allows all of WixToolset.Core's internal functionality to be abstracted behind interfaces in WixToolset.Extensibility. The service provide can also control what interfaces are singletons. --- src/WixToolset.Core/BindContext.cs | 9 +++ src/WixToolset.Core/Binder.cs | 5 +- src/WixToolset.Core/CommandLine/BuildCommand.cs | 10 +++- src/WixToolset.Core/CommandLine/CommandLine.cs | 64 ++++++++++------------ .../CommandLine/CommandLineContext.cs | 26 +++++++++ src/WixToolset.Core/CommandLine/CompileCommand.cs | 3 +- src/WixToolset.Core/CommandLine/HelpCommand.cs | 1 + .../CommandLine/ICommandLineCommand.cs | 9 --- src/WixToolset.Core/CommandLine/VersionCommand.cs | 5 +- src/WixToolset.Core/ExtensionManager.cs | 18 ++++-- src/WixToolset.Core/IncribeContext.cs | 8 +++ src/WixToolset.Core/WixToolsetServiceProvider.cs | 47 ++++++++++++++++ 12 files changed, 149 insertions(+), 56 deletions(-) create mode 100644 src/WixToolset.Core/CommandLine/CommandLineContext.cs delete mode 100644 src/WixToolset.Core/CommandLine/ICommandLineCommand.cs create mode 100644 src/WixToolset.Core/WixToolsetServiceProvider.cs (limited to 'src/WixToolset.Core') diff --git a/src/WixToolset.Core/BindContext.cs b/src/WixToolset.Core/BindContext.cs index 499f3245..7b1a1877 100644 --- a/src/WixToolset.Core/BindContext.cs +++ b/src/WixToolset.Core/BindContext.cs @@ -2,12 +2,21 @@ namespace WixToolset.Core { + using System; using System.Collections.Generic; using WixToolset.Data; using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; public class BindContext : IBindContext { + internal BindContext(IServiceProvider serviceProvider) + { + this.ServiceProvider = serviceProvider; + } + + public IServiceProvider ServiceProvider { get; } + public Messaging Messaging { get; set; } public IEnumerable BindPaths { get; set; } diff --git a/src/WixToolset.Core/Binder.cs b/src/WixToolset.Core/Binder.cs index 43c15634..34bf0dee 100644 --- a/src/WixToolset.Core/Binder.cs +++ b/src/WixToolset.Core/Binder.cs @@ -16,6 +16,7 @@ namespace WixToolset.Core using WixToolset.Data.Bind; using WixToolset.Data.Rows; using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; /// /// Binder of the WiX toolset. @@ -42,14 +43,14 @@ namespace WixToolset.Core //this.SuppressIces = new List(); } - public Binder(BindContext context) + public Binder(IBindContext context) { this.Context = context; this.TableDefinitions = WindowsInstallerStandard.GetTableDefinitions(); } - private BindContext Context { get; } + private IBindContext Context { get; } private TableDefinitionCollection TableDefinitions { get; } diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs index b3909451..4a1fc1ed 100644 --- a/src/WixToolset.Core/CommandLine/BuildCommand.cs +++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs @@ -9,11 +9,13 @@ namespace WixToolset.Core using WixToolset.Data; using WixToolset.Data.Rows; using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; internal class BuildCommand : ICommandLineCommand { - public BuildCommand(ExtensionManager extensions, IEnumerable sources, IDictionary preprocessorVariables, IEnumerable locFiles, IEnumerable libraryFiles, string outputPath, OutputType outputType, string cabCachePath, IEnumerable cultures, bool bindFiles, IEnumerable bindPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile, string wixProjectFile) + public BuildCommand(IServiceProvider serviceProvider, IExtensionManager extensions, IEnumerable sources, IDictionary preprocessorVariables, IEnumerable locFiles, IEnumerable libraryFiles, string outputPath, OutputType outputType, string cabCachePath, IEnumerable cultures, bool bindFiles, IEnumerable bindPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile, string wixProjectFile) { + this.ServiceProvider = serviceProvider; this.ExtensionManager = extensions; this.LocFiles = locFiles; this.LibraryFiles = libraryFiles; @@ -34,7 +36,9 @@ namespace WixToolset.Core this.WixProjectFile = wixProjectFile; } - public ExtensionManager ExtensionManager { get; } + public IServiceProvider ServiceProvider { get; } + + public IExtensionManager ExtensionManager { get; } public IEnumerable LocFiles { get; } @@ -173,7 +177,7 @@ namespace WixToolset.Core intermediateFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); } - var context = new BindContext(); + var context = this.ServiceProvider.GetService(); context.Messaging = Messaging.Instance; context.ExtensionManager = this.ExtensionManager; context.BindPaths = this.BindPaths ?? Array.Empty(); diff --git a/src/WixToolset.Core/CommandLine/CommandLine.cs b/src/WixToolset.Core/CommandLine/CommandLine.cs index 2f203ecb..b0594348 100644 --- a/src/WixToolset.Core/CommandLine/CommandLine.cs +++ b/src/WixToolset.Core/CommandLine/CommandLine.cs @@ -6,11 +6,11 @@ namespace WixToolset.Core using System.Collections.Generic; using System.IO; using System.Linq; - using System.Reflection; using System.Text; using System.Text.RegularExpressions; using WixToolset.Data; using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; internal enum Commands { @@ -22,12 +22,14 @@ namespace WixToolset.Core Bind, } - public class CommandLine + internal class CommandLine : ICommandLine { - private CommandLine() + public CommandLine() { } + private IServiceProvider ServiceProvider { get; set; } + public static string ExpectedArgument { get; } = "expected argument"; public string ActiveCommand { get; private set; } @@ -36,20 +38,29 @@ namespace WixToolset.Core public Queue RemainingArguments { get; } = new Queue(); - public ExtensionManager ExtensionManager { get; } = new ExtensionManager(); + public IExtensionManager ExtensionManager { get; private set; } public string ErrorArgument { get; set; } public bool ShowHelp { get; set; } - public static ICommandLineCommand ParseStandardCommandLine(string commandLineString) + public ICommandLineCommand ParseStandardCommandLine(ICommandLineContext context) { - var args = CommandLine.ParseArgumentsToArray(commandLineString).ToArray(); + this.ServiceProvider = context.ServiceProvider; + + this.ExtensionManager = context.ExtensionManager ?? this.ServiceProvider.GetService(); + + var args = context.ParsedArguments ?? Array.Empty(); + + if (!String.IsNullOrEmpty(context.Arguments)) + { + args = CommandLine.ParseArgumentsToArray(context.Arguments).Union(args).ToArray(); + } - return ParseStandardCommandLine(args); + return this.ParseStandardCommandLine(args); } - public static ICommandLineCommand ParseStandardCommandLine(string[] args) + private ICommandLineCommand ParseStandardCommandLine(string[] args) { var next = String.Empty; @@ -79,7 +90,7 @@ namespace WixToolset.Core var builtOutputsFile = String.Empty; var wixProjectFile = String.Empty; - var cli = CommandLine.Parse(args, (cmdline, arg) => Enum.TryParse(arg, true, out command), (cmdline, arg) => + this.Parse(args, (cmdline, arg) => Enum.TryParse(arg, true, out command), (cmdline, arg) => { if (cmdline.IsSwitch(arg)) { @@ -103,7 +114,7 @@ namespace WixToolset.Core case "cc": cmdline.GetNextArgumentOrError(ref cabCachePath); return true; - + case "cultures": cmdline.GetNextArgumentOrError(cultures); return true; @@ -187,7 +198,7 @@ namespace WixToolset.Core AppCommon.DisplayToolHeader(); } - if (cli.ShowHelp) + if (this.ShowHelp) { return new HelpCommand(command); } @@ -196,14 +207,11 @@ namespace WixToolset.Core { case Commands.Build: { - LoadStandardBackends(cli.ExtensionManager); - var sourceFiles = GatherSourceFiles(files, outputFolder); var variables = GatherPreprocessorVariables(defines); var bindPathList = GatherBindPaths(bindPaths); - var extensions = cli.ExtensionManager; var type = CalculateOutputType(outputType, outputFile); - return new BuildCommand(extensions, sourceFiles, variables, locFiles, libraryFiles, outputFile, type, cabCachePath, cultures, bindFiles, bindPathList, intermediateFolder, contentsFile, outputsFile, builtOutputsFile, wixProjectFile); + return new BuildCommand(this.ServiceProvider, this.ExtensionManager, sourceFiles, variables, locFiles, libraryFiles, outputFile, type, cabCachePath, cultures, bindFiles, bindPathList, intermediateFolder, contentsFile, outputsFile, builtOutputsFile, wixProjectFile); } case Commands.Compile: @@ -217,18 +225,6 @@ namespace WixToolset.Core return null; } - private static void LoadStandardBackends(ExtensionManager extensionManager) - { - var folder = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath); - - foreach (var backendAssemblyName in new[] { "WixToolset.Core.Burn.dll", "WixToolset.Core.WindowsInstaller.dll" }) - { - var path = Path.Combine(folder, backendAssemblyName); - - extensionManager.Load(path); - } - } - private static OutputType CalculateOutputType(string outputType, string outputFile) { if (String.IsNullOrEmpty(outputType)) @@ -269,6 +265,7 @@ namespace WixToolset.Core return OutputType.Unknown; } +#if UNUSED private static CommandLine Parse(string commandLineString, Func parseArgument) { var arguments = CommandLine.ParseArgumentsToArray(commandLineString).ToArray(); @@ -280,18 +277,17 @@ namespace WixToolset.Core { return CommandLine.Parse(commandLineArguments, null, parseArgument); } +#endif - private static CommandLine Parse(string[] commandLineArguments, Func parseCommand, Func parseArgument) + private ICommandLine Parse(string[] commandLineArguments, Func parseCommand, Func parseArgument) { - var cmdline = new CommandLine(); - - cmdline.FlattenArgumentsWithResponseFilesIntoOriginalArguments(commandLineArguments); + this.FlattenArgumentsWithResponseFilesIntoOriginalArguments(commandLineArguments); - cmdline.QueueArgumentsAndLoadExtensions(cmdline.OriginalArguments); + this.QueueArgumentsAndLoadExtensions(this.OriginalArguments); - cmdline.ProcessRemainingArguments(parseArgument, parseCommand); + this.ProcessRemainingArguments(parseArgument, parseCommand); - return cmdline; + return this; } private static IEnumerable GatherSourceFiles(IEnumerable sourceFiles, string intermediateDirectory) diff --git a/src/WixToolset.Core/CommandLine/CommandLineContext.cs b/src/WixToolset.Core/CommandLine/CommandLineContext.cs new file mode 100644 index 00000000..96c149be --- /dev/null +++ b/src/WixToolset.Core/CommandLine/CommandLineContext.cs @@ -0,0 +1,26 @@ +// 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 +{ + using System; + using WixToolset.Data; + using WixToolset.Extensibility.Services; + + internal class CommandLineContext : ICommandLineContext + { + public CommandLineContext(IServiceProvider serviceProvider) + { + this.ServiceProvider = serviceProvider; + } + + public IServiceProvider ServiceProvider { get; } + + public Messaging Messaging { get; set; } + + public IExtensionManager ExtensionManager { get; set; } + + public string Arguments { get; set; } + + public string[] ParsedArguments { get; set; } + } +} diff --git a/src/WixToolset.Core/CommandLine/CompileCommand.cs b/src/WixToolset.Core/CommandLine/CompileCommand.cs index bbcc8270..855e7c6a 100644 --- a/src/WixToolset.Core/CommandLine/CompileCommand.cs +++ b/src/WixToolset.Core/CommandLine/CompileCommand.cs @@ -2,9 +2,8 @@ namespace WixToolset.Core { - using System; using System.Collections.Generic; - using WixToolset.Data; + using WixToolset.Extensibility.Services; internal class CompileCommand : ICommandLineCommand { diff --git a/src/WixToolset.Core/CommandLine/HelpCommand.cs b/src/WixToolset.Core/CommandLine/HelpCommand.cs index e57ad132..2a2eab24 100644 --- a/src/WixToolset.Core/CommandLine/HelpCommand.cs +++ b/src/WixToolset.Core/CommandLine/HelpCommand.cs @@ -3,6 +3,7 @@ namespace WixToolset.Core { using System; + using WixToolset.Extensibility.Services; internal class HelpCommand : ICommandLineCommand { diff --git a/src/WixToolset.Core/CommandLine/ICommandLineCommand.cs b/src/WixToolset.Core/CommandLine/ICommandLineCommand.cs deleted file mode 100644 index f1471355..00000000 --- a/src/WixToolset.Core/CommandLine/ICommandLineCommand.cs +++ /dev/null @@ -1,9 +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 -{ - public interface ICommandLineCommand - { - int Execute(); - } -} diff --git a/src/WixToolset.Core/CommandLine/VersionCommand.cs b/src/WixToolset.Core/CommandLine/VersionCommand.cs index d13e07a3..12941bdc 100644 --- a/src/WixToolset.Core/CommandLine/VersionCommand.cs +++ b/src/WixToolset.Core/CommandLine/VersionCommand.cs @@ -1,9 +1,10 @@ // 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. -using System; - namespace WixToolset.Core { + using System; + using WixToolset.Extensibility.Services; + internal class VersionCommand : ICommandLineCommand { public int Execute() diff --git a/src/WixToolset.Core/ExtensionManager.cs b/src/WixToolset.Core/ExtensionManager.cs index 7e40571b..b9038c6a 100644 --- a/src/WixToolset.Core/ExtensionManager.cs +++ b/src/WixToolset.Core/ExtensionManager.cs @@ -1,6 +1,6 @@ // 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 +namespace WixToolset.Core { using System; using System.Collections.Generic; @@ -8,12 +8,23 @@ namespace WixToolset using System.Linq; using System.Reflection; using WixToolset.Data; - using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; public class ExtensionManager : IExtensionManager { private List extensionAssemblies = new List(); + /// + /// Adds an assembly. + /// + /// Assembly to add to the extension manager. + /// The assembly added. + public Assembly Add(Assembly assembly) + { + this.extensionAssemblies.Add(assembly); + return assembly; + } + /// /// Loads an assembly from a type description string. /// @@ -57,8 +68,7 @@ namespace WixToolset assembly = ExtensionManager.ExtensionLoadFrom(assemblyName); } - this.extensionAssemblies.Add(assembly); - return assembly; + return this.Add(assembly); } /// diff --git a/src/WixToolset.Core/IncribeContext.cs b/src/WixToolset.Core/IncribeContext.cs index 604ba5d1..15dd3664 100644 --- a/src/WixToolset.Core/IncribeContext.cs +++ b/src/WixToolset.Core/IncribeContext.cs @@ -2,11 +2,19 @@ namespace WixToolset.Core { + using System; using WixToolset.Data; using WixToolset.Extensibility; internal class InscribeContext : IInscribeContext { + public InscribeContext(IServiceProvider serviceProvider) + { + this.ServiceProvider = serviceProvider; + } + + public IServiceProvider ServiceProvider { get; } + public Messaging Messaging { get; } = Messaging.Instance; public string IntermediateFolder { get; set; } diff --git a/src/WixToolset.Core/WixToolsetServiceProvider.cs b/src/WixToolset.Core/WixToolsetServiceProvider.cs new file mode 100644 index 00000000..c073c32b --- /dev/null +++ b/src/WixToolset.Core/WixToolsetServiceProvider.cs @@ -0,0 +1,47 @@ +// 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 +{ + using System; + using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; + + public class WixToolsetServiceProvider : IServiceProvider + { + private ExtensionManager extensionManager; + + public object GetService(Type serviceType) + { + if (serviceType == null) throw new ArgumentNullException(nameof(serviceType)); + + // Transients. + if (serviceType == typeof(IBindContext)) + { + return new BindContext(this); + } + + if (serviceType == typeof(IInscribeContext)) + { + return new InscribeContext(this); + } + + if (serviceType == typeof(ICommandLineContext)) + { + return new CommandLineContext(this); + } + + if (serviceType == typeof(ICommandLine)) + { + return new CommandLine(); + } + + // Singletons. + if (serviceType == typeof(IExtensionManager)) + { + return extensionManager = extensionManager ?? new ExtensionManager(); + } + + throw new ArgumentException($"Unknown service type: {serviceType.Name}", nameof(serviceType)); + } + } +} -- cgit v1.2.3-55-g6feb