与AppDomain.Load有趣的错误() [英] Interesting error with AppDomain.Load()

查看:213
本文介绍了与AppDomain.Load有趣的错误()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一种方法,在运行时编译程序集并加载它们。基本目的是将它们存储在数据库中未在盘上。所以我写了一些code,但看到一个有趣的情况。这是我的code:

I am trying to find a way to compile assemblies at runtime and load them. Basic intention is to store them in a database not on the disc. So I wrote some code but saw an interesting situation. Here is my code:

//SumLib
namespace SumLib
{
    public class SumClass
    {
        public static int Sum(int a, int b)
        {
            return a + b;
        }
    }
}


// Console app
class Program
{

    public static void AssemblyLoadEvent(object sender, AssemblyLoadEventArgs args)
    {

        object[] tt = { 3, 6 };
        Type typ = args.LoadedAssembly.GetType("SumLib.SumClass");
        MethodInfo minfo = typ.GetMethod("Sum");
        int x = (int)minfo.Invoke(null, tt);
        Console.WriteLine(x);
    }

    static void Main(string[] args)
    {

        AppDomain apd = AppDomain.CreateDomain("newdomain", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation);
        apd.AssemblyLoad += new AssemblyLoadEventHandler(AssemblyLoadEvent);

        FileStream fs = new FileStream("Sumlib.dll", FileMode.Open);
        byte[] asbyte = new byte[fs.Length];
        fs.Read(asbyte, 0, asbyte.Length);
        fs.Close();
        fs.Dispose();

//      File.Delete("Sumlib.dll");

        apd.Load(asbyte);

        Console.ReadLine();
    }
}

在code用的删除的行注释掉,如果我取消它,应用程序域加载程序集, AssemblyLoadEvent()方法运行,我看到控制台上的9号,但该方法是在 apd.Load()抛出一个错误:无法加载文件或程序。这是完全合理的。

The code runs perfectly with the delete line is commented out, If I uncomment it, the application domain loads the assembly, AssemblyLoadEvent() method runs, I see a number 9 on the console, but when the method is over apd.Load() throws an error : "Could not load file or assembly." which is perfectly reasonable.

现在的问题是:如何 AssemblyLoadEvent()方法,无需光盘上的汇编文件运行?

The question is: how can AssemblyLoadEvent() method run without the assembly file on the disc?

如果该方法以某种方式与原始二进制数据的帮助下运行,那么有没有那个应用程序域完成的 load()的任何方式方法成功地?

If the method somehow runs with the help of raw binary data then is there any way that appdomain finishes the Load() method succesfully?

推荐答案

所以,你要加载从byte []的一个组件,并调用的方法。我不建议你没有(与AssemblyLoad事件的工作)的方式,因为它会要求每一个相关性。

So you are trying to load an assembly from a byte[] and call a method. I do not recommend the way you did (working with the AssemblyLoad event), since it will be called for every dependencies.

@Jester是对有关从父域加载使用的组件负载()。为了解决这个问题,我建议使用包装类是这样的:

@Jester is right about loading an assembly using Load() from a parent domain. To correct this, I suggest to use a wrapper class like this:

// Console app 
class Program 
{  
    public class AssemblyLoader : MarshalByRefObject
    {
        public void LoadAndCall(byte[] binary)
        {
            Assembly loadedAssembly = AppDomain.CurrentDomain.Load(binary);
            object[] tt = { 3, 6 };
            Type typ = loadedAssembly.GetType("SumLib.SumClass");
            MethodInfo minfo = typ.GetMethod("Sum", BindingFlags.Static | BindingFlags.Public);
            int x = (int)minfo.Invoke(null, tt);
            Console.WriteLine(x);
        }
    }

    static void Main()
    {
        AppDomain apd = AppDomain.CreateDomain("newdomain", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation);
        FileStream fs = new FileStream("Sumlib.dll", FileMode.Open);
        byte[] asbyte = new byte[fs.Length];
        fs.Read(asbyte, 0, asbyte.Length);
        fs.Close();
        fs.Dispose();
        File.Delete("Sumlib.dll");    

        AssemblyLoader loader = (AssemblyLoader)apd.CreateInstanceAndUnwrap(typeof(AssemblyLoader).Assembly.FullName, typeof(AssemblyLoader).FullName);
        loader.LoadAndCall(asbyte);
        Console.ReadLine();
      }
}  

这篇关于与AppDomain.Load有趣的错误()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