首页 > 解决方案 > Activator.CreateInstance 与自定义类参数

问题描述

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

类 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

关于如何解决这个问题有什么建议吗?

标签: c#dll-injectionactivator

解决方案


如图所示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) { }
}

推荐阅读