在运行时实例化 Assembly 时找不到构造函数

No constructor found while instantiating Assembly on runtime

加载 DLL 并获取类型后,我在尝试实例化它时遇到异常:

Assembly dll = Assembly.LoadFrom(@"C:\path\file.dll");
Type type = dll.GetType("namespace.CustomClass");
object obj = Activator.CreateInstance(type); // <-- System.MissingMethodException

"No constructor with 0 parameters defined for this object" (average translation)

探索加载类型,我可以看到 DeclaredConstrunctors -> {Void .ctor()}

但是调用 type.GetConstructors() 我得到一个空数组(我猜这意味着只有默认构造函数存在?)

我没有找到任何工厂 class returns 我的 class 的对象或 getInstance 函数。

知道如何进行吗?

这里有几种可能性。

首先是所有定义的参数都带参数。不能保证每个 class 都有一个 0 参数构造函数。下面是一些产生此错误的代码示例:

public class SomeCons
{
    public SomeCons(string cons)
    {

    }
}

static void Main(string[] args)
{
    object result = Activator.CreateInstance(typeof(SomeCons));
}

第二种可能namespace.CustomClass有一个私有构造函数。以下代码产生与您看到的类似的行为。我还包括了一个如何找到实际构造函数的示例 - 你想要 use Binding Flags.

private class NoCons
{
    private NoCons()
    {

    }
}

static void Main(string[] args)
{
    // As you saw, this shows one declared constructor
    Type exploratory = typeof(NoCons);

    // Returns nothing
    ConstructorInfo[] constructors = typeof(NoCons).GetConstructors();

    // Returns 1 constructor
    constructors = typeof(NoCons).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}

请注意,首先准确理解为什么 namespace.CustomClass 有一个私有构造函数可能很重要。如果你试图定义一个单例,这实际上是一件很常见的事情,在这种情况下你可能不想直接调用构造函数。

对于这样的单身人士:

private class NoCons
{
    private NoCons()
    {

    }

    private static NoCons _instance;

    public static NoCons Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new NoCons();
            }

            return _instance;
        }
    }
}

尝试这样的事情:

Type exploratory = typeof(NoCons);

PropertyInfo singletonProperty = exploratory.GetProperties(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(prop => prop.Name.Contains("Instance"));

string name = singletonProperty.GetGetMethod().Name;

var noCons = exploratory.GetMethod(name).Invoke(null, null) as NoCons;

DLL 有一个相关的 OCX 文件放在另一个文件夹中。

文件已使用以下方式注册:

Regsvr32 .\file.ocx

在那之后,我已经能够实例化一个对象调用:

using Microsoft.VisualBasic;

MyAssemblyName object = (MyAssemblyName) Interaction.CreateObject( "MyNamespace.MyAssemblyName", "");