c# CodeDOM - Initialize array - c#

I'm trying to create a simple dll runtime, using CodeDOM.
I have quite understand what I need to finish this simple test application.
I need to create with CodeDOM object this statement:
List<string> test = new List<string>() {"A", "B", ... }
I'm just having this statement for declaration of a List of n values, but find nowhere the instructions for reach what I need.
This is my actual code:
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace samples = new CodeNamespace("ClassLibrary1");
compileUnit.Namespaces.Add(TestNamespace);
samples.Imports.Add(new CodeNamespaceImport("System"));
samples.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
samples.Imports.Add(new CodeNamespaceImport("System.Text"));
CodeTypeDeclaration _class = new CodeTypeDeclaration("TestClass");
CodeMemberField _field = new CodeMemberField();
_field.Attributes = MemberAttributes.Private;
_field.Name = "_testMember";
_field.Type = new CodeTypeReference(typeof(List<string>));
//This is where I cannot understand how to insert the values
_field.InitExpression = new CodeObjectCreateExpression(new CodeTypeReference(typeof(List<string>)), new CodePrimitiveExpression(64));
class1.Members.Add(_field);
How to initialize a list (or an array) with some default values?
Thank you in advance.

As suggested, the answer lies in CodeArrayCreateExpression.
Here is the completed (working) code snippet:
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace samples = new CodeNamespace("ClassLibrary1");
compileUnit.Namespaces.Add(samples);
samples.Imports.Add(new CodeNamespaceImport("System"));
samples.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
samples.Imports.Add(new CodeNamespaceImport("System.Text"));
CodeTypeDeclaration _class = new CodeTypeDeclaration("TestClass");
CodeMemberField _field = new CodeMemberField();
_field.Attributes = MemberAttributes.Private;
_field.Name = "_testMember";
_field.Type = new CodeTypeReference(typeof(List<string>));
var initialiseExpression = new CodeArrayCreateExpression(
new CodeTypeReference(typeof(string)),
new CodePrimitiveExpression("A"),
new CodePrimitiveExpression("B"),
new CodePrimitiveExpression("C"));
_field.InitExpression = new CodeObjectCreateExpression(new CodeTypeReference(typeof(List<string>)), initialiseExpression);
_class.Members.Add(_field);
The important part is the new initialiseExpression variable that defines the array.

Related

How to Use FontFamily in a concise manner

I'm new to C# programming and I have a function involving FontFamily. The code seems to work fine but I wanted it written in a more concise manner.
I searched online but seems unable to get the right solution. The following code is what I currently have.
public FontFamily[] FontFamilyExt()
{
FontFamily[] f =
{new FontFamily(_fnt[0]),
new FontFamily(_fnt[1]),
new FontFamily(_fnt[2]),
new FontFamily(_fnt[3]),
new FontFamily(_fnt[4]),
new FontFamily(_fnt[5]),
new FontFamily(_fnt[6]),
new FontFamily(_fnt[7]),
new FontFamily(_fnt[8]),
new FontFamily(_fnt[9]),
new FontFamily(_fnt[10]),
new FontFamily(_fnt[11]),
new FontFamily(_fnt[12]),
new FontFamily(_fnt[13]),
new FontFamily(_fnt[14]),
new FontFamily(_fnt[15]),
new FontFamily(_fnt[16]),
new FontFamily(_fnt[17]),
new FontFamily(_fnt[18]),
new FontFamily(_fnt[19]),
new FontFamily(_fnt[20]),
new FontFamily(_fnt[21]),
new FontFamily(_fnt[22]),
new FontFamily(_fnt[23]),
new FontFamily(_fnt[24]),
new FontFamily(_fnt[25]),
new FontFamily(_fnt[26]),
new FontFamily(_fnt[27]),
new FontFamily(_fnt[28]),
new FontFamily(_fnt[29]),
new FontFamily(_fnt[30]),
new FontFamily(_fnt[31])
};
return f;
}
I am looking for something that works similarly but uses less codes. Thank you in advance.
You could use a loop as recommended. You could also use Enumerable.Range, which basically creates a loop under the covers, but will put the code into one line. Something like:
using System.Linq;
public FontFamily[] FontFamilyExt()
{
return Enumerable.Range(0, 32).Select(x => new FontFamily(_fnt[x])).ToArray();
}
You can try this:
public FontFamily[] FontFamilyExt()
{
FontFamily[] f = new FontFamily[32];
for ( int index = 0; index <= 31; index++ )
f[index] = new FontFamily(_fnt[index]);
return f;
}

