如何使用加载的DLLS程序集引用另一个程序集的方法?

时间:2012-03-12 08:42:19

标签: c# .net dllimport appdomain

我有两个装配。我将classlib1添加到classLib2引用中。像那样: enter image description here

我用过它:



namespace ClassLibrary2
{
    public class Class1
    {
        public Class1()
        {

        }

        public int GetSum(int a , int b)
        {
            try
            {
                ClassLibrary1.Class1 ctx = new ClassLibrary1.Class1();
                return ctx.Sum(a, b);
            }
            catch
            {
                return -1;
            }

        }
    }
}

我还想使用AppDomain动态加载(class1lib和Class2Lib)另一个C#项目。  


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Reflection.Emit;

namespace WcfService3 { public partial class Default : System.Web.UI.Page { public static ArrayList arryFiles { get; set; } protected void Page_Load(object sender, EventArgs e) {

    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        arryFiles = new ArrayList();
        List<byte[]> binaryList = new List<byte[]>();
        // string fileName = @"S:\Source\Yusuf.Karatoprak\plugin\ClassLibrary1.dll";
        DirSearch(@"S:\Source\Yusuf.Karatoprak\plugin");
        foreach (var filePath in arryFiles)
        {
            FileStream fileStream = File.OpenRead(filePath.ToString());
            byte[] buffer = new byte[fileStream.Length];
            fileStream.Read(buffer, 0, Convert.ToInt32(fileStream.Length));
            fileStream.Dispose();
            binaryList.Add(buffer);
            //Assembly[] assBefore = AppDomain.CurrentDomain.GetAssemblies();

            //AppDomain.CurrentDomain.Load(buffer);

            //Assembly[] assAfter = AppDomain.CurrentDomain.GetAssemblies();

            //Type t = Type.GetType("ClassLibrary1.Class1,ClassLibrary1");
        }

        new AssemblyLoader().LoadAndCall(binaryList);
    }
    static void DirSearch(string sDir)
    {
        try
        {
            foreach (string f in Directory.GetFiles(sDir, "*.dll"))
            {
                if (!arryFiles.Contains(f))
                    arryFiles.Add(f);
            }
            foreach (string d in Directory.GetDirectories(sDir))
            {
                if (d != null)
                {
                    foreach (string f in Directory.GetFiles(d, "*.dll"))
                    {
                        if (!arryFiles.Contains(f))
                            arryFiles.Add(f);
                    }
                    DirSearch(d);
                }
                else
                    break;
            }

        }
        catch (System.Exception excpt)
        {
            throw new Exception(excpt.Message);

        }
    }
}

public class AssemblyLoader : MarshalByRefObject
{
    public void LoadAndCall(List<byte[]> binaryList)
    {
        Assembly loadedAssembly=null;
        Assembly[] assBefore = AppDomain.CurrentDomain.GetAssemblies();
        foreach (byte[] binary in binaryList)
        {
            loadedAssembly = AppDomain.CurrentDomain.Load(binary);
        }
        Assembly[] assAfter = AppDomain.CurrentDomain.GetAssemblies();
        object[] tt = { 3, 6 };
        Type type = loadedAssembly.GetType("ClassLibrary2.Class1");
        object loaded = loadedAssembly.CreateInstance("ClassLibrary2.Class1", true, BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance, null, new object[] { }, null, null);
       // object obj = Activator.CreateInstance(type);



        ObjectCreateMethod inv = new ObjectCreateMethod(type); //Specify Type
        Object obj = inv.CreateInstance();

        MethodInfo minfo = type.GetMethod("GetSum", BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance);
        int x = (int)minfo.Invoke(obj, new Object[] { 3, 6 });
        Console.WriteLine(x);
    }
}

public class ObjectCreateMethod
{
    delegate object MethodInvoker();
    MethodInvoker methodHandler = null;

    public ObjectCreateMethod(Type type)
    {
        CreateMethod(type.GetConstructor(Type.EmptyTypes));
    }

    public ObjectCreateMethod(ConstructorInfo target)
    {
        CreateMethod(target);
    }

    void CreateMethod(ConstructorInfo target)
    {
        DynamicMethod dynamic = new DynamicMethod(string.Empty,
                    typeof(object),
                    new Type[0],
                    target.DeclaringType);
        ILGenerator il = dynamic.GetILGenerator();
        il.DeclareLocal(target.DeclaringType);
        il.Emit(OpCodes.Newobj, target);
        il.Emit(OpCodes.Stloc_0);
        il.Emit(OpCodes.Ldloc_0);
        il.Emit(OpCodes.Ret);

        methodHandler = (MethodInvoker)dynamic.CreateDelegate(typeof(MethodInvoker));
    }

