当类在另一个命名空间中时编组.net对象

本文关键字:net 对象 另一个 命名空间 | 更新日期: 2023-09-27 18:12:15

我在。net Windows Service中跨应用程序域编组对象时遇到问题。

我创建了两个跨应用程序域封送对象并通过代理MarshalByRefObject运行代码的应用程序

第一个应用程序是一个简单的概念证明,因为我没有太多跨应用程序域的编组经验。它包含一个项目,其中MarshalByRefObject定义在与项目其余部分相同的名称空间中。这个应用程序工作得很好,使用的代码几乎与我的另一个应用程序相同。主要区别在于,我在第二个应用程序中编组的类是在另一个命名空间中定义的。

另一个项目更复杂,它是一个有多个项目的Windows服务。主Windows服务加载一个库来执行封送。Marshal目标类型的类类型是在另一个库中定义的,因此我使用完全限定的名称空间/类名。

我面临的问题是,当它到达下面的最后一行代码时,它抛出一个异常:

无法从程序集ProductNameService中加载companyname . productgroup . businessojects . productname . marshalbyrefscriptcompiler ,其中product name是主要的Windows Service类。

代码:

AppDomain compilerDomain = null;
AppDomainSetup compilerDomainSetup;
CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler scriptCompiler;
...
// Setup a seperate AppDomain 
compilerDomainSetup = new AppDomainSetup();
exeAssembly = Assembly.GetEntryAssembly().FullName;
compilerDomainSetup.ApplicationBase = System.Environment.CurrentDirectory;
compilerDomainSetup.DisallowBindingRedirects = false;
compilerDomainSetup.DisallowCodeDownload = true;
compilerDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
compilerDomain = AppDomain.CreateDomain("LiveLinkCSScriptDomain", null, compilerDomainSetup);
// Create an instance of the MarshalByRefScriptCompiler in the other AppDomain
scriptCompiler = (CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler)compilerDomain.CreateInstanceAndUnwrap(exeAssembly, typeof(CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler).FullName);

我已经对这个异常进行了研究,几乎所有我发现的都说这是DLL版本控制的问题,但是我的DLL不在GAC中,并且没有安装其他版本。我正在做一个干净的构建和安装服务与installutil。

我使用MSDN文档作为创建执行封送的代码的指南

我想知道加载MarshalByRefScriptCompiler是否有问题,因为类型在另一个库中。我能够在一个简单的winforms应用程序中创建一个MarshalByRefScriptCompiler,但我在我的windows服务中得到例外。

任何提示或见解将不胜感激!

当类在另一个命名空间中时编组.net对象

我应该能帮助你。我最近花了很多时间研究不同的跨应用域封送问题(如何跨应用域将引用作为方法参数传递?)我的第一个建议是尝试使用CreateInstanceFromAndUnwrap而不是CreateInstanceAndUnwrap

我对这一行也有点警惕:

compilerDomainSetup.ApplicationBase = System.Environment.CurrentDirectory;

如何创建您的原始AppDomain ?您是否托管在IIS中,在这种情况下,您的原始AppDomain将使用ShadowCopy?所有dll都在一个文件夹中吗?

编辑:

总而言之,如果你的compilerDomainSetup. exe . exe,你可以使用CreateInstanceAndUnwrap。ApplicationBase被设置为包含你的dll的目录,你传入正确的第一个参数(例如typeof(MarshalByRefScriptCompiler). assembly . fullname)。

或者,您可以使用CreateInstanceFromAndUnwrap并将包含程序集的位置(例如typeof(MarshalByRefScriptCompiler). assembly . location)作为第一个参数。

作为起点,您可以尝试Process Monitor来确定它试图从哪里加载丢失的类型。这很可能就像在错误的目录中查找程序集一样简单。