ApplicationManager.CreateObject 无法在新 AppDomain 中加载程序集
我正在尝试开发一个 Web 应用程序,该应用程序根据每个请求调度(Dispatcher)到另一个 Web 应用程序的多个版本。为此,我使用 ApplicationManager.CreateObject 来创建新的 AppDomains 运行有问题的 Web 应用程序,但新的应用程序域似乎无法加载调度程序的 DLL(我正在将 DLL 复制到 Web 应用程序的 bin 目录,所以我很确定它在那里)。
var version = "version";
var path = @"C:\code\devel\webapp";
// Copy host assembly to target webapp so that 'Host' is available
var assembly = Assembly.GetExecutingAssembly().Location;
var target = path + "\\bin\\" + Path.GetFileName(assembly);
File.Copy(assembly, target, true);
var manager = ApplicationManager.GetApplicationManager();
var obj = manager.CreateObject(version, typeof(Host), "/", path, true, true);
这是融合日志:
Assembly manager loaded from: c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
Running under executable C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\9.0\WebDev.WebServer.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = FOOBAR\aaron
LOG: DisplayName = Dispatcher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/Dispatcher.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/Dispatcher/Dispatcher.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/Dispatcher.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/Dispatcher/Dispatcher.EXE.
Appbase 似乎指向开发服务器的根目录,而不是传递给 ApplicationManager.CreateObject 的路径,并且它似乎只搜索开发服务器下的目录,这看起来很奇怪。关于如何让新的 AppDomain 在 Web 应用程序的根目录而不是在开发服务器下搜索 DLL,有什么想法吗?
I'm trying to develop a web application that dispatch (Dispatcher) to multiple versions of another webapp on a per-request basis. To to that end, I'm using ApplicationManager.CreateObject to create new AppDomains running the web app in question, but the new app domains seem to be failing to load the Dispatcher's DLL (and I'm copying the DLL over to the web app's bin directory, so I'm pretty sure it's there).
var version = "version";
var path = @"C:\code\devel\webapp";
// Copy host assembly to target webapp so that 'Host' is available
var assembly = Assembly.GetExecutingAssembly().Location;
var target = path + "\\bin\\" + Path.GetFileName(assembly);
File.Copy(assembly, target, true);
var manager = ApplicationManager.GetApplicationManager();
var obj = manager.CreateObject(version, typeof(Host), "/", path, true, true);
Here's the fusion log:
Assembly manager loaded from: c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
Running under executable C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\9.0\WebDev.WebServer.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = FOOBAR\aaron
LOG: DisplayName = Dispatcher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/Dispatcher.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/Dispatcher/Dispatcher.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/Dispatcher.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/9.0/Dispatcher/Dispatcher.EXE.
The Appbase seems to be pointing at the root of the development server, rather than the path passed in to ApplicationManager.CreateObject and it only seems to be searching directories under the development server which seems strange. Any ideas on how to make the new AppDomain search for the DLL in the web app's root rather than under the development server?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来(至少在我们的情况下)这是错误的方法:使用反向代理是正确的方法。
反向代理的优点是它们是 HTTP 体系结构中的一种“模式”,并且它们使我们不必确保 ASP.NET 运行时在运行实际 Web 应用程序的 AppDomain 中真正正确配置。
我们目前正在研究 ProxyMachine,它是一个高度可配置的 TCP 反向代理,GitHub 似乎已经取得了一些成功。
It looks like (at least in our situation) this is the wrong way to go: Using a reverse proxy being the right way.
Reverse proxies have the advantage that they are a "pattern" in HTTP architecture and they save us from having to make sure that the ASP.NET runtime is really configured properly in the AppDomains running the actual web app.
We're currently looking at ProxyMachine which is a highly configurable TCP reverse proxy that GitHub seems to have had some success with.