Skip to content

Instantly share code, notes, and snippets.

@pardeike
Created April 26, 2019 19:51
Show Gist options
  • Save pardeike/495b8ad65b0a84bea97f1067ee181ff8 to your computer and use it in GitHub Desktop.
Save pardeike/495b8ad65b0a84bea97f1067ee181ff8 to your computer and use it in GitHub Desktop.
A test that verifies that dynamic assemblies with method builder are garbage collected
using HarmonyLib;
using NUnit.Framework;
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace HarmonyLibTests
{
[TestFixture]
public class TestMethodBuilder
{
public static string Original()
{
try
{
return "Foo";
}
catch (Exception)
{
throw;
}
}
[Test]
public void TestGarbageCollection()
{
var currentDomain = AppDomain.CurrentDomain;
GC.Collect();
var baseCount = currentDomain.GetAssemblies().Length;
for (var i = 1; i <= 10; i++)
{
var abuilder = currentDomain.DefineDynamicAssembly(new AssemblyName("assembly" + i), AssemblyBuilderAccess.RunAndCollect);
var mBuilder = abuilder.DefineDynamicModule("assembly" + i, "assembly" + i + ".exe");
var tBuilder = mBuilder.DefineType("TestType", TypeAttributes.Public);
var meBuilder = tBuilder.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(string), new Type[0]);
var generator = meBuilder.GetILGenerator();
generator.Emit(OpCodes.Ldstr, "Hello World" + i);
generator.Emit(OpCodes.Ret);
var aType = tBuilder.CreateType();
var method = aType.GetMethod("TestMethod");
Assert.IsNotNull(method);
var original = typeof(TestMethodBuilder).GetMethod("Original");
Assert.IsNotNull(original);
var error = Memory.DetourMethod(original, method);
Assert.IsNull(error);
var res = Original();
Assert.AreEqual(res, "Hello World" + i);
Assert.AreEqual(currentDomain.GetAssemblies().Length, baseCount + 1);
GC.Collect();
Assert.AreEqual(currentDomain.GetAssemblies().Length, baseCount);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment