将程序集加载到单独的AppDomain中,出现InvalidCastException错误

6

我正在尝试在单独的应用程序域中加载程序集,但遇到了一个非常奇怪的问题。以下是一些代码:

    public static void LoadAssembly(string assemblyPath)
    {

        string pathToDll = Assembly.GetCallingAssembly().CodeBase;
        AppDomainSetup domainSetup = new AppDomainSetup
        {
            PrivateBinPath = pathToDll
        };

        AppDomain newDomain = AppDomain.CreateDomain("AssemblyLoader",null,domainSetup);


        AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
            pathToDll,
            typeof(AssemblyLoader).FullName);

    }

AssemblyLoader是与此类相同程序集中的另一个类,它继承自MarshalByRef,但由于某种奇怪的原因,每次尝试运行时都会出现强制转换异常。我甚至硬编码了DLL的路径而不是使用GetCallingAssembly().CodeBase,但仍然出现异常。
我知道在没有实际看到代码并获得更多信息的情况下回答这样的问题很困难,但也许有人遇到过类似的情况,并且知道常见的“坑”以及应该注意什么。
编辑:我不想直接加载它的原因是因为这只是代码的一部分。最终目标是,这个类将有一个方法来加载程序集,获取它们的GUID和其他一些信息,并将它们存储在我正在开发的项目的数据库中。因此,如果我在单独的应用程序域中加载此程序集,我也可以在那里加载其他程序集,然后卸载该应用程序域。如果我只需要那些数据,那么在整个应用程序的持续时间内加载所有这些程序集是没有意义的。

如果AssemblyLoader类与此类在同一个程序集中,为什么要尝试从newDomain加载它?为什么不直接实例化它呢? - Phillip Wells
1
这是一种间接加载插件的方式。如果加载器实例在主应用程序域中,您可以在外部应用程序域中创建一个版本,并要求它加载您感兴趣的插件。这样可以防止插件需要知道它们是否能够由单独的应用程序域处理。(即从MarshalByRefObject派生) 这保持了设计决策的灵活性(例如,创建一个插件基类,为插件提供所有共享功能。) - Jason D
4个回答

2

(编辑:阅读给定的异常后,完全更改答案)

问题似乎出在CreateInstanceFromAndUnwrap调用上,它使用“pathToDll”的LoadFrom语义。 Suzanne Cook在她的博客中详细说明了可能的关键点,在这里您的原始AppDomain试图调用Load("SomeAssembly, [...]")而不是LoadFrom("pathToDll")来解决所涉及的类型。

她的建议是钩住当前域上的AssemblyResolve事件以执行正确的LoadFrom以获取类型。有一点有针对性的谷歌搜索带来了一个基于Suzanne建议的可能解决方案


不,这是在说:无法将透明代理转换为类型“CompanyNamespaceTakenOut.AssemblyLoader” - BFree

0

请查看这篇文章

使用那篇文章中的代码,我得到了一个跨应用程序域对象。我使用泛型进行了一些抽象,并拥有三个程序集(即定义接口的程序集、定义插件实现的程序集以及告诉泛型要加载什么的主程序)。原始文章的代码很容易理解。


0

0

我认为PrivateBinPath配置不是必需的,除此之外,你不需要使用DLL路径,而是应该使用程序集的完全限定名称作为第一个参数;尝试一下:

AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
        typeof(AssemblyLoader).Assembly.FullName,
        typeof(AssemblyLoader).FullName);

1
答案错误。CreateInstanceFromAndUnwrap()的第一个参数是路径和文件名,而不是程序集名称。然而,CreateInstanceAndUnwrap()的第一个参数是程序集名称,但这并不能帮助提问者,因为它只会解析到相同的路径和文件名。 - Timwi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接