Generierte Klassen zur Laufzeit kompilieren und einbinden.
Marcel
- sonstiges
Guten Morgen,
ich hab ein kleines Problem und komme nicht weiter. Ich habe Klassen in C# zur Laufzeit geschrieben bzw. generiert. Dies sind reine Models und sollen später gefüllt werden. Hier ist der Code zur generierung einer Klasse:
/// <summary>
/// Schreiben einr Klasse mit dazugehörigen Attributen
/// </summary>
/// <param name="className"></param>
/// <param name="attrList"></param>
/// <param name="buildPath"></param>
private static void BuildClass(string className, List<KeyValuePair<string, string>> attrList, string buildPath)
{
CodeNamespace ns = new CodeNamespace("Validator.Model.Rdf");
string typeName = className;
CodeTypeDeclaration type = new CodeTypeDeclaration(typeName);
List<CodeMemberProperty> listOfProperty = WritePropertysByAttributeList(attrList);
foreach (CodeMemberProperty property in listOfProperty)
{
type.Members.Add(property);
}
ns.Types.Add(type);
CSharpCodeProvider provider = new CSharpCodeProvider();
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(ns);
string classPath = buildPath;
using (StringWriter writer = new StringWriter())
{
provider.GenerateCodeFromCompileUnit(ccu, writer, null);
using (StreamWriter stream = new StreamWriter(classPath + typeName + ".cs"))
{
stream.WriteLine(writer.ToString());
}
}
}
/// <summary>
/// Attribute als Property definieren.
/// </summary>
/// <param name="listAttribute"></param>
/// <returns></returns>
private static List<CodeMemberProperty> WritePropertysByAttributeList(List<KeyValuePair<string, string>> listAttribute)
{
List<CodeMemberProperty> listProperty = new List<CodeMemberProperty>();
foreach (KeyValuePair<string, string> attr in listAttribute)
{
string name = attr.Key;
string attrType = attr.Value;
CodeMemberProperty property = new CodeMemberProperty();
property.Name = name;
property.Attributes = MemberAttributes.Public;
property.Type = new CodeTypeReference(typeof(string));
property.HasGet = true;
property.HasSet = true;
listProperty.Add(property);
}
return listProperty;
}
Wie kann ich nun diese Klassen zur Luafzeit kompilieren und in der Laufzeitumgebung verwenden? Weiß das hier jemand?
Vielen Dank und Gruß
Marcel
Moin
einfach die Stichworte C#, code, compile, runtime in Google einzugeben, hätte dich quasi an erster Stelle auf folgende Seite geführt:
http://www.codeproject.com/KB/cs/codecompilation.aspx
Nach kurzem überfliegen muss ich feststellen, dass der Artikel durchaus alles enthalten sollte, wonach du suchst.
private static void BuildClass(string className, List<KeyValuePair<string, string>> attrList, string buildPath)
Wozu bitte List<KeyValuePair<string, string>> ?, Warum nicht einfach Dictionary<string, string> ?
Wie kann ich nun diese Klassen zur Luafzeit kompilieren und in der Laufzeitumgebung verwenden? Weiß das hier jemand?
Das Kompilat (z.b. Assembly) kannst du (wenn es nicht bereits automatisch geladen ist) mithilfe der Assembly.Load/LoadFrom Methode in die ApplicationDomain laden. Das Benutzen solch dynamischer Dinge ist generell über Reflection machbar (MethodInfo x = Type.GetMethod(...); x.Invoke(targetInstance, ...). Oder du benutzt Interface-Deklarationen und kannst dann darüber ausführen, dann musst du nur den Typ/Klasse mithilfe von Reflection instanzieren. Das geht entweder über den Activator.CreateInstance oder ConstructorInfo.Invoke
Bitte bedenke, dass solche fetzigen Sachen bei häufiger Benutzung zu erheblichen Performanceeinbrüchen führen können. Ich bin mir fast sicher, dass du dein Ziel auch ohne dynamische Codekompilierung, dafür aber mit entsprechenden Design-Patterns (Bridge, Factory, Composite, Mediator) erreichen kannst.
Ciao, Frank