вызов метода во время выполнения - PullRequest
9 голосов
/ 31 января 2010

Мне интересно, можно ли загрузить .net DLL во время выполнения, просмотреть доступные методы и выполнить один во время выполнения.

Если это возможно, не могли бы вы указать мне правильное направление

Ответы [ 4 ]

7 голосов
/ 31 января 2010

Как правило, вы используете классы System.Reflection для выполнения этой задачи.

В частности, вы должны загрузить DLL через Assembly.Load (или Assembly.LoadFrom ) и затем вызвать Assembly.GetTypes , а затем для каждого типа вызов Type.GetMethods . Если у вас есть MethodInfo , вы можете вызвать MethodInfo.Invoke .

3 голосов
/ 31 января 2010

Да, это возможно, вы просто начинаете с загрузки вашей dll:

Assembly assembly = Assembly.LoadFrom(assemblyPath);

А затем, чтобы вызвать метод внутри вашей dll, вам нужно будет использовать отражение .

object obj = assembly.CreateInstance(<type.FullName>);

, где type.FullName - это свойство FullName некоторого типа в этой сборке.

Как только вы получите свой экземпляр, вы можете вызвать свой метод следующим образом:

MethodInfo methodInfo = obj.GetMethod("MyMethod");
methodInfo.Invoke(obj,null);
3 голосов
/ 31 января 2010

Вам нужно использовать Отражение .

Вы можете вызвать Assembly.LoadFile, чтобы загрузить .DLL, содержащий сборку .Net, а затем вызвать метод GetTypes возвращаемого объекта Assembly, чтобы посмотреть на классы в DLL.
Найдя объект Type для интересующего вас класса, вы можете вызвать метод InvokeMember для вызова функции.

Остерегайтесь, что отражение может быть довольно медленным.

1 голос
/ 31 января 2010

Я нашел это в образцы отражения

 // get all public static methods of MyClass type
  MethodInfo[] methodInfos = typeof(MyClass).GetMethods(BindingFlags.Public |
                                                  BindingFlags.Static);


[C#]
// dynamically load assembly from file Test.dll
 Assembly testAssembly = Assembly.LoadFile(@"c:\Test.dll");

[C#]
// get type of class Calculator from just loaded assembly
Type calcType = testAssembly.GetType("Test.Calculator");

[C#]
// create instance of class Calculator
object calcInstance = Activator.CreateInstance(calcType);

[C#]
// get info about property: public double Number
PropertyInfo numberPropertyInfo = calcType.GetProperty("Number");

[C#]
// get value of property: public double Number
double value = (double)numberPropertyInfo.GetValue(calcInstance, null);

[C#]
// set value of property: public double Number
numberPropertyInfo.SetValue(calcInstance, 10.0, null);

[C#]
// get info about static property: public static double Pi
PropertyInfo piPropertyInfo = calcType.GetProperty("Pi");

[C#]
// get value of static property: public static double Pi
double piValue = (double)piPropertyInfo.GetValue(null, null);

[C#]
// invoke public instance method: public void Clear()
calcType.InvokeMember("Clear",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
null, calcInstance, null);

[C#]
// invoke private instance method: private void DoClear()
calcType.InvokeMember("DoClear",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
null, calcInstance, null);

[C#]
// 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 });

[C#]
// invoke public static method: public static double GetPi()
double piValue = (double)calcType.InvokeMember("GetPi",
BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
null, null, null);

[C#]
// get value of private field: private double _number
double value = (double)calcType.InvokeMember("_number",
BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic,
null, calcInstance, null);
...