【问题标题】:C# create instance of type from DLL extending host application typeC# 从 DLL 扩展主机应用程序类型创建类型实例
【发布时间】:2017-03-05 19:21:11
【问题描述】:

如果不能,这可能吗?有人可以解释一下我如何实现它吗?

所以我有一个 C# 应用程序和一个名为模块的文件夹,所以文件:

Application.exe
modules/
        Application.Handler.ModuleName.dll

因此,在 DLL 内部,它的命名空间 Application.Handle 包含类型 ModuleNameModuleName 扩展了在 Application.exe 中实现的 Handler,因此编译需要 Application.exe 作为参考。

在我的主机应用程序中,我有:

 string[] dirs = Directory.GetFiles(@"modules/", "Application.Handler.*.dll");
 foreach(string filePath in dirs)
 {
      Assembly.LoadFile(new FileInfo(filePath).FullName);

      string fileName = filePath.Split('/').Last();
      string typeAssemblyName = fileName.Replace(".dll", "");
      string typeName = typeAssemblyName.Split('.').Last();
 }

但我不确定我是否可以从我认为可以使用 Activator.CreateInstance 的字符串中实现类型,但我不确定我是否正确地执行它或者我尝试实现它的方式是否有效?

更新 我可能不清楚,但实际上我需要做的是 Application.Handler handler = new Application.Handler.ModuleName()Application.Handler.ModuleName 在 php 中的操作如下所示,我认为会有一个系统返回字符串中给定类型的对象。如果不存在则抛出异常

$className = "\Application\Handler\ModuleName"; 
$instance = new $className();

我也尝试过使用@rene 建议的Unwrap 系统

Assembly asm = Assembly.LoadFile(new FileInfo(filePath).FullName);

string fileName = filePath.Split('/').Last();
string typeAssemblyName = fileName.Replace(".dll", "");
string typeName = typeAssemblyName.Split('.').Last();
FrameHandler fh;
fh = (FrameHandler)Activator.CreateInstance(asm.FullName, typeAssemblyName).Unwrap();
fh.RegisterHandlers();

使用这种方法,我给它一个 Assembly 名称,它给了我一个 FileNotFoundException,没有 Assembly 名称我得到 TypeLoadException,但它必须将程序集的清单加载为 Application.Handler.ModuleName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

【问题讨论】:

  • 你不能用MEF吗?
  • 我得到的只是The type or namepsace 'Composition' does not exists in ...
  • 我至少会确保共享的 接口 在应用程序和“插件”DLL 引用的单独程序集中声明。通过这样做,您将避免循环依赖/引用。
  • 我没有循环依赖,模块依赖于主机进行编译,但是当我将它作为程序集加载时,我不需要再次加载主机应用程序,因为名称空间和类型已经存在。 @spender
  • 我认为你必须UnWrap

标签: c# dll .net-assembly


【解决方案1】:

您只需要类型的句柄,因此您将需要程序集路径和类型的全名

var assy = Assembly.LoadFile("...");
var type = assy.GetType("...");
var obj = Activator.CreateInstance(type);

【讨论】:

  • 你能不能更新一下使用我的代码,例如var type=asm.GetType(typeAssemblyName)
  • 没必要 - 我不知道您的类型或程序集的名称,所以我为什么要将它包含在我的答案中?您可以通过在包含它的程序集中调用 type.FullName 或更好的方法来找到您的类型名称 - type.AssemblyQualifiedName
  • 这就是我的观点,如果您阅读我的问题和代码,您将获得该信息,并且您可以对问题给出完整且有意义的完整答案...
猜你喜欢
  • 2011-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
相关资源
最近更新 更多