【问题标题】:How to work with an interface dynamically loaded from an assembly and invoke its members如何使用从程序集中动态加载的接口并调用其成员
【发布时间】:2010-09-21 18:55:56
【问题描述】:

我有一些代码来加载程序集并获取所有类型,它们实现了某个接口,就像这样(假设 asm 是一个有效且已加载的程序集)。

var results = from type in asm.GetTypes()
  where typeof(IServiceJob).IsAssignableFrom(type)
  select type;

现在我陷入了困境:我需要创建这些对象的实例并调用对象的方法和属性。而且我需要将创建的对象的引用存储在一个数组中以供以后使用。

【问题讨论】:

  • 您没有明确说明您需要调用的“方法和属性”是任意的还是 IServiceJob 接口的成员。

标签: c# reflection interface assemblies pinvoke


【解决方案1】:

哇哦——我几天前才blogged about this。这是我返回实现给定接口的所有类型的实例的方法:

private static IEnumerable<T> InstancesOf<T>() where T : class
{
    var type = typeof(T);
    return from t in type.Assembly.GetExportedTypes()
           where t.IsClass
               && type.IsAssignableFrom(t)
               && t.GetConstructor(new Type[0]) != null
           select (T)Activator.CreateInstance(t);
}

如果你重构它以接受一个程序集参数而不是使用接口的程序集,它就会变得足够灵活以满足你的需要。

【讨论】:

  • @Matt Hamilton:那么是否有可能以没有默认空构造函数的方式调用构造函数?
  • Activator.CreateInstance 有一个重载,它可以接受传递给您正在实例化的类的 ctor 的对象数组,但我认为您没有任何方法可以在像我在这里发布的那样的单个查询。
【解决方案2】:

您可以使用Activator.CreateInstance 方法创建一个类型的实例:-

IServiceJob x = Activator.CreateInstance(type);

所以你的代码变成了:-

IServiceJob[] results = (from type in asm.GetTypes()
  where typeof(IServiceJob).IsAssignableFrom(type)
  select (IServiceJob)Activator.CreateInstance(type)).ToArray();

(注意将 var 更改为 IServiceJob[] 以明确创建的内容)。

【讨论】:

  • 请记住,如果实现类型没有默认 ctor,则此代码将抛出 MethodMissingException。因此检查我的查询。
  • @Matt Hamilton:那么是否有可能以没有默认空构造函数的方式调用构造函数?
猜你喜欢
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 2012-04-22
  • 2012-12-29
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多