C#-从.NET DLL(类库)执行代码而不引用它?
我试图找到一种方法,在我的应用程序启动后,我可以从.NETDLL执行代码。我在下面包含了一些伪代码,它们可能会试图解释我要做的事情。我知道这可能比我想象的要复杂得多C#-从.NET DLL(类库)执行代码而不引用它?,c#,class,dll,C#,Class,Dll,我试图找到一种方法,在我的应用程序启动后,我可以从.NETDLL执行代码。我在下面包含了一些伪代码,它们可能会试图解释我要做的事情。我知道这可能比我想象的要复杂得多 ClassLibrary myLibrary = new ClassLibrary("C:\\Users\\Admin\\Desktop\\myTestLibrary.dll"); myLibrary.executeMethod("showMessageMethod", arg1, arg2, arg3...); 这就是我想做的,
ClassLibrary myLibrary = new ClassLibrary("C:\\Users\\Admin\\Desktop\\myTestLibrary.dll");
myLibrary.executeMethod("showMessageMethod", arg1, arg2, arg3...);
这就是我想做的,尽管我知道这可能比那复杂得多
我还想明确地说,我确实理解,在你的项目中,你应该参考图书馆,等等。。。但我的项目要求我不要这样做
提前谢谢 您需要从磁盘加载程序集,如下所示:
Assembly myLibrary = System.Reflection.Assembly
.LoadFile("C:\\Users\\Admin\\Desktop\\myTestLibrary.dll");
之后,您将需要使用反射获得适当的类型并调用适当的方法。当您要调用的类实现在启动时引用的程序集中定义的接口时,这将是最方便的:
Type myClass = (
from type in myLibrary.GetExportedTypes()
where typeof(IMyInterface).IsAssignableFrom(type)
select type)
.Single();
var instance = (IMyInterface)Activator.CreateInstance(myClass);
instance.executeMethod("showMessageMethod", arg1, arg2, arg3...);
第一个解决方案是使用:
Assembly asm = Assembly.LoadFrom(path);
第二个是:您正在寻找的可能是一种在运行时动态加载程序集的方法
请看此视频:我希望下面的代码示例对您有所帮助
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace zielonka.co.uk.stackoverflow.examples.Reflection
{
class Program
{
static void Main(string[] args)
{
// dynamically load assembly from file Test.dll
Assembly testAssembly = Assembly.LoadFile(@"c:\Test.dll");
// get type of class Calculator from just loaded assembly
Type calcType = testAssembly.GetType("Test.Calculator");
// create instance of class Calculator
object calcInstance = Activator.CreateInstance(calcType);
// get info about property: public double Number
PropertyInfo numberPropertyInfo = calcType.GetProperty("Number");
// get value of property: public double Number
double value = (double)numberPropertyInfo.GetValue(calcInstance, null);
// set value of property: public double Number
numberPropertyInfo.SetValue(calcInstance, 10.0, null);
// get info about static property: public static double Pi
PropertyInfo piPropertyInfo = calcType.GetProperty("Pi");
// get value of static property: public static double Pi
double piValue = (double)piPropertyInfo.GetValue(null, null);
// invoke public instance method: public void Clear()
calcType.InvokeMember("Clear",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
null, calcInstance, null);
// invoke private instance method: private void DoClear()
calcType.InvokeMember("DoClear",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
null, calcInstance, null);
// invoke public instance method: public double Add(double number)
double value = (double)calcType.InvokeMember("Add",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
null, calcInstance, new object[] { 20.0 });
// invoke public static method: public static double GetPi()
double piValue = (double)calcType.InvokeMember("GetPi",
BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
null, null, null);
// get value of private field: private double _number
double value = (double)calcType.InvokeMember("_number",
BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic,
null, calcInstance, null);
}
}
}
虽然您可以按照Steven的回答中的详细说明加载程序集,但还有另一种可能性 可以在解决方案中添加对程序集的引用,但不能将程序集作为解决方案的一部分进行部署。这意味着您不必使用反射,而是使用AppDomain.AssemblyResolve事件 您的需求不清楚,但本质上这是一种注入dll的方法 例如,假设您有dll来实现您所支持的每个后端的数据库操作 当您的代码尝试查找程序集时,它会在通常的位置进行查找,如果尚未加载并且找不到该程序集,则会触发AssmemblyResolve事件,并在其中根据某些配置选项从某个可访问的位置动态加载该程序集
可访问的位置,可以是url、完全不同的路径,甚至是网络路径。显然,这个示例并不适用,但它甚至可能是数据库中的一个blob。您的答案很适合将MEF作为一个选项,但您应该包括一个小示例(不只是链接到codeplex位置)。您好,我在下面添加了一个完整的示例,它展示了如何实际调用这些方法。我希望这有帮助。