编程语言
首页 > 编程语言> > c#-在为aspx页面编译动态程序集期间未触发AssemblyResolve事件

c#-在为aspx页面编译动态程序集期间未触发AssemblyResolve事件

作者:互联网

这真的让我很生气.开始:

我的目标是在运行时加载包含嵌入式aspx,ascx等的程序集.我还想不将程序集文件锁定在磁盘上,这样我就可以在运行时更新该文件而不必重新启动应用程序(我知道这将保留以前的版本).

为此,我编写了一个可以解决问题的虚拟路径提供程序.我已订阅CurrentDomain.AssemblyResolve事件,以便将框架重定向到我的程序集.

问题是当框架尝试为aspx页面编译动态程序集时,我得到以下信息:

编译器错误消息:CS0400:在全局名称空间中找不到类型或名称空间名称’Pages'(是否缺少程序集引用?)

源错误:
 公共类app_resource_pages__version_1_0_0_0__culture_neutral__publickeytoken_null_default_aspx:global :: Pages._Default,System.Web.SessionState.IRequiresSessionState,System.Web.IHttpHandle

我注意到,如果我用Assembly.Load(AssemblyName)或Assembly.LoadFrom(filename)加载程序集,则不会得到上述错误.如果我用Assembly.Load(byte [])加载它(以便不锁定它),则会引发异常,但我的AssemblyResolve处理程序在被调用时会正确返回程序集(被调用一次).

所以我猜想它在框架解析asp标记时被调用一次,而在它试图为aspx页面创建动态程序集时不被调用.

解决方法:

我不确定是什么导致缺少程序集引用,但是如果我们稍微退后一步,使程序按预期工作,那么我们必须解决另一个问题.这个问题是加载组件的锁定. .Net框架始终锁定加载的程序集.您可以更新bin文件夹中的dll文件的原因实际上是一个技巧.您会看到,AppDomain具有一个名为ShadowCopyDirectories的不错的属性,该属性指示在加载程序集时将被阴影复制的目录.因此,通过更改影子复制的目录列表,您可以从任何文件夹加载而不锁定程序集:

    protected const string ApplicationAssembliesFolder = "~/Assemblies";

    protected void Application_Start(object sender, EventArgs e)
    {
        var assembliesPath = Server.MapPath(ApplicationAssembliesFolder);

        AppDomain.CurrentDomain.SetShadowCopyPath(
            AppDomain.CurrentDomain.SetupInformation.ShadowCopyDirectories + 
            Path.PathSeparator + assembliesPath);

        Assembly.LoadFrom(
            Path.Combine(assembliesPath, "Example.dll"));
    }

标签:reflection,assemblies,loading,c
来源: https://codeday.me/bug/20191024/1917732.html