public void AssemblyLoadContext_IfCustomContextsLoadReturnsNullAndDefaultContextHasAssemblyAssemblyFromDefaultContextIsBound() { // Arrange string solutionDir = Path.GetFullPath(typeof(AssemblyLoadContextTests).GetTypeInfo().Assembly.Location + "../../../../../../.."); string referenceeProjectName = "StubProject.Referencee"; string referenceeAssemblyPath = $"{solutionDir}/test/{referenceeProjectName}/bin/debug/netstandard1.1/{referenceeProjectName}.dll"; string referencerProjectName = "StubProject.Referencer"; string referencerAssemblyPath = $"{solutionDir}/test/{referencerProjectName}/bin/debug/netstandard1.1/{referencerProjectName}.dll"; AssemblyLoadContext.Default.LoadFromAssemblyPath(referenceeAssemblyPath); BasicAssemblyLoadContext loadContext = new BasicAssemblyLoadContext(); // Act Assembly referencerAssembly = loadContext.LoadFromAssemblyPath(referencerAssemblyPath); Type type = referencerAssembly.GetTypes().First(); object test = Activator.CreateInstance(type); MethodInfo method = type.GetMethod("CreateReferenceeStubClassInstance", BindingFlags.Instance | BindingFlags.Public); object referenceeStubInstance = method.Invoke(test, new object[] { }); Assembly referenceeAssembly = referenceeStubInstance.GetType().GetTypeInfo().Assembly; // Assert Assert.NotNull(referencerAssembly); AssemblyLoadContext referencerLoadContext = AssemblyLoadContext.GetLoadContext(referencerAssembly); Assert.Equal(loadContext, referencerLoadContext); AssemblyLoadContext referenceeLoadContext = AssemblyLoadContext.GetLoadContext(referenceeAssembly); Assert.Equal(AssemblyLoadContext.Default, referenceeLoadContext); }
public void AssemblyLoadContext_PropagatesExceptionsAcrossContextBoundaries() { // Arrange string solutionDir = Path.GetFullPath(typeof(AssemblyLoadContextTests).GetTypeInfo().Assembly.Location + "../../../../../../.."); string projectAndAssemblyName = "StubProject.ThrowsException"; string assemblyPath = $"{solutionDir}/test/{projectAndAssemblyName}/bin/debug/netstandard2.0/{projectAndAssemblyName}.dll"; string testExceptionMessage = "testExceptionMessage"; BasicAssemblyLoadContext loadContext = new BasicAssemblyLoadContext(); Assembly assembly = loadContext.LoadFromAssemblyPath(assemblyPath); Type throwsExceptionStubClass = assembly.GetTypes().First(); object throwsExceptionStubClassInstance = Activator.CreateInstance(throwsExceptionStubClass); MethodInfo method = throwsExceptionStubClass.GetMethod("ThrowException", BindingFlags.Instance | BindingFlags.Public); // Act Exception result = null; try { method.Invoke(throwsExceptionStubClassInstance, new object[] { testExceptionMessage }); } catch (Exception exception) { result = exception; } // Assert Assert.NotNull(result); Assert.Equal(testExceptionMessage, result.InnerException.Message); }
public void AssemblyLoadContext_StaticsOfTheSameTypeInDifferentLoadContextsAreNotShared() { // Arrange string solutionDir = Path.GetFullPath(typeof(AssemblyLoadContextTests).GetTypeInfo().Assembly.Location + "../../../../../../.."); string projectAndAssemblyName = "StubProject.Statics"; string projectFile = $"{solutionDir}/test/{projectAndAssemblyName}/{projectAndAssemblyName}.csproj"; string assemblyPath = $"{solutionDir}/test/{projectAndAssemblyName}/bin/debug/netstandard2.0/{projectAndAssemblyName}.dll"; Assembly defaultALCAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath); Type defaultStubClass = defaultALCAssembly.GetTypes().First(); FieldInfo defaultField = defaultStubClass.GetField("StaticField"); object defaultInstance = Activator.CreateInstance(defaultStubClass); AssemblyLoadContext customContext = new BasicAssemblyLoadContext(); Assembly customALCAssembly = customContext.LoadFromAssemblyPath(assemblyPath); Type customStubClass = customALCAssembly.GetTypes().First(); FieldInfo customField = customStubClass.GetField("StaticField"); object customInstance = Activator.CreateInstance(customStubClass); // Act defaultField.SetValue(defaultInstance, 1); customField.SetValue(customInstance, 2); // Assert Assert.Equal(1, defaultField.GetValue(defaultInstance)); }
public void AssemblyLoadContext_InstancesOfATypeFromTheSameAssemblyInDifferentContextsCannotBeUsedInterchangeably() { // Arrange string solutionDir = Path.GetFullPath(typeof(AssemblyLoadContextTests).GetTypeInfo().Assembly.Location + "../../../../../../.."); string projectAndAssemblyName = "StubProject.Referencee"; string projectFile = $"{solutionDir}/test/{projectAndAssemblyName}/{projectAndAssemblyName}.csproj"; string assemblyPath = $"{solutionDir}/test/{projectAndAssemblyName}/bin/debug/netstandard1.1/{projectAndAssemblyName}.dll"; Assembly defaultALCAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath); Type defaultStubClass = defaultALCAssembly.GetTypes().First(); AssemblyLoadContext customContext = new BasicAssemblyLoadContext(); Assembly customALCAssembly = customContext.LoadFromAssemblyPath(assemblyPath); Type customStubClass = customALCAssembly.GetTypes().First(); // Act and Assert Assert.Throws <InvalidCastException>(() => Convert.ChangeType(Activator.CreateInstance(customStubClass), defaultStubClass)); }
public void AssemblyLoadContext_IfCustomContextsLoadReturnsNullAndDefaultContextHasDifferentVersionOfTheSameAssemblyAssemblyFromDefaultContextIsBoundd() { // Arrange string solutionDir = Path.GetFullPath(typeof(AssemblyLoadContextTests).GetTypeInfo().Assembly.Location + "../../../../../../.."); string projectName = "StubProject.OlderFramework"; string assemblyPath = $"{solutionDir}/test/{projectName}/bin/debug/netstandard1.0/{projectName}.dll"; BasicAssemblyLoadContext loadContext = new BasicAssemblyLoadContext(); // Act Assembly projectAssembly = loadContext.LoadFromAssemblyPath(assemblyPath); Type olderFrameworkStubClass = projectAssembly.GetTypes().First(); object olderFrameworkStubClassInstance = Activator.CreateInstance(olderFrameworkStubClass); MethodInfo getString = olderFrameworkStubClass.GetMethod("GetString", BindingFlags.Instance | BindingFlags.Public); object result = getString.Invoke(olderFrameworkStubClassInstance, new object[] { }); // Assert Assert.NotNull(result); // Older framework project references an older system.runtime version. Newer version from host was bound instead. }
public void AssemblyLoadContext_AnInstanceofATypeFromAnAssemblyLoadedDynamicallyCanHaveItsMethodsCalledUsingReflection() { // Arrange string solutionDir = Path.GetFullPath(typeof(AssemblyLoadContextTests).GetTypeInfo().Assembly.Location + "../../../../../../.."); string projectAndAssemblyName = "StubProject.InstanceMethod"; string assemblyPath = $"{solutionDir}/test/{projectAndAssemblyName}/bin/debug/netstandard2.0/{projectAndAssemblyName}.dll"; string testString = "testString"; AssemblyLoadContext loadContext = new BasicAssemblyLoadContext(); Assembly assembly = loadContext.LoadFromAssemblyPath(assemblyPath); Type instanceMethodStubClass = assembly.GetTypes().First(); object instanceMethodStubClassInstance = Activator.CreateInstance(instanceMethodStubClass); MethodInfo method = instanceMethodStubClass.GetMethod("GetString", BindingFlags.Instance | BindingFlags.Public); // Act String result = (string)method.Invoke(instanceMethodStubClassInstance, new object[] { testString }); // Assert Assert.Equal(testString, result); }
public void AssemblyLoadContext_AllowsDifferentVersionsOfTheSameAssemblyToBeLoadedInDifferentContexts() { // Arrange string solutionDir = Path.GetFullPath(typeof(AssemblyLoadContextTests).GetTypeInfo().Assembly.Location + "../../../../../../.."); string projectAndAssemblyName = "StubProject.Referencee"; string projectFile = $"{solutionDir}/test/{projectAndAssemblyName}/{projectAndAssemblyName}.csproj"; string assemblyV1Path = $"{solutionDir}/test/{projectAndAssemblyName}/bin/debug/netstandard1.1/{projectAndAssemblyName}.dll"; string testVersion = "2.0.0.0"; _msBuildService.Build(projectFile, $"/t:build /p:OutDir={_tempDir},AssemblyVersion=2.0.0.0"); // TODO netstandard2.0 and earlier, AssemblyLoadContexts cannot be unloaded string assemblyV2Path = $"{_tempDir}/{projectAndAssemblyName}.dll"; BasicAssemblyLoadContext loadContext = new BasicAssemblyLoadContext(); // Act Assembly assemblyV1 = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyV1Path); Assembly assemblyV2 = loadContext.LoadFromAssemblyPath(assemblyV2Path); // Assert Assert.Equal("1.0.0.0", assemblyV1.GetName().Version.ToString()); Assert.Equal(testVersion, assemblyV2.GetName().Version.ToString()); }