how can i add values to hashTable using Codedom in C# - c#

CodeVariableDeclarationStatement hashTableParam = new CodeVariableDeclarationStatement();
hashTableParam.Name = "hashtable";
hashTableParam.Type = new CodeTypeReference(typeof(System.Collections.Hashtable));
In the above code i tried to do a basic declaration for hashTable.
Now i need to added values to the hash table(key,value).
ht.Add("testKey","testData")
i.e how can i generate such code to add keys and values to HashTable programatically using codeDom

There is probably a way to do this that is more CodeDom oriented, which would allow for easier cross language support, but this will work
Assuming you already have a class created and a method, create a new CodeSnippetExpression and put the code you want in it, and then add that to your method body.

Related

How to update a Dictionary entry in ClearScript?

Context: ClearScript, JScript, C#, Windows, Azure
In my ClearScript-enabled projects, I have a Dictionary<string,object> that I use for passing data into, around inside and back out of evaluated scripts.
On the C# side I have
static Dictionary<string, object> Settings = new Dictionary<string, object>();
and then later on
JSengine = new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging);
and
JSengine.AddHostObject("CSSettings", Settings);
On the JScript side I have things like
CSSettings.Add("your API key", CSConfig.Retrieve("api.key"));
for setting values.
The challenge at the moment is updating a value in the Dictionary. The following works
CSSettings.Item("id") = Wfm_AccNumber;
it's just that it's non-standard JScript. What's more the JSHint tool that I'm using inside of Notepad++ complains.
I could do a .Remove() before the .Add(), I suppose but is there a better way?
The following should work:
CSSettings.Item.set("id", Wfm_AccNumber);
value = CSSettings.Item.get("id"); // or CSSettings.Item("id")
This may look a bit clunky, but it's standard JavaScript and should work with all .NET indexers (which aren't always named "Item", and can have more than one parameter).

CodeDom InitExpression for Typed Dictionary type

There are a couple of questions similar to this, on StackExchange, but they don't cover quite the same case. Please read it through before marking it as a duplicate!
Using CodeDom in C#, I'm trying to generate an Init Expression for a dictionary.
eg
Dictionary<int,string> dict = new Dictionary<int,string>{
{1,"one"},
{2,"two"}
};
I have found other solutions that use a CodeExpression to instantiate the object, and then several CodeStatements that populate the instance, but due to a bunch of boring reasons that's a path I'd rather not go down.
To clarify, since I can't use multiple CodeStatements, I kinda need to avoid generating something like this:
Dictionary<int,string> dict = new Dictionary<int,string>();
dict.Add(1,"one");
dict.Add(2,"two");
My question is: Is there a way to generate code like this using only CodeDom.CodeExpression(s)?
I'm pretty sure that at this point the answer is "no.", but thought it would be worth asking just in case.
As far as I can see, you can't express collection initializers in the CodeDOM object model. But there is a way to work around that: CodeSnippetExpression. Using that, you can create a string that directly contains any C# expression you want and use it inside another CodeDOM object.
You might be able to use the CodeDOM object model and GenerateCodeFromExpression() to get parts of the code you need (but you will certainly need to combine those parts by yourself).
No, if you want to use collection initializers you'll need to use LINQ Expressions instead of CodeDOM, e.g. System.Linq.Expressions.ListInitExpression.

Can't query/order on built-in rally fields "could not read all instances of class com.f4tech.slm.domain.Artifact"

I'm using v2.0 of the API via the C# dll. But this problem also happens when I pass a Query String to the v2.0 API via https://rally1.rallydev.com/slm/doc/webservice/
I'm querying at the Artifact level because I need both Defects and Stories. I tried to see what kind of query string the Rally front end is using, and it passes custom fields and built-in fields to the artifact query. I am doing the same thing, but am not finding any luck getting it to work.
I need to be able to filter out the released items from my query. Furthermore, I also need to sort by the custom c_ReleaseType field as well as the built-in DragAndDropRank field. I'm guessing this is a problem because those built-in fields are not actually on the Artifact object, but why would the custom fields work? They're not on the Artifact object either. It might just be a problem I'm not able to guess at hidden in the API. If I can query these objects based on custom fields, I would expect the ability would exist to query them by built-in fields as well, even if those fields don't exist on the Ancestor object.
For the sake of the example, I am leaving out a bunch of the setup code... and only leaving in the code that causes the issues.
var request = new Request("Artifact");
request.Order = "DragAndDropRank";
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I comment the Order by DragAndDropRank line, it works.
var request = new Request("Artifact");
request.Query = (new Query("c_SomeCustomField", Query.Operator.Equals, "somevalue").
And(new Query("Release", Query.Operator.Equals, "null")));
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I take the Release part out of the query, it works.
var request = new Request("Artifact");
request.Query = (((new Query("TypeDefOid", Query.Operator.Equals, "someID").
And(new Query("c_SomeCustomField", Query.Operator.Equals, "somevalue"))).
And(new Query("DirectChildrenCount", Query.Operator.Equals, "0"))));
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I take the DirectChildrenCount part out of the query, it works.
Here's an example of the problem demonstrated by an API call.
https://rally1.rallydev.com/slm/webservice/v2.0/artifact?query=(c_KanbanState%20%3D%20%22Backlog%22)&order=DragAndDropRank&start=1&pagesize=20
When I remove the Order by DragAndDropRank querystring, it works.
I think most of your trouble is due to the fact that in order to use the Artifact endpoint you need to specify a types parameter so it knows which artifact sub classes to include.
Simply adding that to your example WSAPI query above causes it to return successfully:
https://rally1.rallydev.com/slm/webservice/v2.0/artifact?query=(c_KanbanState = "Backlog")&order=DragAndDropRank&start=1&pagesize=20&types=hierarchicalrequirement,defect
However I'm not tally sure if the C# API allows you to encode additional custom parameters onto the request...
Your question already contains the answer.
UserStory (HierarchicalRequirement in WS API) and Defect inherit some of their fields from Artifact, e.g. FormattedID, Name, Description, LastUpdateDate, etc. You may use those fields in the context of Artifact type.
The fields that you are trying to access on Artifact object do not exist on it. They exist on a child level, e.g. DragAndDropRank, Release, Iteration. It is not possible to use those fields in the context of Artifact type.
Parent objects don't have access to attributes specific to child object.
Artifact is an abstract type.
If you need to filter by Release, you need to make two separate requests - one for stories, the other for defects.

