带有自定义类参数的 Activator.CreateInstance

时间:2021-01-20 07:24:40

标签: c# dll-injection activator

我正在尝试使用 Activator.CreateInstance 从 dll 创建一个实例(类测试)。

Class Test 有一个构造函数,它需要一个论证类 CommonService。但它会抛出 System.MissingMethodException 错误。

有代码:

// Define
public class Test: BaseTest
{
    public Test(CommonService commonService) : base(commonService, new TestConfigurations()
    {
       enableTimer = false
    })
    { 
    }
}

// Usage
var commonService = new CommonService();
var test = new Test(commonService); // test can be created successfully.

var dll = Assembly.LoadFile(@"xxx\Test.dll");
foreach (Type type in DLL.GetExportedTypes())
{
    if (type.BaseType?.Name?.Equals("BaseTest") == true)
    {
        dynamic c = Activator.CreateInstance(type, new object[] { // Throw System.MissingMethodException error
            commonService
        });
    }
}

这是完整的代码链接:https://codeshare.io/2EzrEv

有没有关于如何解决问题的建议?

1 个答案:

答案 0 :(得分:0)

如图所示的 Activator.CreateInstance:应该可以正常工作。如果不是,那么您正在初始化的 type 可能不是您认为的那样 - 检查 type.FullName 的值。或者,您可能在不同的位置具有相同名称的类型,这意味着:您传入的CommonService 不同类型所期望的 CommonService。你可以用反射来检查。以下打印 True 两次:

using System;
using System.Linq;
using System.Reflection;

public class Test : BaseTest
{
    public Test(CommonService commonService) : base(commonService, new TestConfigurations()
    {
        enableTimer = false
    })
    {
    }
}

static class P
{
    static void Main()
    {
        // Usage
        var commonService = new CommonService();
        var test = new Test(commonService); // test can be created successfully.

        var type = typeof(Test); // instead of loop
        dynamic c = Activator.CreateInstance(type, new object[] { // Throw System.MissingMethodException error
            commonService
        });
        Console.WriteLine(c is object); // it worked

        var ctor = type.GetConstructors().Single();
        var ctorArg = ctor.GetParameters().Single();
        Console.WriteLine(ctorArg.ParameterType == typeof(CommonService)); // check the expected param type
    }
}
public class CommonService { }
public class TestConfigurations
{
    internal bool enableTimer;
}
public class BaseTest
{
    public BaseTest(CommonService svc, TestConfigurations cfg) { }
}