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

时间:2018-01-08 20:29:01

标签: c# dll system.reflection

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

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

&#34;没有为此对象定义0参数的构造函数&#34; (平均翻译)

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

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

我既没有找到任何返回班级对象或getInstance函数的工厂类。

知道如何继续吗?

2 个答案:

答案 0 :(得分:1)

这里有一些可能性。

首先,所有已定义的参数都带有参数。并不能保证每个类都有一个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首先拥有私有构造函数可能很重要。如果您正在尝试定义Singleton,那么这实际上是很常见的事情,在这种情况下,您可能不想直接调用构造函数。

对于像这样的单身人士:

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;

答案 1 :(得分:0)

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

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

  

Regsvr32。\ file.ocx

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

  

使用Microsoft.VisualBasic;

     

MyAssemblyName object =(MyAssemblyName)Interaction.CreateObject(“MyNamespace.MyAssemblyName”,“”);