Create folder using CMIS and Sharepoint

Currently I need to create a folder on a Sharepoint repository using it CMIS implementation so I am using the web services it offers on the path http://(server)/_vti_bin/cmis/soap. I implemented the code based on this example https://chemistry.apache.org/java/opencmis-cookbook.html but Sharepoint does not return the rootFolderId so the method getChildren returns nothing. Finally based on a query using the discovery service I retrieve the root folder id, but now the problem is I can't create a sub folder. This is my code:
Object.cmisPropertyId p1 = new Object.cmisPropertyId();
p1.propertyDefinitionId = "cmis:baseTypeId";
p1.value = new string[1];
p1.value[0] = "cmis:folder";
propertiesType.Items.SetValue(p1, 0);
Object.cmisPropertyString p2 = new Object.cmisPropertyString();
p2.propertyDefinitionId = "cmis:name";
p2.value = new string[1];
p2.value[0] = "mytest";
propertiesType.Items.SetValue(p2, 1);
Object.cmisPropertyString p3 = new Object.cmisPropertyString();
p3.propertyDefinitionId = "cmis:path";
p3.value = new string[1];
p3.value[0] = "Rep/f1/mytest";
propertiesType.Items.SetValue(p3, 2);
Object.cmisPropertyId p4 = new Object.cmisPropertyId();
p4.propertyDefinitionId = "cmis:objectTypeId";
p4.value = new string[1];
p4.value[0] = "cmis:folder";
propertiesType.Items.SetValue(p4, 3);
Object.cmisPropertyId p5 = new Object.cmisPropertyId();
p5.propertyDefinitionId = "cmis:parentId";
p5.value = new string[1];
p5.value[0] = "268";
propertiesType.Items.SetValue(p5, 4);
Object.cmisPropertyString p6 = new Object.cmisPropertyString();
p6.propertyDefinitionId = "Author";
p6.value = new string[1];
p6.value[0] = "theAuthor";
propertiesType.Items.SetValue(p6, 5);
Object.cmisPropertyId p7 = new Object.cmisPropertyId();
p7.propertyDefinitionId = "cmis:allowedChildObjectTypeIds";
p7.value = new string[3];
p7.value[0] = "cmis:document";
p7.value[1] = "0x010100C98D402E3C78834C873469CE4F41E2C300B0A3B5E8A3E51543977DFDCE95850082";
p7.value[2] = "cmis:folder";
propertiesType.Items.SetValue(p7, 6);
var result = objectService.createFolder(repositoryInfo.repositoryId, propertiesType, null, null, null, null, ref extType);
It always return null, I'm not sure how to pass correctly the arguments to the service for make the creation works. I don't know where to find logs o something that tell me what I am doing wrong.
Thank you
PD: I need to use this aproach because is a modification to an existing code that already use the Sharepoint CMIS services.
You try to update readonly properties. See CMIS 1.0
http://docs.oasis-open.org/cmis/CMIS/v1.1/CMIS-v1.1.html
Sample on Java
Folder root = session.getRootFolder();
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");
properties.put(PropertyIds.NAME, "a new folder");
Folder newFolder = root.createFolder(properties);
The key is "session". You should create session to CMIS Repository(Atom or WSDL binding). Session will provide you ability to create/retrieve folders/documents

