From 4e6244d8a84873c93c7cf50217cce265281e3fe2 Mon Sep 17 00:00:00 2001 From: Andrew Stanton-Nurse Date: Tue, 8 Dec 2015 11:30:25 -0800 Subject: [PATCH] add ProjectAssemblyLoadContext allows the loading of assemblies in the context of an existing project --- Microsoft.DotNet.Cli.sln | 78 +++++++++++++++ .../LoaderProjectContextExtensions.cs | 9 +- ...Microsoft.DotNet.ProjectModel.Loader.xproj | 19 ++++ .../ProjectContextLoadContext.cs | 41 -------- .../ProjectLoadContext.cs | 95 +++++++++++++++++++ .../project.json | 1 + .../WorkspaceProjectContextExtensions.cs | 1 - .../Constants.cs | 13 +++ .../ProjectContext.cs | 12 ++- test/LoadContextTest/LoadContextTest.xproj | 20 ++++ test/LoadContextTest/Program.cs | 51 ++++++++++ .../Properties/AssemblyInfo.cs | 23 +++++ test/LoadContextTest/project.json | 26 +++++ test/TestLibrary/Helper.cs | 5 + test/TestLibrary/project.json | 3 +- 15 files changed, 347 insertions(+), 50 deletions(-) create mode 100644 src/Microsoft.DotNet.ProjectModel.Loader/Microsoft.DotNet.ProjectModel.Loader.xproj delete mode 100644 src/Microsoft.DotNet.ProjectModel.Loader/ProjectContextLoadContext.cs create mode 100644 src/Microsoft.DotNet.ProjectModel.Loader/ProjectLoadContext.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Constants.cs create mode 100644 test/LoadContextTest/LoadContextTest.xproj create mode 100644 test/LoadContextTest/Program.cs create mode 100644 test/LoadContextTest/Properties/AssemblyInfo.cs create mode 100644 test/LoadContextTest/project.json diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln index 1924437b4..8490082a5 100644 --- a/Microsoft.DotNet.Cli.sln +++ b/Microsoft.DotNet.Cli.sln @@ -47,6 +47,16 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Extensions.Testin EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Test", "src\Microsoft.DotNet.Tools.Test\Microsoft.DotNet.Tools.Test.xproj", "{F003F228-2AE2-4E9D-877B-93EB773B5061}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectModel.Loader", "src\Microsoft.DotNet.ProjectModel.Loader\Microsoft.DotNet.ProjectModel.Loader.xproj", "{C7AF0290-EF0D-44DC-9EDC-600803B664F8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestApp", "test\TestApp\TestApp.xproj", "{58808BBC-371E-47D6-A3D0-4902145EDA4E}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestLibrary", "test\TestLibrary\TestLibrary.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D2DD58}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "LoadContextTest", "test\LoadContextTest\LoadContextTest.xproj", "{7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -347,6 +357,70 @@ Global {F003F228-2AE2-4E9D-877B-93EB773B5061}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU {F003F228-2AE2-4E9D-877B-93EB773B5061}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU {F003F228-2AE2-4E9D-877B-93EB773B5061}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.Debug|x64.ActiveCfg = Debug|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.Debug|x64.Build.0 = Debug|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.Release|Any CPU.Build.0 = Release|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.Release|x64.ActiveCfg = Release|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.Release|x64.Build.0 = Release|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {C7AF0290-EF0D-44DC-9EDC-600803B664F8}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|x64.ActiveCfg = Debug|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|x64.Build.0 = Debug|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.Build.0 = Release|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|x64.ActiveCfg = Release|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|x64.Build.0 = Release|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|Any CPU.Build.0 = Debug|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|x64.ActiveCfg = Debug|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|x64.Build.0 = Debug|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|Any CPU.ActiveCfg = Release|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|Any CPU.Build.0 = Release|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|x64.ActiveCfg = Release|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|x64.Build.0 = Release|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.Debug|x64.ActiveCfg = Debug|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.Debug|x64.Build.0 = Debug|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.Release|Any CPU.Build.0 = Release|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.Release|x64.ActiveCfg = Release|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.Release|x64.Build.0 = Release|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF}.RelWithDebInfo|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -370,5 +444,9 @@ Global {DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {DCDFE282-03DE-4DBC-B90C-CC3CE3EC8162} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {F003F228-2AE2-4E9D-877B-93EB773B5061} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} + {C7AF0290-EF0D-44DC-9EDC-600803B664F8} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} + {58808BBC-371E-47D6-A3D0-4902145EDA4E} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} + {947DD232-8D9B-4B78-9C6A-94F807D2DD58} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} + {7A75ACC4-3C2F-44E1-B492-0EC08704E9FF} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} EndGlobalSection EndGlobal diff --git a/src/Microsoft.DotNet.ProjectModel.Loader/LoaderProjectContextExtensions.cs b/src/Microsoft.DotNet.ProjectModel.Loader/LoaderProjectContextExtensions.cs index 5ec178400..4deea175f 100644 --- a/src/Microsoft.DotNet.ProjectModel.Loader/LoaderProjectContextExtensions.cs +++ b/src/Microsoft.DotNet.ProjectModel.Loader/LoaderProjectContextExtensions.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; +using System.IO; using System.Reflection; using System.Runtime.Loader; -using Microsoft.Extensions.ProjectModel; namespace Microsoft.DotNet.ProjectModel.Loader { public static class LoaderProjectContextExtensions { - public static AssemblyLoadContext Create(this ProjectContext context, string configuration = "Debug") + public static AssemblyLoadContext CreateLoadContext(this ProjectContext context, string configuration = "Debug") { var exporter = context.CreateExporter(configuration); var assemblies = new Dictionary(); @@ -32,7 +32,10 @@ namespace Microsoft.DotNet.ProjectModel.Loader } } - return new ProjectContextLoadContext(assemblies, dllImports); + return new ProjectLoadContext( + assemblies, + dllImports, + new[] { context.GetOutputDirectoryPath(configuration) }); } } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel.Loader/Microsoft.DotNet.ProjectModel.Loader.xproj b/src/Microsoft.DotNet.ProjectModel.Loader/Microsoft.DotNet.ProjectModel.Loader.xproj new file mode 100644 index 000000000..37f236678 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel.Loader/Microsoft.DotNet.ProjectModel.Loader.xproj @@ -0,0 +1,19 @@ + + + + 14.0.24720 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + c7af0290-ef0d-44dc-9edc-600803b664f8 + Microsoft.DotNet.ProjectModel.Loader + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel.Loader/ProjectContextLoadContext.cs b/src/Microsoft.DotNet.ProjectModel.Loader/ProjectContextLoadContext.cs deleted file mode 100644 index 24e9914ab..000000000 --- a/src/Microsoft.DotNet.ProjectModel.Loader/ProjectContextLoadContext.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.Loader; - -namespace Microsoft.DotNet.ProjectModel.Loader -{ - public class ProjectContextLoadContext : AssemblyLoadContext - { - private readonly Dictionary _assemblies; - private readonly Dictionary _dllImports; - public ProjectContextLoadContext(Dictionary assemblies, - Dictionary dllImports) - { - _assemblies = assemblies; - _dllImports = dllImports; - } - - protected override Assembly Load(AssemblyName assemblyName) - { - string path; - if (_assemblies.TryGetValue(assemblyName, out path)) - { - return LoadFromAssemblyPath(path); - } - - return null; - } - - protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) - { - string path; - if (_dllImports.TryGetValue(unmanagedDllName, out path)) - { - return LoadUnmanagedDllFromPath(path); - } - - return base.LoadUnmanagedDll(unmanagedDllName); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel.Loader/ProjectLoadContext.cs b/src/Microsoft.DotNet.ProjectModel.Loader/ProjectLoadContext.cs new file mode 100644 index 000000000..fbf814fd6 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel.Loader/ProjectLoadContext.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Loader; + +namespace Microsoft.DotNet.ProjectModel.Loader +{ + /// + /// An designed to allow loading from a Project. + /// + public class ProjectLoadContext : AssemblyLoadContext + { + private readonly IDictionary _assemblyPaths; + private readonly IDictionary _nativeLibraries; + private readonly IEnumerable _searchPaths; + + private static readonly string[] NativeLibraryExtensions; + private static readonly string[] ManagedAssemblyExtensions = new[] + { + ".dll", + ".ni.dll", + ".exe", + ".ni.exe" + }; + + + static ProjectLoadContext() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + NativeLibraryExtensions = new[] { ".dll" }; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + NativeLibraryExtensions = new[] { ".dylib" }; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + NativeLibraryExtensions = new[] { ".so" }; + } + NativeLibraryExtensions = new string[0]; + } + + public ProjectLoadContext(IDictionary assemblyPaths, + IDictionary nativeLibraries, + IEnumerable searchPaths) + { + _assemblyPaths = assemblyPaths; + _nativeLibraries = nativeLibraries; + _searchPaths = searchPaths; + } + + protected override Assembly Load(AssemblyName assemblyName) + { + string path; + if (_assemblyPaths.TryGetValue(assemblyName, out path) || SearchForLibrary(ManagedAssemblyExtensions, assemblyName.Name, out path)) + { + return LoadFromAssemblyPath(path); + } + + return null; + } + + protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) + { + string path; + if (_nativeLibraries.TryGetValue(unmanagedDllName, out path) || SearchForLibrary(NativeLibraryExtensions, unmanagedDllName, out path)) + { + return LoadUnmanagedDllFromPath(path); + } + + return base.LoadUnmanagedDll(unmanagedDllName); + } + + private bool SearchForLibrary(string[] extensions, string name, out string path) + { + foreach(var searchPath in _searchPaths) + { + foreach(var extension in extensions) + { + var candidate = Path.Combine(searchPath, name + extension); + if(File.Exists(candidate)) + { + path = candidate; + return true; + } + } + } + path = null; + return false; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel.Loader/project.json b/src/Microsoft.DotNet.ProjectModel.Loader/project.json index b8227c95f..e451aed94 100644 --- a/src/Microsoft.DotNet.ProjectModel.Loader/project.json +++ b/src/Microsoft.DotNet.ProjectModel.Loader/project.json @@ -1,6 +1,7 @@ { "dependencies": { "Microsoft.DotNet.ProjectModel": "1.0.0-*", + "System.AppContext": "4.0.1-beta-23504", "System.Runtime.Loader": "4.0.0-beta-23504" }, "frameworks": { diff --git a/src/Microsoft.DotNet.ProjectModel.Workspaces/WorkspaceProjectContextExtensions.cs b/src/Microsoft.DotNet.ProjectModel.Workspaces/WorkspaceProjectContextExtensions.cs index 6bba8b877..615f4fac2 100644 --- a/src/Microsoft.DotNet.ProjectModel.Workspaces/WorkspaceProjectContextExtensions.cs +++ b/src/Microsoft.DotNet.ProjectModel.Workspaces/WorkspaceProjectContextExtensions.cs @@ -1,5 +1,4 @@ using Microsoft.CodeAnalysis; -using Microsoft.Extensions.ProjectModel; namespace Microsoft.DotNet.ProjectModel.Workspaces { diff --git a/src/Microsoft.DotNet.ProjectModel/Constants.cs b/src/Microsoft.DotNet.ProjectModel/Constants.cs new file mode 100644 index 000000000..c3c5b0da4 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Constants.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.ProjectModel +{ + internal static class Constants + { + public static readonly string DefaultOutputDirectory = "bin"; + public static readonly string DefaultConfiguration = "Debug"; + } +} diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs index 8166c9b92..8721ad775 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs @@ -113,14 +113,18 @@ namespace Microsoft.DotNet.ProjectModel ProjectFile.Name + FileNameSuffixes.DotNet.ProgramDatabase); } - private string GetOutputDirectoryPath(string buildConfiguration) + public string GetOutputDirectoryPath(string buildConfiguration) { - return Path.Combine( + var outDir = Path.Combine( ProjectDirectory, DirectoryNames.Bin, buildConfiguration, - TargetFramework.GetShortFolderName(), - ProjectModel.RuntimeIdentifier.Current); + TargetFramework.GetShortFolderName()); + if (!string.IsNullOrEmpty(RuntimeIdentifier)) + { + outDir = Path.Combine(outDir, RuntimeIdentifier); + } + return outDir; } } } \ No newline at end of file diff --git a/test/LoadContextTest/LoadContextTest.xproj b/test/LoadContextTest/LoadContextTest.xproj new file mode 100644 index 000000000..466d4af8e --- /dev/null +++ b/test/LoadContextTest/LoadContextTest.xproj @@ -0,0 +1,20 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + 7a75acc4-3c2f-44e1-b492-0ec08704e9ff + LoadContextTest + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + + 2.0 + + + diff --git a/test/LoadContextTest/Program.cs b/test/LoadContextTest/Program.cs new file mode 100644 index 000000000..586dd61f5 --- /dev/null +++ b/test/LoadContextTest/Program.cs @@ -0,0 +1,51 @@ +using System; +using System.IO; +using System.Reflection; +using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.ProjectModel.Loader; +using NuGet.Frameworks; + +namespace LoadContextTest +{ + public class Program + { + public static int Main(string[] args) + { + Console.WriteLine("Press enter to start"); + Console.ReadLine(); + // Get the path to the project + if(args.Length < 1) + { + Console.Error.WriteLine("Usage: LoadContextTest "); + return 1; + } + var project = Path.GetFullPath(args[0]); + + // Load the project load context + Console.WriteLine($"Creating load context for {project}"); + var context = ProjectContext.Create(project, FrameworkConstants.CommonFrameworks.DnxCore50, new[] { RuntimeIdentifier.Current }); + var loadContext = context.CreateLoadContext(); + + // Load the project assembly + var asm = loadContext.LoadFromAssemblyName(new AssemblyName(context.ProjectFile.Name)); + + // Find the helper type and method + var type = asm.GetType("TestLibrary.Helper"); + if(type == null) + { + Console.Error.WriteLine("Failed to find type"); + return 1; + } + var method = type.GetMethod("SayHi", BindingFlags.Public | BindingFlags.Static); + if(method == null) + { + Console.Error.WriteLine("Failed to find method"); + return 1; + } + + // Call it! + method.Invoke(null, new object[0]); + return 0; + } + } +} diff --git a/test/LoadContextTest/Properties/AssemblyInfo.cs b/test/LoadContextTest/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..4e1b3147b --- /dev/null +++ b/test/LoadContextTest/Properties/AssemblyInfo.cs @@ -0,0 +1,23 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("LoadContextTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("LoadContextTest")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7a75acc4-3c2f-44e1-b492-0ec08704e9ff")] diff --git a/test/LoadContextTest/project.json b/test/LoadContextTest/project.json new file mode 100644 index 000000000..67dc190b4 --- /dev/null +++ b/test/LoadContextTest/project.json @@ -0,0 +1,26 @@ +{ + "version": "1.0.0-*", + "description": "LoadContextTest Console Application", + "authors": [ "anurse" ], + "tags": [ "" ], + "projectUrl": "", + "licenseUrl": "", + + "compilationOptions": { + "emitEntryPoint": true + }, + + "dependencies": { + "Microsoft.CSharp": "4.0.1-beta-23516", + "System.Collections": "4.0.11-beta-23516", + "System.Console": "4.0.0-beta-23516", + "System.Linq": "4.0.1-beta-23516", + "System.Threading": "4.0.11-beta-23516", + + "Microsoft.DotNet.ProjectModel.Loader": { "target": "project" } + }, + + "frameworks": { + "dnxcore50": { } + } +} diff --git a/test/TestLibrary/Helper.cs b/test/TestLibrary/Helper.cs index 6c3bc0e53..ad2fa235e 100644 --- a/test/TestLibrary/Helper.cs +++ b/test/TestLibrary/Helper.cs @@ -11,5 +11,10 @@ namespace TestLibrary { return "This string came from the test library!"; } + + public static void SayHi() + { + Console.WriteLine("Hello there!"); + } } } diff --git a/test/TestLibrary/project.json b/test/TestLibrary/project.json index 0e91574b2..0b7bbdaf8 100644 --- a/test/TestLibrary/project.json +++ b/test/TestLibrary/project.json @@ -1,7 +1,8 @@ { "version": "1.0.0-*", "dependencies": { - "System.Runtime": "4.0.21-beta-23428" + "System.Runtime": "4.0.21-beta-23428", + "System.Console": "4.0.0-beta-23428" }, "frameworks": {