在运行时实例化 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", "");
加载 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", "");