Why is my static dictionary not initialising? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am using a big dictionary I want to only be created once to store some information along with a static function to extract info from it like so:
public static class AceMimeInfo
{
static Dictionary<string, Info> mimedictionary = new Dictionary<string, Info>
{
{".abap", new Info("abap", "ABAP")},
{".asciidoc", new Info("asciidoc", "AsciiDoc")},
{".c9search_results", new Info("c9search", "C9Search")},
{".coffee", new Info("coffee", "CoffeeScript")},
{".cf", new Info("coffee", "CoffeeScript")},
{".xul", new Info("xml", "XML")},
{".xbl", new Info("xml", "XML")},
{".xq", new Info("xquery", "XQuery")},
{".yaml", new Info("yaml", "YAML")}
};
public class Info
{
public string Mode;
public string Name;
public Info(string mode, string name)
{
Mode = mode;
Name = name;
}
}
public static string GetMode(string fileext)
{
string fe;
fe = fileext.ToLower();
if(!fe.StartsWith("."))
fe = "." + fe;
if (mimedictionary.ContainsKey(fe))
return mimedictionary[fe].Mode;
return "";
}
}
However when I step through GetMode with the debugger, the dictionary mimedictionary is always null.
What do I need to do to make sure this isn't the case?
Any suggestions as to a better way of doing this would also be appreciated.
I am calling GetMode this like so:
string mode = AceMimeInfo.GetMode("filename.cpp");
Thanks in advance
Update:
I tried the above code and it does indeed work. The dictionary above is a shorter version of what I am actually using (because it's quite long).
Here is the actual class I am using - and it doesn't work. When I shorten the dictionary, it does work.
public static class AceMimeInfo
{
static Dictionary<string, Info> mimedictionary = new Dictionary<string, Info>
{
{".abap", new Info("abap", "ABAP")},
{".asciidoc", new Info("asciidoc", "AsciiDoc")},
{".c9search_results", new Info("c9search", "C9Search")},
{".coffee", new Info("coffee", "CoffeeScript")},
{".cf", new Info("coffee", "CoffeeScript")},
{".cfm", new Info("coldfusion", "ColdFusion")},
{".cs", new Info("csharp", "C#")},
{".css", new Info("css", "CSS")},
{".dart", new Info("dart", "Dart")},
{".diff", new Info("diff", "Diff")},
{".patch", new Info("diff", "Diff")},
{".dot", new Info("dot", "Dot")},
{".glsl", new Info("glsl", "Glsl")},
{".frag", new Info("glsl", "Glsl")},
{".vert", new Info("glsl", "Glsl")},
{".go", new Info("golang", "Go")},
{".groovy", new Info("groovy", "Groovy")},
{".hx", new Info("haxe", "Haxe")},
{".haml", new Info("haml", "HAML")},
{".htm", new Info("html", "HTML")},
{".html", new Info("html", "HTML")},
{".xhtml", new Info("html", "HTML")},
{".c", new Info("c_cpp", "C/C++")},
{".cc", new Info("c_cpp", "C/C++")},
{".cpp", new Info("c_cpp", "C/C++")},
{".cxx", new Info("c_cpp", "C/C++")},
{".h", new Info("c_cpp", "C/C++")},
{".hh", new Info("c_cpp", "C/C++")},
{".hpp", new Info("c_cpp", "C/C++")},
{".clj", new Info("clojure", "Clojure")},
{".jade", new Info("jade", "Jade")},
{".java", new Info("java", "Java")},
{".jsp", new Info("jsp", "JSP")},
{".js", new Info("javascript", "JavaScript")},
{".json", new Info("json", "JSON")},
{".jsx", new Info("jsx", "JSX")},
{".latex", new Info("latex", "LaTeX")},
{".tex", new Info("latex", "LaTeX")},
{".ltx", new Info("latex", "LaTeX")},
{".bib", new Info("latex", "LaTeX")},
{".less", new Info("less", "LESS")},
{".lisp", new Info("lisp", "Lisp")},
{".scm", new Info("lisp", "Lisp")},
{".rkt", new Info("lisp", "Lisp")},
{".liquid", new Info("liquid", "Liquid")},
{".lua", new Info("lua", "Lua")},
{".lp", new Info("luapage", "LuaPage")},
{".lucene", new Info("lucene", "Lucene")},
{".make", new Info("makefile", "Makefile")},
{".md", new Info("markdown", "Markdown")},
{".markdown", new Info("markdown", "Markdown")},
{".m", new Info("objectivec", "Objective-C")},
{".ml", new Info("ocaml", "OCaml")},
{".mli", new Info("ocaml", "OCaml")},
{".pl", new Info("perl", "Perl")},
{".pm", new Info("perl", "Perl")},
{".pgsql", new Info("pgsql", "pgSQL")},
{".php", new Info("php", "PHP")},
{".phtml", new Info("php", "PHP")},
{".ps1", new Info("powershell", "Powershell")},
{".py", new Info("python", "Python")},
{".r", new Info("r", "R")},
{".Rd", new Info("rdoc", "RDoc")},
{".Rhtml", new Info("rhtml", "RHTML")},
{".ru", new Info("ruby", "Ruby")},
{".gemspec", new Info("ruby", "Ruby")},
{".rake", new Info("ruby", "Ruby")},
{".rb", new Info("ruby", "Ruby")},
{".scad", new Info("scad", "OpenSCAD")},
{".scala", new Info("scala", "Scala")},
{".scss", new Info("scss", "SCSS")},
{".sass", new Info("scss", "SCSS")},
{".sh", new Info("sh", "SH")},
{".bash", new Info("sh", "SH")},
{".bat", new Info("sh", "SH")},
{".sql", new Info("sql", "SQL")},
{".styl", new Info("stylus", "Stylus")},
{".stylus", new Info("stylus", "Stylus")},
{".svg", new Info("svg", "SVG")},
{".tcl", new Info("tcl", "Tcl")},
{".tex", new Info("tex", "Tex")},
{".txt", new Info("text", "Text")},
{".textile", new Info("textile", "Textile")},
{".typescript", new Info("typescript", "Typescript")},
{".ts", new Info("typescript", "Typescript")},
{".str", new Info("typescript", "Typescript")},
{".xml", new Info("xml", "XML")},
{".rdf", new Info("xml", "XML")},
{".rss", new Info("xml", "XML")},
{".wsdl", new Info("xml", "XML")},
{".xslt", new Info("xml", "XML")},
{".atom", new Info("xml", "XML")},
{".mathml", new Info("xml", "XML")},
{".mml", new Info("xml", "XML")},
{".xul", new Info("xml", "XML")},
{".xbl", new Info("xml", "XML")},
{".xq", new Info("xquery", "XQuery")},
{".yaml", new Info("yaml", "YAML")}
};
public class Info
{
public string Mode;
public string Name;
public Info(string mode, string name)
{
Mode = mode;
Name = name;
}
}
public static string GetMode(string fileext)
{
string fe;
fe = fileext.ToLower();
if(!fe.StartsWith("."))
fe = "." + fe;
if (mimedictionary.ContainsKey(fe))
return "ace/mode/" + mimedictionary[fe].Mode;
return "";
}
}
Debugger output:
{"The type initializer for 'TestApp.AceMimeInfo' threw an exception."}
Update II: Where's the repeated key?
You are adding a key to your dictionary more than once, which is causing the static initializer to throw an exception. You can determine this by examining the InnerException property of the exception that is thrown.
This is most likely just a debugger artifact. The runtime may delay initialization of static fields until they're actually needed. Just viewing the field in the debugger doesn't trigger that initialization, so the debugger can observe uninitialized fields which the program itself doesn't observe.
If your class has a static constructor, it's even forced to delay all static initialization until you either instantiate the class, access a static field, or call a static method.
I'm pretty sure that your code won't see mimedictionary == null. You can add a Debug.Assert(mimedictionary!=null) and you'll see that it doesn't get triggered.
Another possibility that can cause trouble is building some circular calls in your initializer. But your code as posted doesn't have this property.
I cannot reproduce the problem. The dictionary is filled and contains 9 entries in my tests. The problem is your argument "filename.cpp" that is not a key in the dictionary. And ".cpp" is not contained either. It works if you call with ".cf" for instance.
Use this code if you want to apply it to filenames as well:
public static string GetMode(string fileOrExt)
{
string ext = System.IO.Path.GetExtension(fileOrExt);
if (ext == String.Empty) {
ext = fileOrExt;
if (!ext.StartsWith(".")) {
ext = "." + ext;
}
}
Info info;
if (mimedictionary.TryGetValue(ext, out info)) {
return info.Mode;
}
return "-";
}
I would suggest you create a static constructor and initialize all your static types there like in the following example:
public class AcmeMimeInfo
{
private static List<string> list;
static AcmeMimeInfo()
{
list = new List<string>();
}
}

Errors while attempting to generate code using Codedom

My goal: To create a windows form application (executable) through the use of CodeDom. By this I mean I would like a form (with some code behind the form) and turn it into an executable file (as if I had gone into Visual Studio and clicked "Build" > "Build File"). Admittingly, I found this example online and I have since lightly modified it. I am getting errors while trying to generate this code - errors that I have never seen before. Furthermore, I could not find these errors on Google (odd right?)...
Here is the error I am getting:
Element type System.CodeDom.CodeExpression is not supported.
Parameter name: e
I am getting this error on the following line:
CodeProvider.GenerateCodeFromCompileUnit(Unit, writer, new CodeGeneratorOptions());
Here is my full code:
{
CodeDomProvider CodeProvider = CodeDomProvider.CreateProvider("CSharp");
// Create the Unit
CodeCompileUnit Unit = new CodeCompileUnit();
// Define a namespace and add Imports statements
CodeNamespace Namespaces = new CodeNamespace("Test.CreateForm");
Namespaces.Imports.Add(new CodeNamespaceImport("System"));
Namespaces.Imports.Add(new CodeNamespaceImport("System.Drawing"));
Namespaces.Imports.Add(new CodeNamespaceImport("System.Windows.Forms"));
Namespaces.Imports.Add(new CodeNamespaceImport("System.Xml"));
Namespaces.Imports.Add(new CodeNamespaceImport("System.Data"));
Unit.Namespaces.Add(Namespaces);
// Declare the type including base type
CodeTypeDeclaration MyType = new CodeTypeDeclaration("Form1");
MyType.IsClass = true;
MyType.TypeAttributes = System.Reflection.TypeAttributes.Public;
MyType.BaseTypes.Add("System.Windows.Forms.Form");
Namespaces.Types.Add(MyType);
// Create the constructor and add code
CodeConstructor Constructor = new CodeConstructor();
Constructor.Statements.Add(
new CodeMethodInvokeExpression(
new CodeThisReferenceExpression(),"InitializeComponent", new CodeExpression() {}));
Constructor.Attributes = MemberAttributes.Public ;
MyType.Members.Add(Constructor);
// Declare component container
MyType.Members.Add(new CodeMemberField("System.ComponentModel.IContainer", "components"));
// Implement the Dispose method
CodeMemberMethod DisposeMethod = new CodeMemberMethod();
DisposeMethod.Name = "Dispose";
DisposeMethod.Attributes = MemberAttributes.Family;
DisposeMethod.Parameters.Add(
new CodeParameterDeclarationExpression(
typeof(Boolean), "disposing"));
CodeConditionStatement Statement = new CodeConditionStatement();
Statement.Condition = new CodeArgumentReferenceExpression("disposing");
CodeConditionStatement TrueStatement = new CodeConditionStatement();
TrueStatement.Condition =
new CodeBinaryOperatorExpression(
new CodeArgumentReferenceExpression("components"),
CodeBinaryOperatorType.IdentityInequality,
new CodePrimitiveExpression(null));
TrueStatement.TrueStatements.Add(
new CodeMethodInvokeExpression(
new CodeFieldReferenceExpression(null,
"components"), "Dispose", new CodeExpression() {}));
Statement.TrueStatements.Add(TrueStatement);
DisposeMethod.Statements.Add(Statement);
DisposeMethod.Statements.Add(new CodeMethodInvokeExpression( new CodeBaseReferenceExpression(), "Dispose", new CodeArgumentReferenceExpression[]
{new CodeArgumentReferenceExpression("disposing")}));
MyType.Members.Add(DisposeMethod);
// InitializeComponent
CodeMemberMethod InitializeMethod = new CodeMemberMethod();
InitializeMethod.Name = "InitializeComponent";
InitializeMethod.Attributes = MemberAttributes.Private;
InitializeMethod.CustomAttributes.Add(
new CodeAttributeDeclaration(
"System.Diagnostics.DebuggerStepThrough"));
InitializeMethod.Statements.Add(
new CodeAssignStatement(
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "components"),
new CodeObjectCreateExpression(
new CodeTypeReference(
typeof(System.ComponentModel.Container)),
new CodeExpression() { })));
MyType.Members.Add(InitializeMethod);
// Main entry point
CodeEntryPointMethod MainMethod = new CodeEntryPointMethod();
MainMethod.Name = "Main";
MyType.Members.Add(MainMethod);
//Add mouse move event
CodeMemberEvent eventstate = new CodeMemberEvent();
eventstate.Name = "MouseMove";
eventstate.Attributes = MemberAttributes.Final | MemberAttributes.Public;
eventstate.Type = new CodeTypeReference("System.Windows.Forms.MouseEventHandler");
MyType.Members.Add(eventstate);
string OutputName = "Some.cs";
try
{
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BlankLinesBetweenMembers = true;
options.ElseOnClosing = false;
options.BracingStyle = "C";
// This is what we'll write the generated code to
IndentedTextWriter writer = new IndentedTextWriter(new StreamWriter(OutputName, false), " ");
try
{
CodeProvider.GenerateCodeFromCompileUnit(Unit, writer, new CodeGeneratorOptions());
writer.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
writer.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
// Create the compiler options
// Include referenced assemblies
CompilerParameters Options = new CompilerParameters();
Options.GenerateExecutable = true;
Options.OutputAssembly = "TestForm1.exe";
Options.CompilerOptions = "/target:winexe";
Options.MainClass = "Test.CreateForm.Form1";
string[] referenceAssemblies = { "System.dll", "System.Data.dll", "System.Drawing.dll", "System.Windows.Forms.dll", "System.XML.dll" };
Options.ReferencedAssemblies.AddRange(referenceAssemblies);
//Build and look for compiler errors
CompilerResults Result = CodeProvider.CompileAssemblyFromFile(Options, "Some.cs");
if (Result.Errors.Count > 0)
{
foreach(CompilerError ce in Result.Errors)
{
Console.WriteLine(ce.ErrorText);
}
}
else
{
Console.WriteLine("compiled successfully");
}
Console.WriteLine("press enter to continue");
Console.ReadLine();
}
You have many instances where you create an empty CodeExpression, such as in the constructor code:
// Create the constructor and add code
CodeConstructor Constructor = new CodeConstructor();
Constructor.Statements.Add(
new CodeMethodInvokeExpression(
new CodeThisReferenceExpression(), "InitializeComponent", new CodeExpression() { }));
If you don't want to pass any parameters to the method (which is the case in the code above), simply don't pass anything (CodeMethodInvokeExpression constructor takes a params[] array, so if you don't pass anything, it means that it receives an empty array):
// Create the constructor and add code
CodeConstructor Constructor = new CodeConstructor();
Constructor.Statements.Add(
new CodeMethodInvokeExpression(
new CodeThisReferenceExpression(),
"InitializeComponent"));
in case above code is not spitting the required code make sure you are closed the IndentedTextWriter e.g. writer.Close() enjoy..
CodeMemberMethod DisposeMethod = new CodeMemberMethod();
DisposeMethod.Name = "Dispose";
DisposeMethod.ReturnType = new CodeTypeReference(typeof(void));
DisposeMethod.Attributes = MemberAttributes.Override | MemberAttributes.Private;
DisposeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "disposing"));
myDesignerClass.Members.Add(DisposeMethod);
CodeConditionStatement cstif2 = new CodeConditionStatement();
CodeExpression dis = new CodeVariableReferenceExpression("disposing");
CodeExpression comp = new CodeVariableReferenceExpression("components");
cstif2.Condition = new CodeBinaryOperatorExpression(dis, CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression(dis, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)));
CodeExpression dispos = new CodeMethodInvokeExpression(comp, "Dispose", new CodeExpression[] { });
cstif2.TrueStatements.Add(dispos);
DisposeMethod.Statements.Add(cstif2);
CodeExpression bdispos = new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "Dispose", new CodeExpression[] { });
DisposeMethod.Statements.Add(bdispos);
Replace () after CodeExpression with [] and error will vanish.

