.net AppDomains和ConfigSection

.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

我们在.NET3.5应用程序中使用CSLA(一个相当古老的版本),并且我们为一些用户使用它的NetRun应用程序加载。对于那些不熟悉NetRun的人,NetRun.exe基本上是安装在用户计算机上的应用程序“运行程序”(例如到c:\Program Files\NetRun\NetRun.exe)。用户只需启动NetRun.exe即可启动应用程序

NetRun.exe的作用如下:

(1) 创建新的AppDomainSetup

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放到它自己的文件中,然后自己加载/解析它。