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

标签 c# reflection assemblies loading

这个真的让我很生气。开始了:

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

为此,我编写了一个虚拟路径提供程序来实现这一目的。我已订阅 CurrentDomain.AssemblyResolve 事件,以便将框架重定向到我的程序集。

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

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

来源错误: 公共(public)类 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"));
    }

关于c# - 在为 aspx 页面编译动态程序集期间未触发 AssemblyResolve 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2842208/

相关文章:

c# - 如何在不存在的文件夹中自动创建文件?

c# - WPF 中绑定(bind)失败

c# - 如何将字节数组转换为xml?

java - 当前方法的完全限定方法名称

c# - 给定一个属性名称,我如何创建一个委托(delegate)来获取它的值

.net - 阻止将特定的程序集添加到我的工厂项目中?

java - Maven、Proguard 和装配问题

c# - 反转图形

.net - 如何在 .NET 中使用 Reflection 区分封闭类型参数和嵌套类型参数?

.net - .NET 中的程序集的物理位置在哪里?