Standardize creation of public objects in move towards interfaces
Rob Mensching committed
Dec 26, 2017 at 15:11 UTC
1d6ff8af3c423ee4622185edc986ae5caad6b122
13 files changed
+293
-240
src/WixToolset.BuildTasks/DoIt.cs
-1
@@ -157,7 +157,6 @@ namespace WixToolset.BuildTasks
157
commandLineBuilder.AppendSwitchIfNotNull("-contentsfile ", this.BindContentsFile);
158
commandLineBuilder.AppendSwitchIfNotNull("-outputsfile ", this.BindOutputsFile);
159
commandLineBuilder.AppendSwitchIfNotNull("-builtoutputsfile ", this.BindBuiltOutputsFile);
160
- commandLineBuilder.AppendSwitchIfNotNull("-wixprojectfile ", this.WixProjectFile);
160
161
commandLineBuilder.AppendIfTrue("-bindFiles", this.BindFiles);
162
commandLineBuilder.AppendArrayIfNotNull("-bindPath ", this.CalculateBindPathStrings());
src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
-3
@@ -9,9 +9,6 @@ namespace WixToolset.Core.Burn.Bundles
9
using System.Security.Cryptography;
10
using System.Security.Cryptography.X509Certificates;
11
using System.Text;
12
- using WixToolset.Data;
13
- using WixToolset.Data.Bind;
14
- using WixToolset.Data.Rows;
12
13
internal class ProcessPayloadsCommand
14
{
src/WixToolset.Core/Binder.cs
+7
-7
@@ -125,19 +125,19 @@ namespace WixToolset.Core
125
{
126
var entrySection = output.Sections.First(s => s.Type != SectionType.Fragment);
127
128
- Assembly executingAssembly = Assembly.GetExecutingAssembly();
129
- FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(executingAssembly.Location);
128
+ var executingAssembly = Assembly.GetExecutingAssembly();
129
+ var fileVersion = FileVersionInfo.GetVersionInfo(executingAssembly.Location);
130
131
- var buildInfoRow = new WixBuildInfoTuple();
132
- buildInfoRow.WixVersion = fileVersion.FileVersion;
133
- buildInfoRow.WixOutputFile = outputFile;
131
+ var buildInfoTuple = new WixBuildInfoTuple();
132
+ buildInfoTuple.WixVersion = fileVersion.FileVersion;
133
+ buildInfoTuple.WixOutputFile = outputFile;
134
135
if (!String.IsNullOrEmpty(outputPdbPath))
136
{
137
- buildInfoRow.WixPdbFile = outputPdbPath;
137
+ buildInfoTuple.WixPdbFile = outputPdbPath;
138
}
139
140
- entrySection.Tuples.Add(buildInfoRow);
140
+ entrySection.Tuples.Add(buildInfoTuple);
141
}
142
}
143
}
src/WixToolset.Core/CommandLine/BuildCommand.cs
+40
-49
@@ -13,11 +13,11 @@ namespace WixToolset.Core.CommandLine
13
14
internal class BuildCommand : ICommandLineCommand
15
{
16
- public BuildCommand(IServiceProvider serviceProvider, IMessaging messaging, IExtensionManager extensions, IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables, IEnumerable<string> locFiles, IEnumerable<string> libraryFiles, string outputPath, OutputType outputType, string cabCachePath, IEnumerable<string> cultures, bool bindFiles, IEnumerable<BindPath> bindPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile)
16
+ public BuildCommand(IServiceProvider serviceProvider, IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables, IEnumerable<string> locFiles, IEnumerable<string> libraryFiles, string outputPath, OutputType outputType, string cabCachePath, IEnumerable<string> cultures, bool bindFiles, IEnumerable<BindPath> bindPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile)
17
{
18
this.ServiceProvider = serviceProvider;
19
- this.Messaging = messaging;
20
- this.ExtensionManager = extensions;
19
+ this.Messaging = serviceProvider.GetService<IMessaging>();
20
+ this.ExtensionManager = serviceProvider.GetService<IExtensionManager>();
21
this.LocFiles = locFiles;
22
this.LibraryFiles = libraryFiles;
23
this.PreprocessorVariables = preprocessorVariables;
@@ -76,6 +76,11 @@ namespace WixToolset.Core.CommandLine
76
{
77
var intermediates = this.CompilePhase();
78
79
+ if (this.Messaging.EncounteredError)
80
+ {
81
+ return this.Messaging.LastErrorNumber;
82
+ }
83
+
84
if (!intermediates.Any())
85
{
86
return 1;
@@ -112,35 +117,30 @@ namespace WixToolset.Core.CommandLine
117
118
foreach (var sourceFile in this.SourceFiles)
119
{
115
- var preprocessContext = this.ServiceProvider.GetService<IPreprocessContext>();
116
- preprocessContext.Messaging = this.Messaging;
117
- preprocessContext.Extensions = this.ExtensionManager.Create<IPreprocessorExtension>();
118
- preprocessContext.Platform = Platform.X86; // TODO: set this correctly
119
- preprocessContext.IncludeSearchPaths = this.IncludeSearchPaths?.ToList() ?? new List<string>();
120
- preprocessContext.SourceFile = sourceFile.SourcePath;
121
- preprocessContext.Variables = new Dictionary<string, string>(this.PreprocessorVariables);
120
+ var preprocessor = new Preprocessor(this.ServiceProvider);
121
+ preprocessor.IncludeSearchPaths = this.IncludeSearchPaths;
122
+ preprocessor.Platform = Platform.X86; // TODO: set this correctly
123
+ preprocessor.SourcePath = sourceFile.SourcePath;
124
+ preprocessor.Variables = this.PreprocessorVariables;
125
+ var document = preprocessor.Execute();
126
+
127
+ if (this.Messaging.EncounteredError)
128
+ {
129
+ continue;
130
+ }
131
123
- var preprocessor = new Preprocessor();
124
- var document = preprocessor.Process(preprocessContext);
132
+ var compiler = new Compiler(this.ServiceProvider);
133
+ compiler.OutputPath = sourceFile.OutputPath;
134
+ compiler.Platform = Platform.X86; // TODO: set this correctly
135
+ compiler.SourceDocument = document;
136
+ var intermediate = compiler.Execute();
137
126
- if (!this.Messaging.EncounteredError)
138
+ if (this.Messaging.EncounteredError)
139
{
128
- var compileContext = this.ServiceProvider.GetService<ICompileContext>();
129
- compileContext.Messaging = this.Messaging;
130
- compileContext.CompilationId = Guid.NewGuid().ToString("N");
131
- compileContext.Extensions = this.ExtensionManager.Create<ICompilerExtension>();
132
- compileContext.OutputPath = sourceFile.OutputPath;
133
- compileContext.Platform = Platform.X86; // TODO: set this correctly
134
- compileContext.Source = document;
135
-
136
- var compiler = new Compiler();
137
- var intermediate = compiler.Compile(compileContext);
138
-
139
- if (!this.Messaging.EncounteredError)
140
- {
141
- intermediates.Add(intermediate);
142
- }
140
+ continue;
141
}
142
+
143
+ intermediates.Add(intermediate);
144
}
145
146
return intermediates;
@@ -156,17 +156,12 @@ namespace WixToolset.Core.CommandLine
156
return null;
157
}
158
159
- var context = new LibraryContext();
160
- context.Messaging = this.Messaging;
161
- context.BindFiles = this.BindFiles;
162
- context.BindPaths = this.BindPaths;
163
- context.Extensions = this.ExtensionManager.Create<ILibrarianExtension>();
164
- context.Localizations = localizations;
165
- context.LibraryId = Guid.NewGuid().ToString("N");
166
- context.Intermediates = intermediates;
167
-
168
- var librarian = new Librarian();
169
- return librarian.Combine(context);
159
+ var librarian = new Librarian(this.ServiceProvider);
160
+ librarian.BindFiles = this.BindFiles;
161
+ librarian.BindPaths = this.BindPaths;
162
+ librarian.Intermediates = intermediates;
163
+ librarian.Localizations = localizations;
164
+ return librarian.Execute();
165
}
166
167
private Intermediate LinkPhase(IEnumerable<Intermediate> intermediates)
@@ -180,16 +175,12 @@ namespace WixToolset.Core.CommandLine
175
return null;
176
}
177
183
- var context = this.ServiceProvider.GetService<ILinkContext>();
184
- context.Messaging = this.Messaging;
185
- context.Extensions = this.ExtensionManager.Create<ILinkerExtension>();
186
- context.ExtensionData = this.ExtensionManager.Create<IExtensionData>();
187
- context.ExpectedOutputType = this.OutputType;
188
- context.Intermediates = intermediates.Union(libraries).ToList();
189
- context.TupleDefinitionCreator = creator;
190
-
191
- var linker = new Linker();
192
- return linker.Link(context);
178
+ var linker = new Linker(this.ServiceProvider);
179
+ linker.OutputType = this.OutputType;
180
+ linker.Intermediates = intermediates;
181
+ linker.Libraries = libraries;
182
+ linker.TupleDefinitionCreator = creator;
183
+ return linker.Execute();
184
}
185
186
private void BindPhase(Intermediate output)
src/WixToolset.Core/CommandLine/CommandLineParser.cs
+2
-2
@@ -207,14 +207,14 @@ namespace WixToolset.Core.CommandLine
207
var variables = this.GatherPreprocessorVariables(defines);
208
var bindPathList = this.GatherBindPaths(bindPaths);
209
var type = CalculateOutputType(outputType, outputFile);
210
- return new BuildCommand(this.ServiceProvider, this.Messaging, this.ExtensionManager, sourceFiles, variables, locFiles, libraryFiles, outputFile, type, cabCachePath, cultures, bindFiles, bindPathList, intermediateFolder, contentsFile, outputsFile, builtOutputsFile);
210
+ return new BuildCommand(this.ServiceProvider, sourceFiles, variables, locFiles, libraryFiles, outputFile, type, cabCachePath, cultures, bindFiles, bindPathList, intermediateFolder, contentsFile, outputsFile, builtOutputsFile);
211
}
212
213
case Commands.Compile:
214
{
215
var sourceFiles = GatherSourceFiles(files, outputFolder);
216
var variables = GatherPreprocessorVariables(defines);
217
- return new CompileCommand(this.ServiceProvider, this.Messaging, this.ExtensionManager, sourceFiles, variables);
217
+ return new CompileCommand(this.ServiceProvider, sourceFiles, variables);
218
}
219
}
220
src/WixToolset.Core/CommandLine/CompileCommand.cs
+13
-29
@@ -4,28 +4,21 @@ namespace WixToolset.Core.CommandLine
4
{
5
using System;
6
using System.Collections.Generic;
7
- using System.Linq;
7
using WixToolset.Data;
8
using WixToolset.Extensibility;
9
using WixToolset.Extensibility.Services;
10
11
internal class CompileCommand : ICommandLineCommand
12
{
14
- public CompileCommand(IServiceProvider serviceProvider, IMessaging messaging, IExtensionManager extensions, IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables)
13
+ public CompileCommand(IServiceProvider serviceProvider, IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables)
14
{
15
this.PreprocessorVariables = preprocessorVariables;
16
this.ServiceProvider = serviceProvider;
18
- this.Messaging = messaging;
19
- this.ExtensionManager = extensions;
17
this.SourceFiles = sources;
18
}
19
20
private IServiceProvider ServiceProvider { get; }
21
25
- private IMessaging Messaging { get; }
26
-
27
- private IExtensionManager ExtensionManager { get; }
28
-
22
public IEnumerable<string> IncludeSearchPaths { get; }
23
24
private IEnumerable<SourceFile> SourceFiles { get; }
@@ -36,27 +29,18 @@ namespace WixToolset.Core.CommandLine
29
{
30
foreach (var sourceFile in this.SourceFiles)
31
{
39
- var preprocessContext = this.ServiceProvider.GetService<IPreprocessContext>();
40
- preprocessContext.Messaging = this.Messaging;
41
- preprocessContext.Extensions = this.ExtensionManager.Create<IPreprocessorExtension>();
42
- preprocessContext.Platform = Platform.X86; // TODO: set this correctly
43
- preprocessContext.IncludeSearchPaths = this.IncludeSearchPaths?.ToList() ?? new List<string>();
44
- preprocessContext.SourceFile = sourceFile.SourcePath;
45
- preprocessContext.Variables = new Dictionary<string, string>(this.PreprocessorVariables);
46
-
47
- var preprocessor = new Preprocessor();
48
- var document = preprocessor.Process(preprocessContext);
49
-
50
- var compileContext = this.ServiceProvider.GetService<ICompileContext>();
51
- compileContext.Messaging = this.Messaging;
52
- compileContext.CompilationId = Guid.NewGuid().ToString("N");
53
- compileContext.Extensions = this.ExtensionManager.Create<ICompilerExtension>();
54
- compileContext.OutputPath = sourceFile.OutputPath;
55
- compileContext.Platform = Platform.X86; // TODO: set this correctly
56
- compileContext.Source = document;
57
-
58
- var compiler = new Compiler();
59
- var intermediate = compiler.Compile(compileContext);
32
+ var preprocessor = new Preprocessor(this.ServiceProvider);
33
+ preprocessor.IncludeSearchPaths = this.IncludeSearchPaths;
34
+ preprocessor.Platform = Platform.X86; // TODO: set this correctly
35
+ preprocessor.SourcePath = sourceFile.SourcePath;
36
+ preprocessor.Variables = new Dictionary<string, string>(this.PreprocessorVariables);
37
+ var document = preprocessor.Execute();
38
+
39
+ var compiler = new Compiler(this.ServiceProvider);
40
+ compiler.OutputPath = sourceFile.OutputPath;
41
+ compiler.Platform = Platform.X86; // TODO: set this correctly
42
+ compiler.SourceDocument = document;
43
+ var intermediate = compiler.Execute();
44
45
intermediate.Save(sourceFile.OutputPath);
46
}
src/WixToolset.Core/Compiler.cs
+28
-9
@@ -68,10 +68,25 @@ namespace WixToolset.Core
68
Icon,
69
}
70
71
+ public Compiler(IServiceProvider serviceProvider)
72
+ {
73
+ this.ServiceProvider = serviceProvider;
74
+ }
75
+
76
+ private IServiceProvider ServiceProvider { get; }
77
+
78
private ICompileContext Context { get; set; }
79
80
private CompilerCore Core { get; set; }
81
82
+ public string CompliationId { get; set; }
83
+
84
+ public string OutputPath { get; set; }
85
+
86
+ public Platform Platform { get; set; }
87
+
88
+ public XDocument SourceDocument { get; set; }
89
+
90
/// <summary>
91
/// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements.
92
/// </summary>
@@ -87,17 +102,21 @@ namespace WixToolset.Core
102
/// <summary>
103
/// Compiles the provided Xml document into an intermediate object
104
/// </summary>
90
- /// <param name="context">Context for the compile. The BaseURI property
91
- /// should be properly set to get messages containing source line information.</param>
105
/// <returns>Intermediate object representing compiled source document.</returns>
106
/// <remarks>This method is not thread-safe.</remarks>
94
- public Intermediate Compile(ICompileContext context)
107
+ public Intermediate Execute()
108
{
96
- this.Context = context ?? throw new ArgumentNullException(nameof(context));
109
+ this.Context = this.ServiceProvider.GetService<ICompileContext>();
110
+ this.Context.Messaging = this.ServiceProvider.GetService<IMessaging>();
111
+ this.Context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().Create<ICompilerExtension>();
112
+ this.Context.CompilationId = this.CompliationId;
113
+ this.Context.OutputPath = this.OutputPath;
114
+ this.Context.Platform = this.Platform;
115
+ this.Context.Source = this.SourceDocument;
116
117
var target = new Intermediate();
118
100
- if (String.IsNullOrEmpty(context.CompilationId))
119
+ if (String.IsNullOrEmpty(this.Context.CompilationId))
120
{
121
this.Context.CompilationId = target.Id;
122
}
@@ -115,20 +134,20 @@ namespace WixToolset.Core
134
this.Context.Messaging.Write(ErrorMessages.DuplicateExtensionXmlSchemaNamespace(extension.GetType().ToString(), extension.Namespace.NamespaceName, collidingExtension.GetType().ToString()));
135
}
136
118
- extension.PreCompile(context);
137
+ extension.PreCompile(this.Context);
138
}
139
140
// Try to compile it.
141
try
142
{
124
- var parseHelper = context.ServiceProvider.GetService<IParseHelper>();
143
+ var parseHelper = this.Context.ServiceProvider.GetService<IParseHelper>();
144
145
this.Core = new CompilerCore(target, this.Context.Messaging, parseHelper, extensionsByNamespace);
146
this.Core.ShowPedanticMessages = this.ShowPedanticMessages;
147
this.componentIdPlaceholdersResolver = new WixVariableResolver(this.Context.Messaging);
148
149
// parse the document
131
- var source = context.Source;
150
+ var source = this.Context.Source;
151
var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(source.Root);
152
if ("Wix" == source.Root.Name.LocalName)
153
{
@@ -158,7 +177,7 @@ namespace WixToolset.Core
177
}
178
finally
179
{
161
- foreach (var extension in context.Extensions)
180
+ foreach (var extension in this.Context.Extensions)
181
{
182
extension.PostCompile(target);
183
}
src/WixToolset.Core/ExtensibilityServices/PreprocessHelper.cs
+5
-1
@@ -458,7 +458,11 @@ namespace WixToolset.Core.ExtensibilityServices
458
{
459
this.ExtensionsByPrefix = new Dictionary<string, IPreprocessorExtension>();
460
461
- foreach (var extension in context.Extensions)
461
+ var extensionManager = this.ServiceProvider.GetService<IExtensionManager>();
462
+
463
+ var extensions = extensionManager.Create<IPreprocessorExtension>();
464
+
465
+ foreach (var extension in extensions)
466
{
467
if (null != extension.Prefixes)
468
{
src/WixToolset.Core/Librarian.cs
+25
-7
@@ -9,27 +9,45 @@ namespace WixToolset.Core
9
using WixToolset.Core.Link;
10
using WixToolset.Data;
11
using WixToolset.Extensibility;
12
+ using WixToolset.Extensibility.Services;
13
14
/// <summary>
15
/// Core librarian tool.
16
/// </summary>
17
public sealed class Librarian
18
{
19
+ public Librarian(IServiceProvider serviceProvider)
20
+ {
21
+ this.ServiceProvider = serviceProvider;
22
+ }
23
+
24
+ private IServiceProvider ServiceProvider { get; }
25
+
26
private ILibraryContext Context { get; set; }
27
28
+ public bool BindFiles { get; set; }
29
+
30
+ public IEnumerable<BindPath> BindPaths { get; set; }
31
+
32
+ public IEnumerable<Localization> Localizations { get; set; }
33
+
34
+ public IEnumerable<Intermediate> Intermediates { get; set; }
35
+
36
/// <summary>
37
/// Create a library by combining several intermediates (objects).
38
/// </summary>
39
/// <param name="sections">The sections to combine into a library.</param>
40
/// <returns>Returns the new library.</returns>
25
- public Intermediate Combine(ILibraryContext context)
41
+ public Intermediate Execute()
42
{
27
- this.Context = context ?? throw new ArgumentNullException(nameof(context));
28
-
29
- if (String.IsNullOrEmpty(this.Context.LibraryId))
30
- {
31
- this.Context.LibraryId = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).TrimEnd('=').Replace('+', '.').Replace('/', '_');
32
- }
43
+ this.Context = new LibraryContext(this.ServiceProvider);
44
+ this.Context.Messaging = this.ServiceProvider.GetService<IMessaging>();
45
+ this.Context.BindFiles = this.BindFiles;
46
+ this.Context.BindPaths = this.BindPaths;
47
+ this.Context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().Create<ILibrarianExtension>();
48
+ this.Context.Localizations = this.Localizations;
49
+ this.Context.LibraryId = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).TrimEnd('=').Replace('+', '.').Replace('/', '_');
50
+ this.Context.Intermediates = this.Intermediates;
51
52
foreach (var extension in this.Context.Extensions)
53
{
src/WixToolset.Core/LibraryContext.cs
+5
@@ -10,6 +10,11 @@ namespace WixToolset.Core
10
11
public class LibraryContext : ILibraryContext
12
{
13
+ public LibraryContext(IServiceProvider serviceProvider)
14
+ {
15
+ this.ServiceProvider = serviceProvider;
16
+ }
17
+
18
public IServiceProvider ServiceProvider { get; }
19
20
public IMessaging Messaging { get; set; }
src/WixToolset.Core/Linker.cs
+26
-10
@@ -12,6 +12,7 @@ namespace WixToolset.Core
12
using WixToolset.Data;
13
using WixToolset.Data.Tuples;
14
using WixToolset.Extensibility;
15
+ using WixToolset.Extensibility.Services;
16
using WixToolset.Link;
17
18
/// <summary>
@@ -27,14 +28,17 @@ namespace WixToolset.Core
28
/// <summary>
29
/// Creates a linker.
30
/// </summary>
30
- public Linker()
31
+ public Linker(IServiceProvider serviceProvider)
32
{
33
+ this.ServiceProvider = serviceProvider;
34
this.sectionIdOnRows = true; // TODO: what is the correct value for this?
35
36
//this.extensionData = new List<IExtensionData>();
37
//this.inspectorExtensions = new List<InspectorExtension>();
38
}
39
40
+ private IServiceProvider ServiceProvider { get; }
41
+
42
private ILinkContext Context { get; set; }
43
44
/// <summary>
@@ -49,11 +53,13 @@ namespace WixToolset.Core
53
/// <value>The option to show pedantic messages.</value>
54
public bool ShowPedanticMessages { get; set; }
55
52
- /// <summary>
53
- /// Gets or sets the Wix variable resolver.
54
- /// </summary>
55
- /// <value>The Wix variable resolver.</value>
56
- //internal IBindVariableResolver WixVariableResolver { get; set; }
56
+ public OutputType OutputType { get; set; }
57
+
58
+ public IEnumerable<Intermediate> Intermediates { get; set; }
59
+
60
+ public IEnumerable<Intermediate> Libraries { get; set; }
61
+
62
+ public ITupleDefinitionCreator TupleDefinitionCreator { get; set; }
63
64
/// <summary>
65
/// Links a collection of sections into an output.
@@ -61,16 +67,26 @@ namespace WixToolset.Core
67
/// <param name="inputs">The collection of sections to link together.</param>
68
/// <param name="expectedOutputType">Expected output type, based on output file extension provided to the linker.</param>
69
/// <returns>Output object from the linking.</returns>
64
- public Intermediate Link(ILinkContext context)
70
+ public Intermediate Execute()
71
{
66
- this.Context = context ?? throw new ArgumentNullException(nameof(context));
72
+ var extensionManager = this.ServiceProvider.GetService<IExtensionManager>();
73
+
74
+ var creator = this.TupleDefinitionCreator ?? this.ServiceProvider.GetService<ITupleDefinitionCreator>();
75
+
76
+ this.Context = this.ServiceProvider.GetService<ILinkContext>();
77
+ this.Context.Messaging = this.ServiceProvider.GetService<IMessaging>();
78
+ this.Context.Extensions = extensionManager.Create<ILinkerExtension>();
79
+ this.Context.ExtensionData = extensionManager.Create<IExtensionData>();
80
+ this.Context.ExpectedOutputType = this.OutputType;
81
+ this.Context.Intermediates = this.Intermediates.Union(this.Libraries).ToList();
82
+ this.Context.TupleDefinitionCreator = creator;
83
84
var sections = this.Context.Intermediates.SelectMany(i => i.Sections).ToList();
85
86
// Add sections from the extensions with data.
71
- foreach (var data in context.ExtensionData)
87
+ foreach (var data in this.Context.ExtensionData)
88
{
73
- var library = data.GetLibrary(context.TupleDefinitionCreator);
89
+ var library = data.GetLibrary(this.Context.TupleDefinitionCreator);
90
91
if (library != null)
92
{
src/WixToolset.Core/Preprocessor.cs
+91
-45
@@ -14,6 +14,7 @@ namespace WixToolset.Core
14
using WixToolset.Extensibility;
15
using WixToolset.Core.Preprocess;
16
using WixToolset.Extensibility.Services;
17
+ using System.Linq;
18
19
/// <summary>
20
/// Preprocessor object
@@ -35,6 +36,21 @@ namespace WixToolset.Core
36
XmlResolver = null,
37
};
38
39
+ public Preprocessor(IServiceProvider serviceProvider)
40
+ {
41
+ this.ServiceProvider = serviceProvider;
42
+ }
43
+
44
+ public IEnumerable<string> IncludeSearchPaths { get; set; }
45
+
46
+ public Platform Platform { get; set; }
47
+
48
+ public string SourcePath { get; set; }
49
+
50
+ public IDictionary<string, string> Variables { get; set; }
51
+
52
+ private IServiceProvider ServiceProvider { get; }
53
+
54
private IPreprocessContext Context { get; set; }
55
56
private Stack<string> CurrentFileStack { get; } = new Stack<string>();
@@ -87,14 +103,19 @@ namespace WixToolset.Core
103
/// </summary>
104
/// <param name="context">The preprocessing context.</param>
105
/// <returns>XDocument with the postprocessed data.</returns>
90
- public XDocument Process(IPreprocessContext context)
106
+ public XDocument Execute()
107
{
92
- this.Context = context ?? throw new ArgumentNullException(nameof(context));
108
+ this.Context = this.CreateContext();
109
+
110
+ this.PreProcess();
111
94
- using (XmlReader reader = XmlReader.Create(context.SourceFile, DocumentXmlReaderSettings))
112
+ XDocument document;
113
+ using (XmlReader reader = XmlReader.Create(this.Context.SourceFile, DocumentXmlReaderSettings))
114
{
96
- return Process(context, reader);
115
+ document = this.Process(reader);
116
}
117
+
118
+ return PostProcess(document);
119
}
120
121
/// <summary>
@@ -103,46 +124,32 @@ namespace WixToolset.Core
124
/// <param name="context">The preprocessing context.</param>
125
/// <param name="reader">XmlReader to processing the context.</param>
126
/// <returns>XDocument with the postprocessed data.</returns>
106
- public XDocument Process(IPreprocessContext context, XmlReader reader)
127
+ public XDocument Execute(XmlReader reader)
128
{
108
- if (this.Context == null)
109
- {
110
- this.Context = context ?? throw new ArgumentNullException(nameof(context));
111
- }
112
- else if (this.Context != context)
113
- {
114
- throw new ArgumentException(nameof(context));
115
- }
116
-
117
- if (String.IsNullOrEmpty(this.Context.SourceFile) && !String.IsNullOrEmpty(reader.BaseURI))
129
+ if (String.IsNullOrEmpty(this.SourcePath) && !String.IsNullOrEmpty(reader.BaseURI))
130
{
131
var uri = new Uri(reader.BaseURI);
120
- this.Context.SourceFile = uri.AbsolutePath;
132
+ this.SourcePath = uri.AbsolutePath;
133
}
134
123
- this.Context.CurrentSourceLineNumber = new SourceLineNumber(this.Context.SourceFile);
135
+ this.Context = this.CreateContext();
136
125
- this.Helper = this.Context.ServiceProvider.GetService<IPreprocessHelper>();
137
+ this.PreProcess();
138
127
- foreach (var extension in this.Context.Extensions)
128
- {
129
- if (null != extension.Prefixes)
130
- {
131
- foreach (string prefix in extension.Prefixes)
132
- {
133
- if (!this.ExtensionsByPrefix.TryGetValue(prefix, out var collidingExtension))
134
- {
135
- this.ExtensionsByPrefix.Add(prefix, extension);
136
- }
137
- else
138
- {
139
- this.Context.Messaging.Write(ErrorMessages.DuplicateExtensionPreprocessorType(extension.GetType().ToString(), prefix, collidingExtension.GetType().ToString()));
140
- }
141
- }
142
- }
139
+ var document = this.Process(reader);
140
144
- extension.PrePreprocess(context);
145
- }
141
+ return PostProcess(document);
142
+ }
143
+
144
+ /// <summary>
145
+ /// Preprocesses a file.
146
+ /// </summary>
147
+ /// <param name="context">The preprocessing context.</param>
148
+ /// <param name="reader">XmlReader to processing the context.</param>
149
+ /// <returns>XDocument with the postprocessed data.</returns>
150
+ private XDocument Process(XmlReader reader)
151
+ {
152
+ this.Helper = this.ServiceProvider.GetService<IPreprocessHelper>();
153
154
this.CurrentFileStack.Clear();
155
this.CurrentFileStack.Push(this.Helper.GetVariableValue(this.Context, "sys", "SOURCEFILEDIR"));
@@ -161,14 +168,6 @@ namespace WixToolset.Core
168
this.UpdateCurrentLineNumber(reader, 0);
169
throw new WixException(ErrorMessages.InvalidXml(this.Context.CurrentSourceLineNumber, "source", e.Message));
170
}
164
- finally
165
- {
166
- // Finalize the preprocessing.
167
- foreach (var extension in this.Context.Extensions)
168
- {
169
- extension.PostPreprocess(output);
170
- }
171
- }
171
172
return this.Context.Messaging.EncounteredError ? null : output;
173
}
@@ -1404,7 +1403,7 @@ namespace WixToolset.Core
1403
{
1404
// build a string to test the directory containing the source file first
1405
var currentFolder = this.CurrentFileStack.Peek();
1407
- var includeTestPath = Path.Combine(Path.GetDirectoryName(currentFolder) , includePath);
1406
+ var includeTestPath = Path.Combine(Path.GetDirectoryName(currentFolder), includePath);
1407
1408
// test the source file directory
1409
if (File.Exists(includeTestPath))
@@ -1428,5 +1427,52 @@ namespace WixToolset.Core
1427
1428
return finalIncludePath;
1429
}
1430
+
1431
+ private IPreprocessContext CreateContext()
1432
+ {
1433
+ var context = this.ServiceProvider.GetService<IPreprocessContext>();
1434
+ context.Messaging = this.ServiceProvider.GetService<IMessaging>();
1435
+ context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().Create<IPreprocessorExtension>();
1436
+ context.CurrentSourceLineNumber = new SourceLineNumber(this.SourcePath);
1437
+ context.Platform = this.Platform;
1438
+ context.IncludeSearchPaths = this.IncludeSearchPaths?.ToList() ?? new List<string>();
1439
+ context.SourceFile = this.SourcePath;
1440
+ context.Variables = new Dictionary<string, string>(this.Variables);
1441
+
1442
+ return context;
1443
+ }
1444
+
1445
+ private void PreProcess()
1446
+ {
1447
+ foreach (var extension in this.Context.Extensions)
1448
+ {
1449
+ if (extension.Prefixes != null)
1450
+ {
1451
+ foreach (var prefix in extension.Prefixes)
1452
+ {
1453
+ if (!this.ExtensionsByPrefix.TryGetValue(prefix, out var collidingExtension))
1454
+ {
1455
+ this.ExtensionsByPrefix.Add(prefix, extension);
1456
+ }
1457
+ else
1458
+ {
1459
+ this.Context.Messaging.Write(ErrorMessages.DuplicateExtensionPreprocessorType(extension.GetType().ToString(), prefix, collidingExtension.GetType().ToString()));
1460
+ }
1461
+ }
1462
+ }
1463
+
1464
+ extension.PrePreprocess(this.Context);
1465
+ }
1466
+ }
1467
+
1468
+ private XDocument PostProcess(XDocument document)
1469
+ {
1470
+ foreach (var extension in this.Context.Extensions)
1471
+ {
1472
+ extension.PostPreprocess(document);
1473
+ }
1474
+
1475
+ return document;
1476
+ }
1477
}
1478
}
src/WixToolset.Core/WixToolsetServiceProvider.cs
+51
-77
@@ -3,6 +3,7 @@
3
namespace WixToolset.Core
4
{
5
using System;
6
+ using System.Collections.Generic;
7
using WixToolset.Core.CommandLine;
8
using WixToolset.Core.ExtensibilityServices;
9
using WixToolset.Data;
@@ -11,95 +12,68 @@ namespace WixToolset.Core
12
13
public class WixToolsetServiceProvider : IServiceProvider
14
{
14
- private ExtensionManager extensionManager;
15
- private Messaging messaging;
16
- private ParseHelper parseHelper;
17
- private PreprocessHelper preprocessHelper;
18
- private TupleDefinitionCreator tupleDefinitionCreator;
19
- private WindowsInstallerBackendHelper windowsInstallerBackendHelper;
20
-
21
- public object GetService(Type serviceType)
15
+ public WixToolsetServiceProvider()
16
{
23
- if (serviceType == null) throw new ArgumentNullException(nameof(serviceType));
24
-
25
- // Transients.
26
- if (serviceType == typeof(IPreprocessContext))
27
- {
28
- return new PreprocessContext(this);
29
- }
30
-
31
- if (serviceType == typeof(ICompileContext))
32
- {
33
- return new CompileContext(this);
34
- }
35
-
36
- if (serviceType == typeof(ILinkContext))
37
- {
38
- return new LinkContext(this);
39
- }
40
-
41
- if (serviceType == typeof(IBindContext))
42
- {
43
- return new BindContext(this);
44
- }
45
-
46
- if (serviceType == typeof(ILayoutContext))
47
- {
48
- return new LayoutContext(this);
49
- }
50
-
51
- if (serviceType == typeof(IResolveContext))
52
- {
53
- return new ResolveContext(this);
54
- }
55
-
56
- if (serviceType == typeof(IInscribeContext))
57
- {
58
- return new InscribeContext(this);
59
- }
60
-
61
- if (serviceType == typeof(ICommandLineContext))
17
+ this.CreationFunctions = new Dictionary<Type, Func<IServiceProvider, Dictionary<Type, object>, object>>
18
{
63
- return new CommandLineContext(this);
64
- }
19
+ // Singletons.
20
+ { typeof(IExtensionManager), (provider, singletons) => AddSingleton(singletons, typeof(IExtensionManager), new ExtensionManager()) },
21
+ { typeof(IMessaging), (provider, singletons) => AddSingleton(singletons, typeof(IMessaging), new Messaging()) },
22
+ { typeof(ITupleDefinitionCreator), (provider, singletons) => AddSingleton(singletons, typeof(ITupleDefinitionCreator), new TupleDefinitionCreator(provider)) },
23
+ { typeof(IParseHelper), (provider, singletons) => AddSingleton(singletons, typeof(IParseHelper), new ParseHelper(provider)) },
24
+ { typeof(IPreprocessHelper), (provider, singletons) => AddSingleton(singletons, typeof(IPreprocessHelper), new PreprocessHelper(provider)) },
25
+ { typeof(IWindowsInstallerBackendHelper), (provider, singletons) => AddSingleton(singletons, typeof(IWindowsInstallerBackendHelper), new WindowsInstallerBackendHelper(provider)) },
26
66
- if (serviceType == typeof(ICommandLine))
67
- {
68
- return new CommandLineParser();
69
- }
27
+ // Transients.
28
+ { typeof(ICommandLineContext), (provider, singletons) => new CommandLineContext(provider) },
29
+ { typeof(ICommandLine), (provider, singletons) => new CommandLineParser() },
30
+ { typeof(IPreprocessContext), (provider, singletons) => new PreprocessContext(provider) },
31
+ { typeof(ICompileContext), (provider, singletons) => new CompileContext(provider) },
32
+ { typeof(ILinkContext), (provider, singletons) => new LinkContext(provider) },
33
+ { typeof(IResolveContext), (provider, singletons) => new ResolveContext(provider) },
34
+ { typeof(IBindContext), (provider, singletons) => new BindContext(provider) },
35
+ { typeof(ILayoutContext), (provider, singletons) => new LayoutContext(provider) },
36
+ { typeof(IInscribeContext), (provider, singletons) => new InscribeContext(provider) },
37
+ };
38
+
39
+ this.Singletons = new Dictionary<Type, object>();
40
+ }
41
71
- // Singletons.
72
- if (serviceType == typeof(IExtensionManager))
73
- {
74
- return this.extensionManager = this.extensionManager ?? new ExtensionManager();
75
- }
42
+ private Dictionary<Type, Func<IServiceProvider, Dictionary<Type, object>, object>> CreationFunctions { get; }
43
77
- if (serviceType == typeof(IMessaging))
78
- {
79
- return this.messaging = this.messaging ?? new Messaging();
80
- }
44
+ private Dictionary<Type, object> Singletons { get; }
45
82
- if (serviceType == typeof(ITupleDefinitionCreator))
83
- {
84
- return this.tupleDefinitionCreator = this.tupleDefinitionCreator ?? new TupleDefinitionCreator(this);
85
- }
46
+ public object GetService(Type serviceType)
47
+ {
48
+ if (serviceType == null) throw new ArgumentNullException(nameof(serviceType));
49
87
- if (serviceType == typeof(IParseHelper))
50
+ if (!this.Singletons.TryGetValue(serviceType, out var service))
51
{
89
- return this.parseHelper = this.parseHelper ?? new ParseHelper(this);
52
+ if (this.CreationFunctions.TryGetValue(serviceType, out var creationFunction))
53
+ {
54
+ service = creationFunction(this, this.Singletons);
55
+
56
+#if DEBUG
57
+ if (!serviceType.IsAssignableFrom(service?.GetType()))
58
+ {
59
+ throw new InvalidOperationException($"Creation function for service type: {serviceType.Name} created incompatible service with type: {service?.GetType()}");
60
+ }
61
+#endif
62
+ }
63
}
64
92
- if (serviceType == typeof(IPreprocessHelper))
93
- {
94
- return this.preprocessHelper = this.preprocessHelper ?? new PreprocessHelper(this);
95
- }
65
+ return service ?? throw new ArgumentException($"Unknown service type: {serviceType.Name}", nameof(serviceType));
66
+ }
67
97
- if (serviceType == typeof(IWindowsInstallerBackendHelper))
98
- {
99
- return this.windowsInstallerBackendHelper = this.windowsInstallerBackendHelper ?? new WindowsInstallerBackendHelper(this);
100
- }
68
+ public void AddService(Type serviceType, Func<IServiceProvider, Dictionary<Type, object>, object> creationFunction)
69
+ {
70
+ this.CreationFunctions[serviceType] = creationFunction;
71
+ }
72
102
- throw new ArgumentException($"Unknown service type: {serviceType.Name}", nameof(serviceType));
73
+ private static object AddSingleton(Dictionary<Type, object> singletons, Type type, object service)
74
+ {
75
+ singletons.Add(type, service);
76
+ return service;
77
}
78
}
79
}