使用Assembly.Load(byte [])加载程序集时解析依赖项

时间:2016-06-16 04:56:15

标签: c#

我使用Assembly.Load(byte [])来加载程序集。这个加载的程序集在内部使用codeDomProvider.CompileAssemblyFromSource()来编译失败的代码,错误'类型或命名空间名称'< ClassName>'找不到(你错过了使用指令或汇编引用吗?)'。

对于要编译的代码中存在的引用,不会触发AppDomain.AssemblyResolve事件。

仅供参考:我正在尝试加载使用FileHelpers.dll的程序集,并调用ClassBuilder.ClassFromString函数。程序集加载因RunTimeCompilationException而失败。

我该如何解决这种依赖?

更新:

以下是我正在使用的代码

ctor()
{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve;
}

private Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
{
    AssemblyName assemblyName = new AssemblyName(args.Name);
    return LoadAssembly(assemblyName);
}

public Assembly GetAssembly(string assemblyFullName)
{
    AssemblyName assemblyName = new AssemblyName(assemblyFullName);

    Assembly assembly = LoadAssembly(assemblyName) ?? Assembly.Load(assemblyName);
}

private Assembly LoadAssembly(AssemblyName assemblyName)
{
    byte[] assemblyBytes = GetAssemblyBytes(); // Get assembly bytes from external source
    return Assembly.Load(assemblyBytes);
}

由于

佳日

1 个答案:

答案 0 :(得分:2)

您需要按照以下方式处理CurrentDomain.ResolveEventHandler事件,只要需要引用,就会触发此事件:

加载程序集的代码:

private void LoadAssem(){
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
//use File.ReadAllBytes to avoid assembly locking
    Assembly asm2 = Assembly.Load(File.ReadAllBytes("AssemblyPath"));
    }

一旦需要参考,它将调用以下事件:

 private static string asmBase;
//asmBase contains the folder where all your assemblies found.
        public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            //This handler is called only when the common language runtime tries to bind to the assembly and fails.

            //Retrieve the list of referenced assemblies in an array of AssemblyName.
            Assembly MyAssembly, objExecutingAssemblies;
            string strTempAssmbPath = "";
            objExecutingAssemblies = args.RequestingAssembly;
            AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

            //Loop through the array of referenced assembly names.
            foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
            {
                //Check for the assembly names that have raised the "AssemblyResolve" event.
                if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
                {
                    //Build the path of the assembly from where it has to be loaded.                
                    strTempAssmbPath = asmBase + "\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
                    break;
                }

            }
            //Load the assembly from the specified path.                    
            MyAssembly = Assembly.Load(File.ReadAllBytes(strTempAssmbPath));

            //Return the loaded assembly.
            return MyAssembly;
        }