在运行时动态加载DLL并创建接口实现实例。

问题描述 投票:0回答:1

我有很多DLL连接器。每个DLL里面有太多的方法。但是每个DLL连接器都包含以下两个方法(byte[] Document = GetDocument(string, string, string); byte[] Image = GetImage(string, string, string);)。

我想做的是:1-在运行时选择DLL文件.2-填入三个字符串.3-将这三个字符串传给插入的DLL里面的方法(上面提到的),以接收返回的文件。

我只是想知道如何调用DLL里面的方法。

任何帮助都是感激的。

c# wpf dll load
1个回答
0
投票

你必须使用反射(当然)。请看一下 Assembly 类。

例如,你可以使用 Assembly.LoadFileAssembly.LoadFrom 来加载汇编。要激活一个assmebly中包含的类型以调用其成员,你可以使用 Assembly.CreateInstance:

Assembly assembly = Assembly.LoadFile("C:\bin\runtime.dll");
TypeInsideAssembly instanceOfTypeInsideAssembly = (TypeInsideAssembly) assembly.CreateInstance(typeOf(TypeInsideAssembly));
instanceOfTypeInsideAssembly.InvokeMethod(params);

如果构造函数需要参数,你可以使用适当的 过载 CreateInstance(String, Boolean, BindingFlags, Binder, Object[], CultureInfo, Object[]).

例子

下面的通用示例使用反射来创建以下实例 TBase 位于指定的汇编中,期待一个无参数的构造函数。TBase 可以是一个类(基类)或接口。类型不是 public 或没有定义一个无参数的构造函数将被忽略。

private IEnumerable<TBase> GetInstancesOf<TBase>(string assemblyFilePath)
{
  var assembly = Assembly.LoadFile(assemblyFilePath);

  // Get all public types that are defined in this assembly
  Type[] publicTypes = assembly.GetExportedTypes();

  // Filter all public types in assembly and return only types...
  IEnumerable<TBase> documentProviders = publicTypes

    // ...that are not an interface (as we can't create instances of interfaces)...
    .Where(publicType => !publicType.IsInterface 

      // ...AND that are not an abstract class (as we can't create instances of abstract types)...
      && !publicType.IsAbstract 

      // ...AND that have a public parameterless constructor...
      && publicType.GetConstructor(Type.EmptyTypes) != null 

      // ...AND are a subtype of TBase. Note that TBase can be a base class or interface 
      && typeof(TBase).IsAssignableFrom(publicType))

    // Take each collected type and create an instance of those types
    .Select(concreteInterfaceType => assembly.CreateInstance(concreteInterfaceType.FullName))

    // Since CreateInstance() returns object, cast each created instance to the common subtype TBase
    .Cast<TBase>();

  return documentProviders;
}

使用方法

private void HandleDocuments(string assemblyFilePath)
{
  foreach (IClientMethods documentProvider in GetInstancesOf<IClientMethods>(assemblyFilePath))
  {        
    byte[] document = documentProvider.GetDocument(...);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.