.net AppDomains和ConfigSection
我们在.NET3.5应用程序中使用CSLA(一个相当古老的版本),并且我们为一些用户使用它的NetRun应用程序加载。对于那些不熟悉NetRun的人,NetRun.exe基本上是安装在用户计算机上的应用程序“运行程序”(例如到c:\Program Files\NetRun\NetRun.exe)。用户只需启动NetRun.exe即可启动应用程序 NetRun.exe的作用如下: (1) 创建新的AppDomainSetup.net AppDomains和ConfigSection,.net,configuration,appdomain,.net,Configuration,Appdomain,我们在.NET3.5应用程序中使用CSLA(一个相当古老的版本),并且我们为一些用户使用它的NetRun应用程序加载。对于那些不熟悉NetRun的人,NetRun.exe基本上是安装在用户计算机上的应用程序“运行程序”(例如到c:\Program Files\NetRun\NetRun.exe)。用户只需启动NetRun.exe即可启动应用程序 NetRun.exe的作用如下: (1) 创建新的AppDomainSetup Dim setupDomain As New AppDomainSetu
Dim setupDomain As New AppDomainSetup()
setupDomain.ApplicationBase = CurrentDomainPath() ' this will be C:\Program Files\NetRun\
setupDomain.ConfigurationFile = "http://www.ourdomain.com/TheApp.xml" ' The app.config file is actually named TheApp.xml on the server because it has NetRun-specific config settings that don't belong in the standard TheApp.config that is used when the app is running directly from the server.
' create new application domain
Dim newDomain As AppDomain = AppDomain.CreateDomain("TheApp", Nothing, setupDomain)
(2) 然后使用该AppDomainSetup创建一个新的AppDomain
Dim setupDomain As New AppDomainSetup()
setupDomain.ApplicationBase = CurrentDomainPath() ' this will be C:\Program Files\NetRun\
setupDomain.ConfigurationFile = "http://www.ourdomain.com/TheApp.xml" ' The app.config file is actually named TheApp.xml on the server because it has NetRun-specific config settings that don't belong in the standard TheApp.config that is used when the app is running directly from the server.
' create new application domain
Dim newDomain As AppDomain = AppDomain.CreateDomain("TheApp", Nothing, setupDomain)
(3) 然后,NetRun.Launcher(一个launch helper类——主要用于普通启动屏幕)通过以下方式在新AppDomain中实例化:
' create launcher object in new appdomain
Dim launcher As Launcher = CType(newDomain.CreateInstanceAndUnwrap("NetRun", "NetRun.Launcher"), Launcher)
(4) 然后,午餐助手类通过在新AppDomain中运行应用程序
' use launcher object from the new domain to launch the remote app in that appdomain
launcher.RunApp()
(5) 在经历了所有的闪屏之后,应用程序最终通过
Dim ass = Assembly.LoadFrom("http://www.ourdomain.com/TheApp.exe")
ass.EntryPoint.Invoke(ass.EntryPoint, Nothing)
因此,概括地说,实际运行的应用程序的AppDomain的ApplicationBase是C:\Program Files\NetRun\,而实际应用程序的入口点位于“”。到目前为止,一切顺利
应用程序本身,除了app.exe之外,还依赖于ALibrary.dll。到目前为止,这对我们非常有效。即使ALibrary.dll的配置项被拉入app.xml文件中,这些配置项也始终可以正常读取(并继续这样做)
在即将发布的版本中,我们添加了一个新的自定义配置文件部分,该部分在ALibrary.dll中定义。我们将新的部分添加到app.xml和app.config文件中
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.Applicat...">
<section name="TheApp.My.MySettings" type="System.Configuration.ClientSettingsS..."/>
<section name="ALibrary.My.MySettings" type="System.Configuration.ClientSettingsS..."/>
</sectionGroup>
<!-- NEW CONFIG SECTION -->
<section name="fixedPriceExceptionModel" type="ALibrary.Configuration.FixedPrices.FixedPriceExceptionModelSection, ALibrary"/>
</configSections>
我们得到以下例外情况:
在创建时出错
的配置节处理程序
fixedPriceExceptionModel:无法
加载文件或程序集“ALibrary”或
它的一个依赖项。系统
找不到指定的文件。
(
第8行)
做一些研究,这是因为.NET配置库的汇编解析器在所有常见的地方都在寻找ALibrary.dll;ApplicationBase、特定子目录、.NET核心目录,然后是GAC。不幸的是,ALibrary.dll永远不会在这些位置中找到。如果此应用程序直接在服务器上运行,而不使用NetRun,则应用程序不会引发异常并正确读取配置部分
我尝试过的一件事是以不同的方式设置AppDomainSetup,因为它的ApplicationBase将设置为,但随后对CType(newDomain.CreateInstanceAndUnwrap(“NetRun”、“NetRun.Launcher”)、Launcher)的调用会爆炸,因为NetRun.exe不在服务器上
这可能有很多需要理解的地方,我希望我描述得足够好(并且没有让你感到厌烦)。也许没有简单的解决方案,但我已经用尽了我在这方面的有限知识,希望这里的其他人可以有神奇的修复,让我在NetRun和local中运行应用程序时能够可靠地访问自定义配置部分。据我所知,这个问题,问题是,代码在客户机上运行,而不存在程序集,因为它们是从服务器加载的 知道这一点,您有两个选择:
1.拼命用现有代码寻找解决方案;)
2.不使用自定义配置节处理程序 就我个人而言,我赞成第二条 与使用ALibrary.Configuration.FixedPrices.FixedPriceExceptionModelSection作为配置节处理程序不同(这会导致异常,因为在客户端上找不到此类型),请像其他节一样使用默认的System.Configuration.ClientSettingsSection-这是.NET Framework的一部分,因此在客户端上没有问题。之后,为所需的配置类创建一个工厂(如果您确实需要强类型),该工厂将逐步读取配置,并创建FixedPriceExceptionModel对象,该对象填充数据并可供任何需要它的对象使用
如果我误解了这个问题,请告诉我。我认为这永远不会像您所介绍的那样有效 这行代码可以工作,因为
LoadFrom
是一种神奇的方法,它可以在特定位置查找程序集及其任何依赖项。TheApp.exe及其DLL从以下magic LoadFrom上下文加载:
Dim ass = Assembly.LoadFrom("http://www.ourdomain.com/TheApp.exe")
但是,配置节程序集加载失败,因为加载它的.NET framework代码(可能)使用的是普通的assembly.load
调用,该调用与原始LoadFrom
调用断开,并且不知道www.ourdomain.com。有多种方法可以将其他目录获取到.NET程序集搜索路径中,但这些都是相对于应用程序域基目录获取的
正如您所指出的,让
Assembly.Load
了解www.ourdomain.com的唯一其他方法是更改应用程序域的基本目录。在这种情况下,将NetRun.exe部署到web服务器上是否很糟糕?我意识到这是对一个已经回答的问题的很晚的回答,但我已经通过使用元素成功地实现了这一点
示例(如果需要,也可以使用file:///url表单):
不,您根本没有误解问题所在-现场。是的,即使我设置了ShadowCopy并实际拉下文件,但由于ShadowCopy将程序集文件展开的方式,它也没有帮助。你的#2是一个显而易见的解决方案,但我会坚持等待有人拿出一颗神奇的子弹,让你的#1选项成为现实:)看到这样的失败真是让人失望:(感谢你的回答。我最终选择了#2:(只是将我的配置XML放到它自己的文件中,然后自己加载/解析它。