在我的程序中,我们引用了另一个程序集,并且该程序集中有一个实现实例。所以我们想在运行时调用它的方法。我们已经知道接口和方法名称,但实现实例名称并不一定。我怎么只能从接口和方法名称调用方法?
Type outerInterface = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes()
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Object instance = Activator.CreateInstance(outerInterface);
MethodInfo mi = outerInterface.GetMethod("SampleMethod");
var result = mi.Invoke(instance, new object[]{"you will see me"});
抛出异常:
An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll
Additional information: Cannot create an instance of an interface.
引用的汇编代码在这里:
namespace AnotherAssembly
{
public interface ISample
{
string SampleMethod(string name);
}
public class Sample : ISample
{
public string SampleMethod(string name)
{
return string.Format("{0}--{1}", name, "Alexsanda");
}
}
}
但反射部分不起作用,我不知道如何让它运作良好。
编辑:我不清楚实例名称,只知道接口名称和方法名称。但我知道该程序集中的接口肯定有一个实现类。
答案 0 :(得分:2)
您的错误消息非常明确:您无法创建接口实例。想象一下,如果你写了......
var x = new ISample()
...在普通代码中。根本没有意义 。
错误源于这些代码......
Type outerInterface = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes()
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Object instance = Activator.CreateInstance(outerInterface);
...在上面的列表中,您找到了接口本身,然后尝试实例化它。
你真正想做的是找到实现接口的类型并实例化它......
Type type = Assembly.Load("AnotherAssembly")
.GetTypes()
.Single(t => t.GetInterfaces().Contains(typeof(ISample)));
ISample instance = (ISample) Activator.CreateInstance(type);
string result = instance.SampleMethod("test");
...
请注意我ISample
实例的cast - 这样就无需调用GetMethod
。
如果您还没有对程序集的引用,则可以执行以下操作:
Type[] types = Assembly
.Load("AnotherAssembly")
.GetTypes();
Type sampleInterface = types
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Type type = types
.Single(t => t.GetInterfaces().Contains(sampleInterface));
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("SampleMethod");
string result = (string) method.Invoke(instance, new object[] { "you will see me" });
答案 1 :(得分:1)
您无法实例化接口,但可以找到实现它的类:
Assembly assembly = Assembly.LoadAssembly("AnotherAssemblyFile");
Type[] assemblyTypes = assembly.GetTypes();
Type ISampleType = assemblyTypes.GetType("NameSpace.ISample");
Type sampleType = assemblyTypes.Single(type =>
(type != ISampleType) && ISampleType.IsAssignableFrom(type));
object instance = Activator.CreateInstance(sampleType);
MethodInfo mi = sampleType .GetMethod("SampleMethod");
var result = mi.Invoke(instance, new object[]{"you will see me"});
答案 2 :(得分:1)
您无法创建接口类型的实例,因为接口只是一个API,它是一个合同定义而不是其他任何东西。实际上,如果您尝试实例化界面,您将获得异常:
System.MissingMethodException:无法创建的实例 接口
因此,您需要获取实现接口的类型并实例化该类型的实例:
var anotherAssemblyTypes = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes();
// get interface type
Type outerInterface = anotherAssemblyTypes
.Single(t => t.Name == "ISample" && t.IsInterface);
// find class which implements it
Type outerClass = anotherAssemblyTypes
.Single(t => !t.IsInterface && outerInterface.IsAssignableFrom(t));
// instantiate class
dynamic obj = Activator.CreateInstance(outerClass);
string result = obj.SampleMethod("Bob");
当然,您不必在此处使用动态对象。我用它来测试SampleMethod。