2010-01-31 10 views
9

Zastanawiam się, czy można załadować bibliotekę .net w czasie wykonywania, wyświetlić dostępne metody i wykonać je w czasie wykonywania.metoda wywołania w czasie wykonywania

Jeśli jest to możliwe, można wskazać mi w dobrym kierunku

Odpowiedz

3

Trzeba użyć Reflection.

Można zadzwonić Assembly.LoadFile załadować DLL zawierający NET, a następnie wywołać metodę GetTypes na zwróconej Assembly obiektu patrzeć na zajęciach w bibliotece DLL.
Po znalezieniu obiektu Type dla zajęć, które Cię interesują, możesz wywołać jego metodę InvokeMember w celu wywołania funkcji.

Pamiętaj, że odbicie może być dość powolne.

+0

Można poprawić wydajność wywoływania metody poprzez odbicie za pomocą 'Delegate.CreateDelegate (...)' zamiast się metodę i nazywając ją czysto przez odbicie: http://msdn.microsoft.com/en-us/library/system.delegate.createdelegate.aspx –

+1

@Dan: True. Jest to jednak możliwe tylko wtedy, gdy znasz sygnaturę podczas kompilacji. – SLaks

+0

lub użyj DynamicMethod. – codekaizen

1

Znalazłem to na reflection eamples

// 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); 
3

Tak, to jest możliwe, po prostu zacząć z załadowaniem dll:

Assembly assembly = Assembly.LoadFrom(assemblyPath); 

A następnie wywołać metodę wewnątrz dll będziesz muszą używać reflection.

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

gdzie type.FullName jest własnością pełna nazwa pewnego rodzaju w tym zespole.

Gdy masz instancji, można wywołać metodę tak:

MethodInfo methodInfo = obj.GetMethod("MyMethod"); 
methodInfo.Invoke(obj,null);