将外部程序集加载到新的应用程序域并调用“基类”的方法

Posted

技术标签:

【中文标题】将外部程序集加载到新的应用程序域并调用“基类”的方法【英文标题】:Load external assemblies into new app domain and call a method of "base class" 【发布时间】:2021-09-29 00:23:55 【问题描述】:

我是 .NET 远程处理的新手(我相信这与此有关)。

假设主应用程序引用了一个类库A,其中包含一个带有抽象方法的抽象类。

现在,假设我们创建一个全新的项目 B 并引用相同的 DLL A,创建一个继承抽象类并实现方法的新类。

是否可以将这个新程序集加载到主应用程序的新应用程序域中并创建一个只知道基类类型的实例?

或者有更好的方法吗?我正在考虑这里的某种插件系统。

编辑:对于反射,我们可以找到继承基类的类型,然后使用 (BaseClass)Activator.CreateInstance(ParentType);无需知道ParentType

【问题讨论】:

非常不清楚您要做什么-“仅知道基类类型创建实例”-代码如何知道要创建什么?如果您展示您已经尝试过的内容以及卡在哪里,那么回答会容易得多(因为有很多“在另一个应用程序域中创建课程”问题,所以我相信您已经阅读了很多)跨度> “只知道基类类型创建实例”是什么意思?您需要知道您正在创建的实例的类型 - 您可以检查 B 中的所有类型并查看是否有任何扩展“A”,但如果有多个呢? 换句话说,没有内置函数可以“从 B 扩展类型 T 创建任何类型的实例” 我编辑了这个问题。我在想的是类似于 Activator.CreateInstance。这是否可能在外部程序集中以及在不同的应用程序域中? Here 是我对相关问题的较早回答。就像@user1624411 一样,我使用了接口而不是抽象类。关键是AppDomain.CreateInstanceAndUnwrap,这是您使用远程处理时的Activator.CreateInstance。它还可以帮助您避免使用已加载的程序集污染主域,这些程序集可以通过AppDomain.Unload 卸载 【参考方案1】:

当然可以。 这从具有派生自 IPlugin 的类型的外部程序集打印 2147483647。 IPlugin 在您的主域中定义:

var asy = Assembly.LoadFrom("yourChildAssembly.dll");

List<Type> availablePlugIns = asy.GetTypes().Where(t => !t.IsAbstract && typeof(IPlugin).IsAssignableFrom(t)).ToList();

var myPluginType = availablePlugIns.FirstOrDefault();

if (myPluginType != null)

   IPlugin pluginInstance = (IPlugin)System.Activator.CreateInstance(myPluginType); 
   pluginInstance.MyPluginMethod();

使用的示例类型:

public interface IPlugin

    int MyPluginMethod();


public class MyPluginClass : IPlugin

    public int MyPluginMethod()
    
        return int.MaxValue;
    

这个例子只是一个快速而肮脏的解决方案,它有一些限制,比如你的类应该有一个无参数的构造函数来实例化。但您可以将其作为起点。

编辑:我使用了和接口,但它也适用于抽象类

【讨论】:

这会将插件程序集加载到主AppDomain 是的。只是为了展示他如何获得类似插件的系统。如果他按照我的例子和你对 AppDomain 的建议,他会找到解决方案。

以上是关于将外部程序集加载到新的应用程序域并调用“基类”的方法的主要内容,如果未能解决你的问题,请参考以下文章

创建应用程序域并加载程序集

无法将存档的 NSMutableArray 加载到新的 NSMutableArray

如何将变量保存到新的文本文件中,以便下次程序运行时加载这些变量?

使用 blazor 加载外部 .NET Standard 2.0 程序集

无法在新的 AppDomain 中创建 UserControl

将datagridview中的数据集存储到新的访问数据库文件c#