20. maj 2009 - 15:02Der er
5 kommentarer og 1 løsning
Kør en metode fra en string
Jeg sidder og roder med noget kode hvor jeg bruger Reflection til at finde klasser og metodenavne fra en .dll fil. På den måde får jeg metodenavnene op i programmet og vil gerne kalde dem, men det skal være så dynamisk at jeg skal kalde metoderne ud fra de informationer jeg får.
Jeg har en idé om at jeg jeg kan bruge Assemply eller CodeDom til at kalde metoderne med de strings jeg har, men ved ikke hvordan.
Simpelt eksempel på hvordan du kalder en metode via reflection:
class Program { static void Main(string[] args) { var type = typeof(Program); var methodInfo = type.GetMethod("Test"); methodInfo.Invoke(new Program(), null);
var methodInfo2 = type.GetMethod("Test2"); methodInfo2.Invoke(null, null);
Console.ReadLine(); }
public void Test() { Console.WriteLine("test"); }
public static void Test2() { Console.WriteLine("test2"); } }
Tak for svaret, det gav mig et hint om hvad vej jeg skal. Jeg da jeg bruger polymorfi i .dll filen og der skal være mulighed for at ændre klassenavnene eller tilføje flere klasser ved kun at ændre dll filen. Derfor har jeg stadig et problem.
Hvordan giver jeg forresten points for svaret? Jeg vil gerne give points for dette svar og hvis der er nogle der kan hjælpe mig med resten får de self også 60 points, skal bare fortælle mig hvordan jeg gør ;)
Jeg er ved at forberede et strategy pattern med reflection til eksamen.
dll filen ser ud som følger (det skal være mulighed for at skifte den ud med andre klasser der nedarver fra Rabat)
using System; using System.Collections.Generic;
namespace RabatClasses { public abstract class Rabat { public abstract double BeregnRabat(int kr); }
public class RabatLille : Rabat { public override double BeregnRabat(int kr) { double rabat = 0.05; return rabat; } }
public class RabatStor : Rabat { public override double BeregnRabat(int kr) { double rabat = 0.3; return rabat; } } }
Indtil vidre har jeg lavet denne kode til programmet der Henter klassenavne fra Dll filen
using System; using System.Reflection; using RabatClasses; //namespace der er indeholder rabatklasser using System.Collections.Generic; using System.CodeDom;
namespace Rabatprogram { class RabatHandler { private Rabat rabat; private int pris; private int antal;
public void GetClasses() { ReflectionHandler reflections = new ReflectionHandler(); List<string> classList = reflections.GetClasses();
foreach (string item in classList) { System.Windows.Forms.MessageBox.Show(item);
} } } }
Den kode du skrev ovenover kan jeg bruge hvis jeg kalder en af de abstrakte klasser (RabatLille eller RabatStor), men programmet skal indeholde mulighed for at ændre disse klassenavne eller oprette nye der så også skal kunne kaldes ved kun at ændre koden i dll filen.
Hvis jeg har forstået dit projekt rigtigt, er det noget ala en plugin mønster du vil implementere.
Jeg har tilladt mig at lave lidt om i din opbygning og lavet et eksempel på hvordan du kan løse opgaven.
Jeg har lavet 3 projecter. 1. ConsoleApplication der afvikler koden 2. ClassLib med interface for Rabat 3. ClassLib med forskellige implementationer af Rabat
1. kender så til 2. og indlæser 3. dynamisk 2. kender ikke til nogen af de andre 3. kender til 2. for at implementere Rabat i dette
1. ConsoleApplication class Program { static void Main(string[] args) { int kroner = 100; var abstractRabatType = typeof(AbstractRabat); var assembly = Assembly.LoadFile(Environment.CurrentDirectory+@"\RabatClasses.dll"); foreach (var assemblyType in assembly.GetTypes()) { var type = assemblyType; while (type != typeof(object)) { if (type.BaseType == abstractRabatType) { var rabat = (AbstractRabat)Activator.CreateInstance(type); Console.WriteLine(type.Name+" - Rabat for 100kr: "+rabat.BeregnRabat(kroner));
} type = type.BaseType; } } Console.ReadLine(); } }
2. abstract klasse af rabat public abstract class AbstractRabat { public abstract double BeregnRabat(int kr); }
3. implementationer af Rabat public class RabatLille : AbstractRabat { public override double BeregnRabat(int kr) { double rabat = 0.05; return rabat; } }
public class RabatStor : AbstractRabat { public override double BeregnRabat(int kr) { double rabat = 0.3; return rabat; } }
Håber det giver mening, ellers kan jeg godt uploade min solution et sted så du kan se den
Tak for hjælpen, dit foreslag gav mig en fin løsning :)
/Jørn
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.