Build a Yaml document dynamically from c#

Is it possible to build a Yaml document dynamically from c# with Yaml.DotNet or another library?
I understand how this can be done using serialisation, however that requires starting with an object structure.
I'm looking to find a way to create the Yaml document nodes on the fly as you would with Xml using the XElement.Add(object) method for example.
You can do that using YamlDotNet. You start by creating a YamlStream, add one or more document to it, then you can add sequences, mappings and scalars to it.
Here is an example on how to do it:
var address = new YamlMappingNode(
new YamlScalarNode("street"),
new YamlScalarNode("123 Tornado Alley\nSuite 16") { Style = YamlDotNet.Core.ScalarStyle.Literal },
new YamlScalarNode("city"),
new YamlScalarNode("East Westville"),
new YamlScalarNode("state"),
new YamlScalarNode("KS")
) { Anchor = "main-address" };
var stream = new YamlStream(
new YamlDocument(
new YamlMappingNode(
new YamlScalarNode("repeipt"),
new YamlScalarNode("Oz-Ware Purchase Invoice"),
new YamlScalarNode("date"),
new YamlScalarNode("2007-08-06"),
new YamlScalarNode("customer"),
new YamlMappingNode(
new YamlScalarNode("given"),
new YamlScalarNode("Dorothy"),
new YamlScalarNode("family"),
new YamlScalarNode("Gale")
),
new YamlScalarNode("items"),
new YamlSequenceNode(
new YamlMappingNode(
new YamlScalarNode("part_no"),
new YamlScalarNode("A4786"),
new YamlScalarNode("descrip"),
new YamlScalarNode("Water Bucket (Filled)"),
new YamlScalarNode("price"),
new YamlScalarNode("1.47"),
new YamlScalarNode("quantity"),
new YamlScalarNode("4")
),
new YamlMappingNode(
new YamlScalarNode("part_no"),
new YamlScalarNode("E1628"),
new YamlScalarNode("descrip"),
new YamlScalarNode("High Heeled \"Ruby\" Slippers"),
new YamlScalarNode("price"),
new YamlScalarNode("100.27"),
new YamlScalarNode("quantity"),
new YamlScalarNode("1")
)
),
new YamlScalarNode("bill-to"), address,
new YamlScalarNode("ship-to"), address,
new YamlScalarNode("specialDelivery"),
new YamlScalarNode("Follow the Yellow Brick\n" +
"Road to the Emerald City.\n" +
"Pay no attention to the\n" +
"man behind the curtain.")
{
Style = YamlDotNet.Core.ScalarStyle.Literal
}
)
)
);
I've now worked out how to do this using Yaml.Net. The YamlStream needs to be loaded with some initial content using the Load() method.
const string initialContent = "---\nversion: 1\n...";
var sr = new StringReader(initialContent);
var stream = new YamlStream();
stream.Load(sr);
You can then cast the RootNode of the YamlDocument to YamlMappingNode which has an Add method.
var rootMappingNode = (YamlMappingNode)stream.Documents[0].RootNode;
rootMappingNode.Add("shout", "yay!");
You can then add a variety of node types before saving:
var props = new YamlMappingNode();
props.Add("prop1", "value1");
props.Add("prop2", "value2");
rootMappingNode.Add("itemWithProps", props);
var props2 = new YamlMappingNode();
props2.Add("prop1", "value1");
props2.Add("prop2", "value2");
var props3 = new YamlMappingNode();
props3.Add("prop1", "value1");
props3.Add("prop2", "value2");
var seq = new YamlSequenceNode();
seq.Add(props2);
seq.Add(props3);
rootMappingNode.Add("sequenceOfItems", seq);
var col = new YamlSequenceNode();
col.Style = SequenceStyle.Flow;
col.Add("a");
col.Add("b");
col.Add("c");
var seqMapping = new YamlMappingNode();
seqMapping.Add("collection", col);
seq.Add(seqMapping);
using (TextWriter writer = File.CreateText("C:\\temp\\test.yaml"))
stream.Save(writer, false);
The output from this example is:
version: 1
shout: yay!
itemWithProps:
prop1: value1
prop2: value2
sequenceOfItems:
- prop1: value1
prop2: value2
- prop1: value1
prop2: value2
- collection: [a, b, c]
...
Thanks to #Antoine Aubry for creating Yaml.Net and vaguely pointing me in right direction.

Categories