如何在引用公共 DLL 的程序集之间传递引用类型?

发布于 2024-10-15 05:55:56 字数 815 浏览 0 评论 0原文

高级:我正在尝试构建一个控制台应用程序(例如 ConsoleApp.exe),它可以对引用 ConsoleApp.exe 中定义的某种类型的任何给定 DLL 执行一些处理。

我决定(也许是错误的)我需要 ConsoleApp 的配套 DLL,其中包含旨在由任意 DLL 引用的一个或多个类型(例如 ConsoleClass)。为了实现这一目标,因为我不知道更好的方法,我在 ConsoleApp 解决方案中有两个项目,一个是类库(Proving ConsoleApp.dll),另一个是引用类库项目的控制台应用程序。

此时,我现在可以将 ConsoleApp.dll 复制到单独解决方案中的另一个相对不相关的项目(例如 OtherApp.dll),引用它,并编写一个使用 ConsoleClass 实例作为参数的方法。

现在,为了任意处理此 OtherApp.dll,ConsoleApp.exe 加载该程序集,在该程序集中实例化正确的类,然后在该实例上调用正确的方法。下面的相关行希望为我如何做到这一点提供上下文:

Assembly.LoadFrom(path_to_OtherApp_dll);
...
var x = (dynamic)Activator.CreateInstance(type_inside_OtherApp_dll);
...
var instance = new ConsoleClass();
x.some_method_call(instance);

最终失败了。这似乎是因为即使两个项目(ConsoleApp.exe 和 OtherApp.dll)引用相同的 DLL 来定义 ConsoleClass,运行时仍然认为它们是不同的类型。

有什么想法吗?

High level: I am trying to build a console app (e.g. ConsoleApp.exe) which can perform some processing on any given DLL which references a certain type defined in ConsoleApp.exe.

I decided, maybe mistakenly, that I would need a companion DLL for ConsoleApp which contained the type or types (e.g. ConsoleClass) which were intended to be referenced by arbirary DLLs. To pull this off, as I don't know of a better way, I have two projects in the ConsoleApp solution, one is a class library (Proving ConsoleApp.dll) and the other is a console application which references the class library project.

At this point, I now am able to copy my ConsoleApp.dll to another relatively unrelated project in a separate solution (e.g. OtherApp.dll), reference it, and write a method which consumes a ConsoleClass instance as a parameter.

Now, in order to arbitrarily process this OtherApp.dll, the ConsoleApp.exe loads that Assembly, instantiates the proper class in that Assembly, and then calls the proper method on that instance. Pertinent lines below hopefully provide context to how I am doing this:

Assembly.LoadFrom(path_to_OtherApp_dll);
...
var x = (dynamic)Activator.CreateInstance(type_inside_OtherApp_dll);
...
var instance = new ConsoleClass();
x.some_method_call(instance);

Ultimately this fails. It seems to be because even though the two projects (ConsoleApp.exe and OtherApp.dll) are referencing the same DLL to define ConsoleClass, the runtime still considers them to be different types.

Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

木緿 2024-10-22 05:55:57

是的,当 ConsoleApp.dll 加载两次时就会发生这种情况。一次通过主应用程序,再次通过插件,使用其本地副本。类型的标识由加载它的程序集确定。

我不太清楚这是怎么发生的。您选择的第一个武器是 Fuslogvw.exe,将其设置为记录所有绑定。首先要做的是修改插件项目,并将 ConsoleApp.dll 引用的 Copy Local 属性设置为 False,这样就不会意外使用额外的副本。

将插件 DLL 复制到主应用程序构建文件夹是永远不会出现问题的解决方案,您可以使用 Assembly.Load() 加载它们。或者包含 .config 文件的子目录,该文件使用 元素来允许 CLR 找到它们。

Yes, this will happen when ConsoleApp.dll gets loaded twice. Once by the main app, again by a plugin, using its local copy. A type's identity is determined by the assembly it was loaded from.

It isn't that clear to me how that happened. Your first weapon of choice is Fuslogvw.exe, set it up to log all the binds. First thing to do is to doctor the plugin project and set the Copy Local property of the ConsoleApp.dll reference to False so that extra copy isn't there to get accidentally used.

Copying the plugin DLLs to the main app build folder is the never-have-trouble solution, you can load them with Assembly.Load(). Or a subdirectory with a .config file that uses the <probing> element to allow the CLR to find them.

只怪假的太真实 2024-10-22 05:55:57

“运行时认为它们是不同类型”是什么意思?安装程序是否因某些错误异常而结束? x 变量中的方法是否接收到它无法识别的内容或什么?

What do you by "runtime is considering them to be of differnt type"? does setup ends with some exception of error? does method in x variable receives something it does not recognize or what?

只为守护你 2024-10-22 05:55:56
  1. 定义公共接口。把它放到自己的interface.dll中。
  2. 在你的插件中引用interface.dll。让你的plugin.dll 中的主类实现你的接口。
  3. 在您的exe 中引用interface.dll。
  4. 使用 Assembly.Load() 或 Assembly.LoadFrom() 将插件加载到您的 exe 中。
  5. 使用 CreateInstance() 创建插件类的实例。
  6. 只需将创建的插件转换为您的接口类型。

所以你不需要“动态”或其他复杂的东西。很简单,按照我写的一步步进行,就会成功。祝你好运。

  1. Define the public interface. Put it to its own interface.dll.
  2. Reference interface.dll in your plugin. Let the main class in your plugin.dll implements your interface.
  3. Reference interface.dll in your exe.
  4. Use Assembly.Load() or Assembly.LoadFrom() to load plugin into your exe.
  5. Use CreateInstance() to create instance of your plugin class.
  6. Simply cast created plugin to your interface type.

So you don't need "dynamic" or other complicated things. Just easy, go step by step as I wrote and it will work. Good luck.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文