C#反射:替换引用的程序集

3
我目前正在编写一个MutationTesting框架。代码几乎已经完成,但是有一小部分问题(在我花费了半天的时间后)无法解决:
通过反射,我想要执行"TestClass"类中的"TestMethod"方法。"TestClass"所在的项目引用了一个程序集,我们称之为"Proband.dll"。
"TestMethod"会创建一个某种类型的对象,并在该对象上执行方法。
为了澄清一下: - TestClass是包含单元测试的类。 - TestMethod是一个单元测试。 - Proband.dll包含待测试的方法/类。
在执行TestMethod之前,我已经成功地反汇编、突变和重新组装了Proband.dll。因此,现在我有了一个新的"Proband.dll",应该由TestClass来使用!
问题是TestClass已经处于执行过程中。我在思考是否可以创建一个AppDomain,在其中加载新的Proband.dll,并在这个新的AppDomain中执行TestMethod。
我已经创建了这个AppDomain,并成功地将新的Proband.dll加载到其中,但是我不知道如何在这个新的AppDomain中执行TestMethod。而且我也不知道这是否会"替换"测试方法的旧Proband.dll。
以下是我的TestClass:
[TestClass()]
public class TestClass
{
    [TestInitialize()]
    public void MyTestInitialize()
    {
        // code to perform the mutation.
        // From here, the "TestMethod" should be called with 
        // the new "Proband.dll".
    }

    [TestMethod()]
    public void TestMethod()
    {
        // test code calling into Proband.dll
    }
}

有人知道如何实现这个吗?或者有任何线索或关键词吗?

谢谢, Christian

1个回答

1

这可能有些过度了,但看看我的答案:

AppDomain中的静态字段

你需要在加载Proband.dll的AppDomain中创建TestClass,并使用MarshalByRef将类保留在AppDomain中(以便稍后卸载它)。

以下是我所做的更多内容(不完全相同,因为我正在根据你的需求进行更改)。

// Create Domain
_RemoteDomain = AppDomain.CreateDomain(_RemoteDomainName,
   AppDomain.CurrentDomain.Evidence, 
   AppDomain.CurrentDomain.BaseDirectory, 
   AppDomain.CurrentDomain.BaseDirectory, 
   true);

// Load an Assembly Loader in the domain (mine was Builder)
// This loads the Builder which is in the current domain into the remote domain
_Builder = (Builder)_RemoteDomain.CreateInstanceAndUnwrap(
    Assembly.GetExecutingAssembly().FullName, "<namespace>.Builder");

_Builder.Execute(pathToTestDll)


public class Builder : MarshalByRefObject 
{ 
    public void Execute(string pathToTestDll)
    {
        // I used this so the DLL could be deleted while
        // the domain was still using the version that
        // exists at this moment.
        Assembly newAssembly = Assembly.Load(
           System.IO.File.ReadAllBytes(pathToTestDll));

        Type testClass = newAssembly.GetType("<namespace>.TestClass", 
           false, true);

        if (testClass != null)
        {
           // Here is where you use reflection and/or an interface
           // to execute your method(s).
        }
    }
}

这应该为您提供所需的解决方案。


如果我在新的AppDomain中创建TestClass,它会自动使用已加载的Proband.dll吗?还是会加载旧版本的proband.dll? - Christian
嗯,每当我执行 object testClass = mutationDomain.CreateInstanceAndUnwrap(parentObject.GetType().Assembly.FullName, "ArithmeticsTest"); -> 时,我会得到一个 FileNotFoundException。更糟糕的是,它并没有说明找不到哪个文件... - Christian
更新以更全面地回答您的问题。 - Erik Philips

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接