diff options
Diffstat (limited to 'src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs')
| -rw-r--r-- | src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs b/src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs new file mode 100644 index 00000000..28430bb8 --- /dev/null +++ b/src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | // 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. | ||
| 2 | |||
| 3 | namespace WixToolset.BootstrapperCore | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Configuration; | ||
| 7 | using System.Reflection; | ||
| 8 | using System.Runtime.InteropServices; | ||
| 9 | |||
| 10 | /// <summary> | ||
| 11 | /// Entry point for the MBA host to create and return the IBootstrapperApplication implementation to the engine. | ||
| 12 | /// </summary> | ||
| 13 | [ClassInterface(ClassInterfaceType.None)] | ||
| 14 | public sealed class BootstrapperApplicationFactory : MarshalByRefObject, IBootstrapperApplicationFactory | ||
| 15 | { | ||
| 16 | /// <summary> | ||
| 17 | /// Creates a new instance of the <see cref="BootstrapperApplicationFactory"/> class. | ||
| 18 | /// </summary> | ||
| 19 | public BootstrapperApplicationFactory() | ||
| 20 | { | ||
| 21 | } | ||
| 22 | |||
| 23 | /// <summary> | ||
| 24 | /// Loads the bootstrapper application assembly and creates an instance of the IBootstrapperApplication. | ||
| 25 | /// </summary> | ||
| 26 | /// <param name="pEngine">IBootstrapperEngine provided for the bootstrapper application.</param> | ||
| 27 | /// <param name="command">Command line for the bootstrapper application.</param> | ||
| 28 | /// <returns>Bootstrapper application via <see cref="IBootstrapperApplication"/> interface.</returns> | ||
| 29 | /// <exception cref="MissingAttributeException">The bootstrapper application assembly | ||
| 30 | /// does not define the <see cref="BootstrapperApplicationFactoryAttribute"/>.</exception> | ||
| 31 | public IBootstrapperApplication Create(IBootstrapperEngine pEngine, ref Command command) | ||
| 32 | { | ||
| 33 | // Get the wix.boostrapper section group to get the name of the bootstrapper application assembly to host. | ||
| 34 | var section = ConfigurationManager.GetSection("wix.bootstrapper/host") as HostSection; | ||
| 35 | if (null == section) | ||
| 36 | { | ||
| 37 | throw new MissingAttributeException(); // TODO: throw a more specific exception than this. | ||
| 38 | } | ||
| 39 | |||
| 40 | // Load the BA's IBootstrapperApplicationFactory. | ||
| 41 | var baFactoryType = BootstrapperApplicationFactory.GetBAFactoryTypeFromAssembly(section.AssemblyName); | ||
| 42 | var baFactory = (IBootstrapperApplicationFactory)Activator.CreateInstance(baFactoryType); | ||
| 43 | if (null == baFactory) | ||
| 44 | { | ||
| 45 | throw new InvalidBootstrapperApplicationFactoryException(); | ||
| 46 | } | ||
| 47 | |||
| 48 | var ba = baFactory.Create(pEngine, ref command); | ||
| 49 | return ba; | ||
| 50 | } | ||
| 51 | |||
| 52 | /// <summary> | ||
| 53 | /// Locates the <see cref="BootstrapperApplicationFactoryAttribute"/> and returns the specified type. | ||
| 54 | /// </summary> | ||
| 55 | /// <param name="assemblyName">The assembly that defines the IBootstrapperApplicationFactory implementation.</param> | ||
| 56 | /// <returns>The bootstrapper application factory <see cref="Type"/>.</returns> | ||
| 57 | private static Type GetBAFactoryTypeFromAssembly(string assemblyName) | ||
| 58 | { | ||
| 59 | Type baFactoryType = null; | ||
| 60 | |||
| 61 | // Load the requested assembly. | ||
| 62 | Assembly asm = AppDomain.CurrentDomain.Load(assemblyName); | ||
| 63 | |||
| 64 | // If an assembly was loaded and is not the current assembly, check for the required attribute. | ||
| 65 | // This is done to avoid using the BootstrapperApplicationFactoryAttribute which we use at build time | ||
| 66 | // to specify the BootstrapperApplicationFactory assembly in the manifest. | ||
| 67 | if (!Assembly.GetExecutingAssembly().Equals(asm)) | ||
| 68 | { | ||
| 69 | // There must be one and only one BootstrapperApplicationFactoryAttribute. | ||
| 70 | // The attribute prevents multiple declarations already. | ||
| 71 | var attrs = (BootstrapperApplicationFactoryAttribute[])asm.GetCustomAttributes(typeof(BootstrapperApplicationFactoryAttribute), false); | ||
| 72 | if (null != attrs) | ||
| 73 | { | ||
| 74 | baFactoryType = attrs[0].BootstrapperApplicationFactoryType; | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | if (null == baFactoryType) | ||
| 79 | { | ||
| 80 | throw new MissingAttributeException(); | ||
| 81 | } | ||
| 82 | |||
| 83 | return baFactoryType; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | } | ||
