Converting strings in to an expression trees? - c#

We have a requirement to provide user friendly descriptions for types. We have a created a resource file which maps the type to a description.
The full name of the instance with the dots replaced with underscores is used as the key.
The description is a string and contains templates that refer to property in the instance.
When we get an instance, we get its type, get the key, and use it to find the resource value. Then use regex to pull out those template properties. Then use reflection to actually get the value of the property.
for eg.
The instance may be Address
the key would be MyNameSpace_MyPublicTypes_Address(say the full name is'MyNameSpace.MyPublicTypes.Address ')
The description can be 'User stays in {State.City} in {Country}' -- State and Country are properties on the Address class. The State has a property City.
Is it possible to have something like
'obj=>obj.State.City' or 'obj=>obj.Country' ? or some sort of expression ?
I am using obj because it is the reflected instance.
Appreciate any help. Not sure if this question has been asked before.

This is pretty-much what the dynamic LINQ library (one of the .NET 3.5 samples) does. The source is all available, or for usage see here. You should be able to trace the code that parses the strings into Expressions. Of course, it isn't hard to split on . and assemble it manually; I have a dynamic OrderBy implementation here that does this.

Related

How to have early bound attribute names as string constants?

Context
I am using crmsvcutil to generate early bind entities. I am also utilizing entity name string constants MyEntity.EntityLogicalName for example in statements like the following (using alternate key):
var reference = new EntityReference(MyEntity.EntityLogicalName, "my_attribute_name", myValue)
Question
I would like to eliminate the "my_attribute_name" string literal in the statement. How can I do this?
Unfortunatelly I can not find it in the generated C# model.
Missed I something? If not, maybe there is an extension to crmsvcutil (similarly to the optionset generator sameple?
To answer the question, you can use the C# 6 nameof() expression to get the name of the property. If you convert the name to lower case, you end up with the logical name:
var logicalName = nameof(MyEntity.MyAttributeValue).ToLower();
With that being said, I rarely find myself having to do something like this. Often you can use Entity.ToEntityReference() for a more strongly typed approach.
Additionally the constructor you use for EntityReference is only meant to be used for alternate keys (otherwise one would just use the constructor that takes a string and a Guid)

Using SSDT as source for T4 templates

I have a SQL Server Data Tools (SSDT) project that has a number of stored procedures for which I would like to generate the C# code to call them using T4. Are there any existing examples for doing this?
So far, I can create a function per proc, but I'd really like to be able to tap into the meta data SSDT creates so I can get the parameters, data types, and return values from it rather than doing string parsing.
COOL WITH A CAPITAL C! (but don't tell anyone who uses an ORM!)
To get the datatypes etc make sure you grab the latest DacExtensions from the MS DacFx team:
https://github.com/Microsoft/DACExtensions
The new api (which incidentally is written using T4 templates) makes finding the info you need many many times simpler.
There should be enough information you need in this blog to get you going:
https://the.agilesql.club/Blogs/Ed-Elliott/DacFx-Create-tSQLt-Tests-From-A-Dacpac
The only difference is that you are creating C# and not T-SQL so you won't have to deal with the ScriptDom.
When you do this, please dump it on github it sounds like a really useful project.
To answer this question in the comments:
I can create methods with the correct parameters, but I'm struggling
to find where the objects are in the model are that represent the
content of a stored procedure. I need to know the columns returned by
a SELECT statement in order to generate the return objects. Any ideas?
The referenced objects are provided by the TSqlProcedure.BodyDependencies relationship. That will return objects referenced in the stored proc body, but won't tell you how they are used. The relational model doesn't try to embed this info as it doesn't help in deployment, but you can get it by querying the SQLDOM AST for the procedure.
The AST is a syntax tree defining the actual structure of the Procedure statement, including the structure of the procedur body. What you need to do is:
Create a Visitor that visits SelectStatement nodes (or their children)
Find the column names used in the select
Map these names to names of objects returned by TSqlProcedure.BodyDependencies. Now you have a rich object that can state the table the column is contained in, the column's data type, etc.
Do whatever you need to based on this (for example define a return type with the correct properties matching the column data types?)
A few notes / resources:
Ed's DacpacExplorer will help you view and understand the code.
Dave Ballantyne just added SQLDOM support to DacpacExplorer. Not only will this help you see what statements you need to match in the visitor, you should also look at how they use loadAsScriptBackedModel (see this commit) to ensure you have the full AST for the procedure body. Without this you would just get the body as one SqlScript object which isn't much use to you.
Further examples of the visitor pattern are Dave's TSqlSmells and the DacExtensions project
Twitter is an easy way to contact Ed, Dave and me if you are blocked :-)

Definition.Entity property is null

Whenever I create a ReloadableObjectRegistry with path to directory containing compiled modules, Definitions in the tree have Entity property set to null. The reason why I need to access this property is to be able to read the syntax of a definition.
I suspect, the Entity property only gets set after parsing a MIB... Is this a correct assumption? How else can I find out definition's syntax? The Type property is always 'Unknown'.
Sample code:
private ReloadableObjectRegistry Objects;
Objects = new ReloadableObjectRegistry(#"some_path");
P.S. By the looks of it, parsed module (.module) does not have any information about MIB Types in it.
The open source edition SharpSnmpLib.Mib was designed that way, where most of the classes are just placeholders.
If you do need to learn the syntax, you have to use SharpSnmpPro.Mib at http://sharpsnmp.com.
A sample project has been published on GitHub to demonstrate usage of the new APIs.

what will be the Regular Expression to get all the property and variables names of a class in c#?

What will be the Regular Expression to get all the property and variables names of any class in c#, I want to parse the *.cs file. that is i want to select any *.cs file as input and it should get the property name of that selected class, as an output.
can any one help!!!....would appreciate for any help i tried very much but not got the actual result every time class name is coming instead of property.
thanks
Jack
There's no way you're going to be able to get exactly what you want with a regular expression because you need semantic context, not just string parsing.
For example, a good first attempt at finding all of the field and property definitions in a C# file might go something like this
^\s*(?:(?:private|public|protected|internal)\s+)?(?:static\s+)?(?:readonly\s+)?(\w+)\s+(\w+)\s*[^(]
That will match properties (public int Foo {...}) and fields (private int foo;) but not methods (protected void Bar()).
The problem is that a regex engine has no concept of the context within which those tokens appear. It will match both foo and bar in this code:
int foo;
void Stuff()
{
int bar;
}
If you happen to know that your code file follows some coding standards, you may have more luck. For example, if you enforce a style rule that all class members must have access specifiers, then you can make the private/public/etc part of that regex non-optional; since those are only permitted at the class level, it will filter out local variables.
There are other options, none of them too attractive at first glance. There is persistent talk from the C# dev team about exposing the C# compiler as a service in some future version of .NET, which would be perfect here, but I wouldn't expect that any time soon. You could purchase a third-party C# parser/analyzer like this one (caveat: I have zero experience with that, it's just the first Google hit). You could try compiling the .cs file using csc and examining the IL, but you'd need to know all of the third-party references.

.Net/C# Reflection--Populating ComboBox

Greetings all,
I have a list of "Types" meeting a certain critera that I obtained through reflection. Each of the types is a different feature that the user will potentially choose at runtime. If I add more subclasses later, this dynamic implementation would save my having to remember to update the user control is the idea here.
The list of types is nice, but it'd be nice to display something more meaningful than the Name as it's written in code. For example, instead of "RacingBikeDesigner", I'd like to display "Racing Bike Designer", and maybe even display other properties associated with that type like "Description" so that the user knows what that particular choice does.
So I guess the question is, given a Type, how can I provide a more meaningful representation to the user? Could I maybe add a static field to each subclass and call that from the Type, or could I perhaps use a type converter somehow?
The user control (ListBox, ComboBox, etc) is bound to the return value below, but it's not user-friendly:
List<string> LeftHandedUserChoices = new List<string>();
Type[] AllTypesInThisAssembly = Assembly.GetAssembly(typeof(UserChoices)).GetTypes();
foreach (Type _currentType in AllTypesInThisAssembly)
if (_currentType.IsSubclassOf(typeof(UserChoices)))
LeftHandedUserChoices.Add(_currentType.Name);
return LeftHandedUserChoices;
Cheers,
Q
You have a couple of options for doing this. You could use an attribute on your type for the description, or put it in a static field/property on the Type and retrieve that using reflection.
If localization is an issue, you will probably want to store the resource string name, and display the resource value at runtme.
Add custom C# Attributes to your types.
One method is for you to parse class names based on the naming convention you are using (looks like Pascal in your case). For instance RacingBikeDesigner will become Racing Bike Designer. Here is a parsing example.

Categories

Resources