2011-08-25 56 views
2

我处于这种情况,我必须在签名的应用程序中使用未签名的第三方.NET DLL。所以我决定在运行时动态地加载该库:在动态加载的第三方程序集中使用静态类

var asm = Assembly.LoadFrom("THIRDPARTYASSEMBLY.DLL"); 

有一个在我定义的接口在我的应用程序的DLL静态类和使用GetUninitializedObject()加载类:

var obj = FormatterServices.GetUninitializedObject(asm.GetType("NAMESPACE.CLASS")) as IMyInterface; 

虽然我试图加载类不是抽象的(这是一个public static类),我在运行时出现此错误:

System.MemberAccessException是未处理的:不能ç创建一个抽象类 。

很明显,我不能使用CreateInstance方法,因为静态类没有任何构造函数。

那么你会建议什么?我想要:

  • 从该库调用public static方法。 (我目前使用InvokeMember()。)
  • 获取Custom Type属性。
  • 在我的应用程序中处理几个Custom Events

在此先感谢。

回答

5

而不是尝试动态调用该方法,您可以尝试强名称的第三方DLL。

您将需要一个密钥来强烈地命名dll。你可以使用你已经用于你自己的DLL的一个,或者为此创建一个新的(使用sn -k)。

为强名称已编译的程序集:

  1. 打开Visual Studio命令提示符(获取工具集成到你的路径)。
  2. 从组件生成IL:
    ildasm ThirdParty.dll /out:ThirdParty.il
  3. 原ThirdParty.dll重命名为别的东西。
  4. 生成一个新的DLL,强命名它为你这样做:
    ilasm ThirdParty.il /dll /key=MyKey.snk

这将导致一个新的ThirdParty.dll这将是强劲,已指定的键命名。然后,您可以添加一个直接引用,并像通常那样直接调用这些方法。

+0

第4步有一个错字:应该是'ilasm ThirdParty.il/dll /key=MyKey.snk'谢谢你的回答:) –

+0

@John:谢谢,纠正。 – adrianbanks

4

如果它只是一个静态类,则不需要未初始化的对象。一旦你得到的类型,例如

Type t = asm.GetType("NAMESPACE.CLASS"); 

你可以得到你需要

MethodInfo method = t.GetMethod("MethodName"); 
//getmethod has some useful overloads 
//also GetMethods() returns a MethodInfo[] array containing all methods 

,那么你可以调用

object result = method.Invoke(null, new object[] { param1, param2, ... }); 

有这样做,以及其他的方式方法。您可以使用委托来获取指向该方法的函数指针,而不是调用invoke。

我不确定如何做事件处理程序,虽然我确定如果您在Type对象下浏览intellisense,您应该能够找到某些东西。就属性而言,通常只使用它们作为对象,但如果要使用静态类的属性,并且事先已知道返回类型,则可以创建一个类来处理它:

public class ExternalProperty<PropertyType> 
{ 
    delegate PropertyType GetFunction(); 
    delegate void SetFunction(PropertyType value); 
    GetFunction GetValue; 
    SetFunction SetValue; 

    public ExternalProperty(PropertyInfo externalProperty) 
    { 
     MethodInfo getMethod = externalProperty.GetGetMethod(); 
     GetFunction getter = (GetFunction)Delegate.CreateDelegate(typeof(GetFunction), getMethod); 
     MethodInfo setMethod = externalProperty.GetSetMethod(); 
     SetFunction setter = (SetFunction)Delegate.CreateDelegate(typeof(SetFunction), setMethod); 
    } 

    public PropertyType Value 
    { 
     get { return GetValue(); } 
     set 
     { 
      SetValue(value); 
     } 
    } 
} 

如果你已经知道属性类型,使用这个类很容易。假设你有一个字符串类型的属性名称:

ExternalProperty<string> PropName = new ExternalProperty(t.GetProperty("Name")); 
string oldName = PropName.Value; //this will call the property's getter 
PropName.Value = "new name"; //this will call the property's setter 

它没有错误检查,但这样,如果你尝试通过比指定,或一个不同类型的属性,无法找到它,它会打破。这也不适用于对象,只适用于静态类。希望有所帮助。

+0

没错。而'GetUnitializedObject' *实例化类,所以它当然不能用于与静态类进行交互。 –

+0

我目前使用类似的方法来调用方法,但我无法使用'GetProperty()'获取属性,并将它们转换为我的应用程序中的类似匹配接口。另外我不知道如何设置事件处理程序。 – fardjad