首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AssemblyResolve不会触发

AssemblyResolve不会触发
EN

Stack Overflow用户
提问于 2011-04-05 15:41:03
回答 3查看 3.9K关注 0票数 0

我有一个asp.net应用程序。我想动态加载一些程序集。

这是我在应用程序启动时的代码

代码语言:javascript
复制
    protected void Application_Start(Object sender, EventArgs e)
        {
            LoadPrivateAssemblies();
        }
    private static void LoadPrivateAssemblies()
        {
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve;

            Assembly.Load("MyDLL");
        }
    static Assembly CurrentDomainAssemblyResolve(object sender, ResolveEventArgs args)
        {
            //loads and returns assembly successfully.
        }

这段代码工作得很好,除非嵌套的c#代码从asp.net页面内的动态dll调用类(不是代码隐藏)。

示例:

代码语言:javascript
复制
<%if(MyDLL.TestObject.Value){%>white some ting<%}%>

我现在该怎么做?

我想如果我知道什么时候创建了一个新的AppDomain,它可能会解决我的问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-05 19:12:52

我发现这个问题是因为Assembly.Load(bytes);没有持久化appdomain中的程序集。有没有人知道如何在appdomain中使用Assembly.Load(bytes);持久化加载的程序集?

最后,我决定切换到LoadFile方法,而不是load。

编辑

最后,我从Assemly.Load(byte[])切换到了Assembly.LoadFile(string)

但它本身并没有纠正这个问题。我已经将<%@Assembly name="MyDLL"%>添加到所有标记了C#代码的ASPX文件中。

这解决了我的问题。

感谢你的回答。我已经投票选出了对我有帮助的答案,但我不能接受你的解决方案,因为没有人不够完整。

票数 -1
EN

Stack Overflow用户

发布于 2011-04-05 23:06:02

我真的觉得你找错人了。

Assembly.Load(byte[])确实在应用程序域中“持久化”程序集-否则,它还能做什么呢?

为了说明它确实是这样做的,请尝试这样做:

创建一个包含一个控制台应用程序和一个名为OtherAssembly的类库的解决方案。

在类库OtherAssembly中,添加一个类:

代码语言:javascript
复制
namespace OtherAssembly
{
    public class Class1
    {
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

在控制台应用程序中,使用以下代码作为您的程序:

代码语言:javascript
复制
public class Program
{
    static void Main(string[] args)
    {
        try
        {
            using (var fs = new FileStream("OtherAssembly.dll", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                var buffer = new byte[fs.Length];
                // load my assembly into a byte array from disk
                fs.Read(buffer, 0, (int) fs.Length);

                // load the assembly in the byte array into the current app domain
                AppDomain.CurrentDomain.Load(buffer);
            }

            // get my type from the other assembly that we just loaded
            var class1 = Type.GetType("OtherAssembly.Class1, OtherAssembly");

            // create an instance of the type
            var class1Instance = class1.GetConstructor(Type.EmptyTypes).Invoke(null);

            // find and invoke the HelloWorld method.
            var hellowWorldMethod = class1.GetMethod("HelloWorld");
            Console.WriteLine(hellowWorldMethod.Invoke(class1Instance, null));
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        finally
        {
            Console.ReadLine();
        }
    }
}

不要从主程序程序集中引用OtherAssembly,而是编译解决方案并手动将OtherAssembly.dll放到主程序的bin文件夹中。

运行主程序。它输出"Hello World",只有当程序集被加载并保留在内存中时,它才能这样做。你会注意到,我一直非常小心,没有给Visual Studio或C#任何提示来加载这个OtherAssembly。未添加引用,该类型未在C#中显式引用。

你需要重新审视你的问题。

编辑:为了回应您对这不是ASP.NET应用程序的评论

好的-我已经将我的主程序移到了一个ASP.NET网页上,并尝试从代码后台和标记访问程序集-它在这两种情况下都有效。我肯定你在这里遗漏了一些东西--这个方法的行为--它的工作是将程序集加载到当前的应用程序域--在ASP.NET场景中是不同的,这是没有意义的。

在我看来,至少有两件事需要调查:

  • 如果它真的是在每次调用时创建的新应用程序域,那只会是因为您的应用程序中存在未处理的异常。诊断此问题的最快方法是使用SysInternals Process Explorer。启动它-将.Net ->总AppDomains添加到列列表中,并在运行应用程序时查看您的进程(IIS进程或web dev)的应用程序域数。如果这在每次调用时增加,你就会遇到未处理的异常,它会拆除一个AppDomain并强制创建另一个。
  • 你确定这个程序集真的在被加载吗?在将字节数组传递给Assembly.Load时,还要尝试使用FileStream.Write将其写出到磁盘。在Reflector或其他类似工具中打开该文件。这是您期望的程序集吗?它是否真的被加载了,或者它是一个空/损坏的数组?

我不是想争辩,但这真的让人感觉你找错了问题的原因。

票数 2
EN

Stack Overflow用户

发布于 2011-04-05 16:55:28

我想如果我知道一个新的AppDomain是什么时候创建的,它可能会解决我的问题

您应该使用AssemblyLoad事件。当程序集解析失败时发生AssemblyResolved

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5548691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档