How to define EDI data structure C090

I am attempting to create an API that will allow me to create and parse EDI messages in C#.
As a proof of concept and to keep it simple I am attempting to write a small class library to create a C090 data structure, which you can seehere
I am not sure how it's even possible to create properties for the 3286 data element as there are five of them. I don't really want to use arrays or lists for this and was wondering if there was any possible way of creating these as five properties, but without bastardizing them with underscores or numbers?
I have managed to find a way of creating the data structure by defining all of the elements of the composite using class attributes.
When calling the Append(Element) method it will check the definition to see if Element is part of the composite and throws an exception if it isn't, otherwise it will be added to the list, for example:
C090 c = doc.CreateComposite<C090>();
E3477 e = doc.CreateElement<E3477>();
e.Value = CodesList.E3477.Code001;
c.Append( e );
Seems to work great so far!

Code Generation for All CLR supported language using a CodeDomSerializer

I am implementing Code Generation for WindowsForm control at Design-Time, using a Custom CodeDomSerializer.
Here is what I have.
A user control i.e. MyControl written
in C#.
MyControl has a property
MyControlProperty of type ObjectXXX
that is accessible publicly.(like
myControl.MyControlProperty).
The type ObjectYYY has a public property
PropertyXXX of type Collection.
The ObjectXXX has a internal field of type ObjectYYY.
The ObjectXXX should be initialized by passing Collection (which
is nothing but ObjectYYY.PropertyXXX).
The code generated should be as given in the code snippet below.
Line1. NamespaceX.NamespaceY.ObjectXXX x = new NamespaceX.NamespaceY.ObjectXXX(NamespaceX.NamespaceY.ObjectYYY.PropertyXXX);
Line2. myControl.MyControlProperty = x;
I succeeded in generating the aforementioned code at Design-Time by writing a custom CodeDomSerializer FOR C# Language.
But, if i use MyControl for developing an application in C++ Language, the DOT operator is serialized for both ScopeResolution and Pointer-To-Member operator.
What I am doing for code in Line1 is,
string fullyQualifiedName = "NamespaceX.NamespaceY.ObjectYYY.PropertyXXX"; // HERE VARIABLE NAME IS HARDCODED WITH TWO TYPES OF OPERATORS
CodeExpression[] parameters = new CodeExpression[] {new CodeVariableReferenceExpression(fullyQualifiedName);};
CodeStatement code = new CodeVariableDeclarationStatement(typeof(ObjectXXX), "objectXXX1", new CodeObjectCreateExpression(new CodeTypeReference(typeof(ObjectXXX)), parameters));
generatedCode.Add(code); //generatedCode has the final code
For Line2,
CodeExpression codeLhs = new CodeVariableReferenceExpression(myControlVariable + "." + "MyControlProperty"); // HERE Pointer-To-Member IS HARDCODED AS DOT
CodeExpression codeRhs = new CodeVariableReferenceExpression("objectXXX1");
CodeAssignStatement codeAssignStmt = new CodeAssignStatement(codeLhs, codeRhs);
generatedCode.Add(codeAssignStmt); //generatedCode has the final code
Obviously the C++ Designer generated code should have '::' operator(and not DOT) for the ScopeResolution and '->' for the Pointer-To-Member resolution. I was not able to figure out how to make the code serialization for any CLR supported language.
How to solve this problem?
-Thanks a bunch
Dattebayo
Thanks for the quick reply.
I found the solution.
What i need was generating code containing property access and generating code for of .NET types.
To generate code that accesses a property, one should use CodePropertyReferenceExpression. This solves my problem with Line2.
To generate code that contains a Type, one should use Code CodeTypeReferenceExpression.
This combined with CodePropertyReferenceExpression solved problem with Line1.
Now, I am able to generate code properly w.r.t. the Language in use.
//For C# The code would be
NamespaceX.NamespaceY.ObjectXXX x = new NamespaceX.NamespaceY.ObjectXXX(NamespaceX.NamespaceY.ObjectYYY.PropertyXXX);
this.myControl.MyControlProperty = x;
//For C++ The code would be
NamespaceX::NamespaceY::ObjectXXX x = new NamespaceX::NamespaceY::ObjectXXX(NamespaceX::NamespaceY::ObjectYYY::PropertyXXX);
this->myControl->MyControlProperty = x;
Not sure if this will help, but have you looked at MyGeneration its a multi language code generator written in .Net. It doesn't use CodeDomSerializer, but it does generate good code - maybe it'll solve your underlying problem without having to re-invent the wheel?

Categories

Resources