    public object CreateInstance()
    {
        return methodHandler();
    }
}

} protected void Button1_Click(object sender, EventArgs e) { arryFiles = new ArrayList(); List<byte[]> binaryList = new List<byte[]>(); // string fileName = @"S:\Source\Yusuf.Karatoprak\plugin\ClassLibrary1.dll"; DirSearch(@"S:\Source\Yusuf.Karatoprak\plugin"); foreach (var filePath in arryFiles) { FileStream fileStream = File.OpenRead(filePath.ToString()); byte[] buffer = new byte[fileStream.Length]; fileStream.Read(buffer, 0, Convert.ToInt32(fileStream.Length)); fileStream.Dispose(); binaryList.Add(buffer); //Assembly[] assBefore = AppDomain.CurrentDomain.GetAssemblies(); //AppDomain.CurrentDomain.Load(buffer); //Assembly[] assAfter = AppDomain.CurrentDomain.GetAssemblies(); //Type t = Type.GetType("ClassLibrary1.Class1,ClassLibrary1"); } new AssemblyLoader().LoadAndCall(binaryList); } static void DirSearch(string sDir) { try { foreach (string f in Directory.GetFiles(sDir, "*.dll")) { if (!arryFiles.Contains(f)) arryFiles.Add(f); } foreach (string d in Directory.GetDirectories(sDir)) { if (d != null) { foreach (string f in Directory.GetFiles(d, "*.dll")) { if (!arryFiles.Contains(f)) arryFiles.Add(f); } DirSearch(d); } else break; } } catch (System.Exception excpt) { throw new Exception(excpt.Message); } } } public class AssemblyLoader : MarshalByRefObject { public void LoadAndCall(List<byte[]> binaryList) { Assembly loadedAssembly=null; Assembly[] assBefore = AppDomain.CurrentDomain.GetAssemblies(); foreach (byte[] binary in binaryList) { loadedAssembly = AppDomain.CurrentDomain.Load(binary); } Assembly[] assAfter = AppDomain.CurrentDomain.GetAssemblies(); object[] tt = { 3, 6 }; Type type = loadedAssembly.GetType("ClassLibrary2.Class1"); object loaded = loadedAssembly.CreateInstance("ClassLibrary2.Class1", true, BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance, null, new object[] { }, null, null); // object obj = Activator.CreateInstance(type); ObjectCreateMethod inv = new ObjectCreateMethod(type); //Specify Type Object obj = inv.CreateInstance(); MethodInfo minfo = type.GetMethod("GetSum", BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance); int x = (int)minfo.Invoke(obj, new Object[] { 3, 6 }); Console.WriteLine(x); } } public class ObjectCreateMethod { delegate object MethodInvoker(); MethodInvoker methodHandler = null; public ObjectCreateMethod(Type type) { CreateMethod(type.GetConstructor(Type.EmptyTypes)); } public ObjectCreateMethod(ConstructorInfo target) { CreateMethod(target); } void CreateMethod(ConstructorInfo target) { DynamicMethod dynamic = new DynamicMethod(string.Empty, typeof(object), new Type[0], target.DeclaringType); ILGenerator il = dynamic.GetILGenerator(); il.DeclareLocal(target.DeclaringType); il.Emit(OpCodes.Newobj, target); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ret); methodHandler = (MethodInvoker)dynamic.CreateDelegate(typeof(MethodInvoker)); } public object CreateInstance() { return methodHandler(); } }

为什么无法加载和异​​常错误返回给我:

enter image description here

enter image description here

查看内部异常:无法加载文件或程序集'ClassLibrary1但我加载了Classlib2 abd Classlib1。 class2依赖于classlib1如何使用classlib1方法我想在加载程序集后使用GetSum(int a,int b)方法:

2 个答案:

答案 0 :(得分:1)

不太确定是否可以将对另一个DLL的引用链接到程序集duriong动态负载。至少我不知道。但一般来说,

  • 如果您正在谈论插件,请不要将它们链接在一起。如果没有,没有任何理由有基于插件的系统。

  • 我会尝试检查主机应用的.NET Framework版本,关于它加载的插件。 可能某些版本冲突。

希望这有帮助。

答案 1 :(得分:1)

发现这有点similar question。处理解决事件似乎是最后的努力。如果你的选项用完了就试试吧。替换为您的S:\ Source \ Yusuf.Karatoprak \ plugin。您还可以尝试处理AppDomain.AssemblyLoad事件,以查看从二进制文件加载的内容。

@programmerist,干杯!