我有一个consoleapp在一个新的appdomain中加载一个dll,我可以在该dll中调用一个方法。我希望能够再次调用该方法而无需重新加载dll。我希望能够在卸载appdomain之前加载多个dll并从其中任何一个调用方法。
using System;
using System.Reflection;
namespace Parent
{
public interface ILoader
{
int Execute(int arg1, int arg2);
}
public class Loader : MarshalByRefObject, ILoader
{
public int Execute(int arg1, int arg2)
{
byte[] test1 = System.IO.File.ReadAllBytes("C:\\Users\\username\\source\\repos\\Test\\Test\\bin\\Debug\\Test.dll");
Assembly test = Assembly.Load(test1);
foreach (Type type in test.GetTypes())
{
if (type.ToString().ToUpper() == "PROGRAM")
{
var o = Activator.CreateInstance(type);
Console.WriteLine("found Program");
MethodInfo method = type.GetMethod("math", new[] { typeof(int), typeof(int) });
var returnvalue = method.Invoke(o, new object[] { arg1, arg2 });
return (int)returnvalue;
}
return 0;
}
return 0;
}
}
class Program
{
static void Main(string[] args)
{
int arg1 = Convert.ToInt32(args[0]);
int arg2 = Convert.ToInt32(args[1]);
Console.WriteLine(args[0], args[1]);
var domain = AppDomain.CreateDomain("child");
var loader = (ILoader)domain.CreateInstanceAndUnwrap(typeof(Loader).Assembly.FullName, typeof(Loader).FullName);
Console.Out.WriteLine(loader.Execute(arg1, arg2));
//reloads appdomain I dont want that
Console.Out.WriteLine(loader.Execute(2, 3));
Console.ReadKey();
AppDomain.Unload(domain);
Console.WriteLine("Appdomain unloaded");
Console.ReadKey();
}
}
}
测试DLL,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Program
{
public static int math(int arg1, int arg2)
{
int a = arg1;
int b = arg2;
int c = a + b;
return c;
}
}
将domain
变量声明为static
函数之外的main
变量,因为您无法在函数内声明static
变量。一个static
变量在函数执行后没有删除它的数据 - 这就是为什么它被称为“静态”,因为它永远不会改变,就像一个常量而不像“动态”变量。
弄清楚了。必须创建第二个函数来加载二进制和if语句,如果它还不存在。对于那些查看appdomains的人我理解它的界面是共享的功能,让你调用加载到其他appdomain的类。
using Parent;
using System;
using System.Reflection;
namespace Parent
{
public interface ILoader
{
int ExecuteAssm(int arg1, int arg2);
byte[] Test();
}
public class Loader : MarshalByRefObject, ILoader
{
Assembly test1 = null;
byte[] test;
public byte[] Test()
{
byte[] test = System.IO.File.ReadAllBytes("C:\\Users\\username\\source\\repos\\Test\\Test\\bin\\Debug\\Test.dll");
return test;
}
public int ExecuteAssm(int arg1, int arg2)
{
if (test1 == null)
{
test = Test();
test1 = Assembly.Load(test);
}
foreach (Type type in test1.GetTypes())
if (type.ToString().ToUpper() == "PROGRAM")
{
MethodInfo method = type.GetMethod("math");
object o = test1.CreateInstance("math");
var returnint = method.Invoke(o, new object[] { arg1, arg2 });
Console.WriteLine(method);
Console.WriteLine(returnint);
return (int)returnint;
}
return 0;
}
}
//Type t = test1.GetType("Test.Class1");
//var methodInfo = t.GetMethod("math", new Type[] { typeof(int), typeof(int) });
//var o = Activator.CreateInstance(t);
//var result = MethodInfo.(o, new Type[] { 32, 32 });
}
class Program
{
static void Main(string[] args)
{
var domain = AppDomain.CreateDomain("child");
var loader = (ILoader)domain.CreateInstanceAndUnwrap(typeof(Loader).Assembly.FullName, typeof(Loader).FullName);
loader.ExecuteAssm(32, 32);
loader.ExecuteAssm(2, 2);
AppDomain.Unload(domain);
// int returnint = ILoader.ExecuteAssm(32, 32);
//Console.WriteLine(returnint);
}
}