Da ich die erstellung von Code via CodeDOM ziemlich umständlich fand und ich mal testen wollte was man mit einer .NET sprache so alles anstellen kann hab ich mal diese kleine Libary geschrieben.
Würde mich freuen wenn Ihr mir ein bisschen Feedback drüber geben könntet, ist meine erste Libary die ich wirklich veröffentlicht habe.
Sieht super aus, die API könnte man aber noch verbessern:
Ich denke da gibts noch viel Potential, die Idee finde ich aber Klasse und werde es auch verwenden, sobald ich wieder was mit CodeDOM mache.
ImageTools for Silverlight: http://imagetools.codeplex.com | http://www.silverdiagram.net | http://www.cleancodedeveloper.de b:::
Danke für das Feedback, bei !!! 4 !!! downloads muss ich echt noch was tun das die libary bekannter wird
Das CallStatic vereinfachen hab ich mir auch schon gedacht denke ich werde ich einbauen.
Das Body habe ich eingebaut damit man nicht wild Parameter Rückgabetyp und Code Vermischt. Was ich aber schon länger überlege das man nur noch ein End nach einem methoden body machen soll also statt
.Method(MemberAttributes.Public | MemberAttributes.Static, "Main").Parameter(typeof(string[]), "args")
.Body
.CallStatic(typeof(Console), "WriteLine", Expr.Primitive("Hello Fluent CodeDom"))
.End.End
nur noch schreiben muss
.Method(MemberAttributes.Public | MemberAttributes.Static, "Main").Parameter(typeof(string[]), "args")
.Body
.CallStatic(typeof(Console), "WriteLine", Expr.Primitive("Hello Fluent CodeDom"))
.End
Man kann das Body und das End ja als scopes sehen oder wie in TSQL das BEGIN und END Statement
Hallo Desert Fox,
zumindest sollte intuitiv klar sein, wo man End
setzen muss. Für Parameter
braucht man ja auch kein End
. Weshalb sollte man es dann für Method
brauchen? Überhaupt ist es schwer einem Namen wie Method
, Parameter
oder Body
anzusehen, ob er nun ein End
braucht oder nicht.
Klarer wäre es, wenn man End
nur dort braucht, wo man vorher Begin
verwendet hat. Also dass man quasi genau da Begin
/End
verwendet, wo man in normalem Code eine öffnende/schließende geschweifte Klammer setzt.
Wenn dir Begin
und End
nicht sprechend genug sein sollten, könntest du BeginBody
und EndBody
verwenden. Aber Body
und End
sind irgendwie asymmetrische Bezeichnungen.
herbivore
Sehe ich genauso, mein Wunsch Syntax wäre:
.Method(MemberAttributes.Public | MemberAttributes.Static, "Main")
.Parameter(typeof(string[]), "args1")
.Parameter(typeof(string[]), "args2")
.BeginBody
.CallStatic(typeof(Console), "WriteLine", Expr.Primitive("Hello Fluent CodeDom"))
.CallStatic(typeof(Console), "WriteLine", Expr.Primitive("Hello Again"))
.EndBody
ImageTools for Silverlight: http://imagetools.codeplex.com | http://www.silverdiagram.net | http://www.cleancodedeveloper.de b:::
Also persönlich würde ich dann doch
Begin
End
bevorzugen EndBody ist mir dann doch zuviel Text
Hmm über eine VB ähnliche syntax habe ich auch schon nachgedacht und immoment muss ich doch sagen das eine syntax wie
.Method("Test").Parameter(typeof(int) "i")
.CallStatic(typeof(Console), "WriteLine", "Test")
.EndMethod
doch auch am meisten zusagen würde und das mit dem Body weglassen könnte zwar zu ner ziemlich scheuslichen syntax führen, für den well formed code ist dann am ende der programmierer ja eh selbst verantwortlich.
Wenn man nur End Verwendet habe ich selbst schon gemerkt das man da schnell mit den Ends Durcheinander kommt. Und so schlecht schaut das dann garnicht aus
.Namespace("Test.FluentCodeDom.Test")
.Import("System")
.Import("System.Text")
.Class(MemberAttributes.Public, "StringModifier")
.Field(typeof(int), "_intValue").EndField
.Property(MemberAttributes.Public, typeof(int), "IntValue")
.Get
.Return(Expr.Var("_intValue"))
.EndGet
.Set
.Set(Expr.Var("_intValue"), Expr.Value())
.EndGet
.EndProperty
.EndClass
.EndNamespace
Also ich bin grade dabei das ganze umzustellen wie im post oben gezeigt, man muss aber sagen das ganze nicht umbedingt ganz einfach da ich schon ziemlich extremes zeug mit Generics mache.
(Man kann sich ja mal den source anschauen, das ist problem ist nämlich das auch so sachen wie Ifs in Schleifen in Try Blöcken in Methoden möglich sein müssen)
und dann kommen halt mal fehlermeldungen wie die hier raus:
Fehlermeldung:
Fehler 2 "FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeType <FluentCodeDom.FluentCodeClass>, FluentCodeDom.FluentCodeMethod <FluentCodeDom.FluentCodeClass>>, FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeType <FluentCodeDom.FluentCodeClass>, FluentCodeDom.FluentCodeMethod <FluentCodeDom.FluentCodeClass>>, FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeType <FluentCodeDom.FluentCodeClass>, FluentCodeDom.FluentCodeMethod <FluentCodeDom.FluentCodeClass>>.IfCodeBody>.ElseCodeBody>" enthält keine Definition für "EndIf", und es konnte keine Erweiterungsmethode "EndIf" gefunden werden, die ein erstes Argument vom Typ "FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeType <FluentCodeDom.FluentCodeClass>, FluentCodeDom.FluentCodeMethod <FluentCodeDom.FluentCodeClass>>, FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeType <FluentCodeDom.FluentCodeClass>, FluentCodeDom.FluentCodeMethod <FluentCodeDom.FluentCodeClass>>, FluentCodeDom.FluentCodeBody <FluentCodeDom.FluentCodeType <FluentCodeDom.FluentCodeClass>, FluentCodeDom.FluentCodeMethod <FluentCodeDom.FluentCodeClass>>.IfCodeBody>.ElseCodeBody>" akzeptiert. (Fehlt eine Using-Direktive oder ein Assemblyverweis?) C:\Daten\Projects\Dropbox\Nation Commander\FluentCodeDom\FluentCodeDom.Test\DeclarationTests.cs 66 30 FluentCodeDom.Test
Also habe das ganze jetzt geupdated und die neue version ist auf codeplex verfügbar.
Changes sind somit:
Mir ist bewusst das aller alte code der damit erstellt wurde geupdated werden muss bei 7 downloads ist das aber denke ich mal zu verkraften ^^
Das ganze sieht jetzt wie oben angekündigt so aus:
namespace FluentCodeDom.Sample1
{
class Program
{
static void Main(string[] args)
{
CodeCompileUnit compileUnit = new FluentCodeCompileUnit()
.Namespace("Sample1")
.Class("Program")
.Method(MemberAttributes.Public | MemberAttributes.Static, "Main").Parameter(typeof(string[]), "args")
.CallStatic(typeof(Console), "WriteLine", Expr.Primitive("Hello Fluent CodeDom"))
.EndMethod
.EndClass
.EndNamespace
.EndFluent();
Assembly assembly = Helper.CodeDomHelper.CompileInMemory(compileUnit);
assembly.GetType("Sample1.Program").GetMethod("Main").Invoke(null, new object[] { null });
}
}
}