C# code generation - c#

i'm about to make a graduation project application
this application is gonna some way receive a description for a situation , and then accordingly generate c# code
i want to know in what field i need to search or how to autogenerate C# code

Have a look at Kathleen Dollard's book on this if you can. She has a website for this topic as well.
You have three options essentially:
Brute-force - creating the code files yourself in a text file
CodeDOM generation - MS's built in way of creating code.
XSLT - What Kathleen uses.

T4 templates can help too -
http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx
And you could also generate IL on the fly. ;)

CodeDOM
I've done a wrapper around codedom. You only need to create your own C# script and specify the types being used.
Example
public interface IWorld
{
string Hello(string value);
}
string code = #"namespace MyNamespace
{
class Temp : IWorld
{
public string Hello(string value)
{
return "World " + value;
}
}
}";
Compiler compiler = new Compiler();
compiler.AddType(typeof(string));
compiler.Compile(code);
var obj = compiler.CreateInstance<IWorld>();
string result = obj.Hello("World!");
Note that it was a long time ago that I wrote it. The example might not work 100%. (The Compiler class do work, the example might use it incorrectly).
Compiler source code: http://fadd.codeplex.com/SourceControl/changeset/view/65227#925984
Reflection.Emit
You can also generate IL using Reflection.Emit: http://msdn.microsoft.com/en-us/library/3y322t50.aspx
It's a bit harder but more flexible, since CodeDOM generates a new Assembly each type you compile code.

There is a set of MatLab tools that generates C/C++ code from state-charts and data-flow diagrams:
Real Time Workshop
Real-Time Workshop Embedded Coder
Stateflow Coder
You should dig into it.
What will be the "description of a solution" in your case?

Related

C# code expansion/injection in compile time

I'm looking for a way to expand/inject code at compile time,
something like templates/macros/snippets...
Let's say I wrote this code in a lot of places in my application:
[JsonObject("MyProperty")]
private string MyPropertyJson { get; set; }
public object MyProperty { get; set; }
The MyPropertyJson property is used for EF mapping purposes only so I save the value is a JSON string in DB but for class users, they only know about MyProperty property.
What I want to do is, at compile time, MyPropertyJson to be expanded to this:
private string MyPropertyJson
{
get
{
return JsonConvert.SerializeObject(MyProperty);
}
set
{
MyProperty = JsonConvert.DeserializeObject(value);
}
}
I want this to be done in the output binaries only without affecting the source code.
I know about Unity, PostSharp, Aspect-Injector, etc.. but they don't achieve what I want because by using them, I have to use some reflection to find & manipulate MyProperty but I want to expand it exactly like it's been written in the same class with access to all class internals.
It's exactly like code snippets but to be expanded during compilation phase.
A solution that doesn't cost anything extra and is supported within Visual Studio is T4 aka Text Templates. However, it does require you install the VS SDK (eg, 2015) and Modeling SDK (eg, 2015) of the version of VS that you use.
For my base class libraries, I end up dedicating an assembly for utils to use in the T4 code I write in production code. I use it in places like rolling out read/writes for primitives in IO code (eg, .TT and .CS). Although you don't have to do this if you don't need much/complex compile time code gen.
I was able to achieve my requirement by writing a BeforeBuild msbuild target to call an external console app which I've developed to:
Copy source files that will be rewritten to a temp folder
Rewrite the source code in the temp files
Added conditional Compile tag to the .csproj file to include manipulated source files instead of the original ones
It works like a charm :)
I'm working on a generic engine for this task and will commit it to github once finished.
The is a way to kind of get what you want.
Using implicit operators
That would need to create your own json object class for example, then add these:
class JsonObject {
public object obj;
public static implicit operator string(JsonObject target) {
return Json.SerializeObject(target.obj);
}
}
But that won't really do what you really wanted. Almost the same as creating a new class and add functions.

Creating new Excel formulas/functions with C#

We are looking to be able to programmatically create an Excel workbook which would call custom code from within a cell. Cells would look something like:
=MyCode(A1:A10)
My first thought was to use VBA, but since the algorithm is proprietary the powers that be want it to be protected. I can put a password on it, but it is well documented (here on StackOverflow) on how to get around such passwords.
My second thought was to create an Excel 2013 Workbook project in Visual Studio, but I haven't found anything useful on how to expose a function in C# so it can be called like I described.
Next I thought about having VBA call the C#, and found instructions at https://msdn.microsoft.com/en-us/library/bb608613.aspx. I followed those instructions to the letter, but when I try to run the VBA code I get an error with the GetManagedClass function: Object Library Feature not Supported.
Are there any good references on how to do something like this?
You're looking for Excel-DNA.
This open-source library allows you to create managed Excel add-ins, and supports making user-defined functions, but also macros, real-time RTD data sources etc.
Creating an Excel UDF in C# is then as simple as:
[ExcelFunction(Description = "My first .NET function")]
public static string SayHello(string name)
{
return "Hello " + name;
}
and you can call from a cell as:
=SayHello("Walter")
For code protection with .NET, you'd need to use an obfuscator - there are a variety of free and paid-for ones available.
I have also tried this sample, with the same error. I found a solution that worked for me.
In the ISheet1.cs file, replace the ISheet1 interface declaration with the following code. This code makes the ISheet1 interface public, and it applies the http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.comvisibleattribute.aspx attribute to make the interface visible to COM.
C#
[System.Runtime.InteropServices.ComVisible(true)]
public interface ISheet1
{
void CreateVstoNamedRange(Microsoft.Office.Interop.Excel.Range range, string name);
}
Full article her: http://www.nullskull.com/q/10059408/c-code-to-set-excel-workbook-macro-enabled-and-to-trust-vba-projects.aspx

Parsing C# code for contextually aware semantic highlighting

I'm working on a semantic highlighting plugin for VS. Here you can see a web Example.
The goal:
Acquiring all variables and creating different Classifications for every one of them.
The problem:
Getting the variables from the code without writing a C# lexer.
My current approach uses an ITagger. I use an ITagAggregator to get the tags of all the spans that get passed to the ITagger. Then I filter those and get only spans with the "identifier" classification which includes varibles, methods names, class names, usings and properties.
public class Classifier : ITagger<ClassificationTag> {
public IEnumerable<ITagSpan<ClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
ITextSnapshot snapshot = spans[0].Snapshot;
var tags = _aggregator.GetTags(spans).Where((span) => span.Tag.ClassificationType.Classification.Equals("identifier")).ToArray();
foreach(var classifiedSpan in tags) {
foreach(SnapshotSpan span in classifiedSpan.Span.GetSpans(snapshot)) {
//generate classification based on variable name
yield return new TagSpan<ClassificationTag>(span, new ClassificationTag(_classification));
}
}
}
}
It would be a lot easier to use the builtin C# Lexer to get a list of all variables bundled to a bunch of meta data. Is this data available for plugin development? Is there an alternative way I could acquire it, if not?
The problem: Getting the variables from the code without writing a C# lexer.
Roslyn can do this: https://roslyn.codeplex.com/
There's even a Syntax Visualizer sample that might interest you. I also found an example using Roslyn to create a Syntax Highlighter.
Visual Studio exposes that information as a code model.
Here is an example how you can access class, and then find attribute on the class, and parse attribute arguments:
Accessing attribute info from DTE
Here is more information about code models:
http://msdn.microsoft.com/en-us/library/ms228763.aspx
Here's also automation object model chart what I've been using quite few times: http://msdn.microsoft.com/en-us/library/za2b25t3.aspx
Also, as said, Roslyn is indeed also a possible option. Here is an example for VS2015 using roslyn: https://github.com/tomasr/roslyn-colorizer/blob/master/RoslynColorizer/RoslynColorizer.cs
For building language tools if may be better to use a parser generator for C#. The GOLD parsing system is one such toolkit which can handle LALR grammars. It has a .NET component based engine that you can use in your project and it can be used to integrate with any IDE. You can also find the grammars for various programming languages including C#.

Getting a specific method source code from .cs file (at runtime)

1 - I have this file content on the disc (cs file, not compiled):
namespace Test
{
using System;
public class TestClass
{
public string SomeTestMethod(){
return "test here";
}
}
}
How do I get in run time into a variable the method:
public string SomeTestMethod(){
return "test here";
}
for example: SourceCodeParser.GetMothod("path to file","SomeTestMethod");
2 - Is it possible the content of accessor member?
public string SomeMember {
get {
return "test here";
}
}
Roslyn is what you need. You can easily install it using nuget. Here is a working code for getting a method body:
string GetMethod(string filename, string methodName)
{
var syntaxTree = SyntaxTree.ParseFile(filename);
var root = syntaxTree.GetRoot();
var method = root.DescendantNodes()
.OfType<MethodDeclarationSyntax>()
.Where(md => md.Identifier.ValueText.Equals(methodName))
.FirstOrDefault();
return method.ToString();
}
and code for getting body of property getter:
string GetPropertyGetter(string filename, string propertyName)
{
var syntaxTree = SyntaxTree.ParseFile(filename);
var root = syntaxTree.GetRoot();
var property = root.DescendantNodes()
.OfType<PropertyDeclarationSyntax>()
.Where(md => md.Identifier.ValueText.Equals(propertyName))
.FirstOrDefault();
var getter = property.AccessorList.Accessors.First(a => a.Kind == SyntaxKind.GetAccessorDeclaration);
return getter.ToString();
}
You need a tool that can parse the source code, tracks code locations, and knows how to look up methods (or variables, or whatever named thing you care about) in the source code. With that, finding the lines of interest is pretty easy. Such a tool isn't easy to build because parsers for full languages aren't easy to build. Nor are the lookup functions easy; parameters, namespaces, templates, inheritance all combine to make name lookup for modern languages remarkably complex.
Program transformation (PT) tools (which often have such full parsers already available) often do this by building an AST in memory which represents the code. Then, given rules for name lookup, finding the code in the AST by name is relatively straightforward, and one can use the prettyprinter function of such a tool to pretty print the named-entity into a buffer/string/diskfile wherever you want it parked.
You are not likely to find a PT as a subroutine you can call from C# directly. You may be able to invoke such a tool from your program, and have it return the string as a text result/in a file/via a pipe whatever you thinks is best for interprocess communication.
If you want to show the method text embedded in an HTML page, you can often configure the PT to generate the entire page containing the prettyprinted entity text. (See the JavaSource browser via my bio for an example like this).
The .NET Reflection class does not support decompiling to C#. The best you can do is use MMethodInfo.GetMethodBody() and call MethodBody.GetILAsByteArray() on the response. That will give you the MSIL which is the best that .NET reflection can give you.
To decompile to C# you will need a decompiler - of which there are at least a dozen legitimate options. You'll need to investigate for one that meets your requirements and budget.
One option is Red Gate's .NET Reflector. Nick Harrison has a long and thorough article on using .NET Reflector in an application to render source code as HTML.

Creating T4 templates at runtime (build-time)?

We are building an inhouse application which needs to generate HTML files for upload into eBay listings. We are looking to use a template engine to generate the HTML files based on database and static fields that we have pre-defined. The template also needs to have logic capabilities (if-then, foreach, etc).
We have looked at T4 and it looks perfect, but we don't see anything about whether it has the capabilities to be used at runtime, so that a user can create the T4 template, and then the application can "compile" it and generate the final HTML file. Is this possible, and how?
If not, are there other frameworks we should be looking at that has all these capabilities?
I have a similar set of classes that I use for this, embedding templated text generation into software.
Basically, it works like old-style ASP, you surround C# code in <%...%> blocks, and you can emit results by using <%= expression %>.
You can pass a single object into the template code, which of course can be any object type you like, or simply an array of parameters. You can also reference your own assemblies if you want to execute custom code.
Here's how emitting a class would look:
<%
var parameters = (string[])data;
var namespaceName = parameters[0];
var className = parameters[1];
%>
namespace <%= namespaceName %>
{
public class <%= className %>
{
}
}
You can of course loop through things:
<% foreach (var parameter in parameters) { %>
<%= parameter %>
<% } %>
and put code in if-blocks etc.
The class library is released on CodePlex here:
CodePlex: TextTemplate
as well as on NuGet.
The project comes with examples, download the source or browse it online.
To answer questions by email also here, for others to see:
All types of C# code that fit into a method call can be compiled in the template. It runs normal C# 3.5 code, with everything that means, there's no artificial limits. Only things to know is that any if, while, for, foreach, etc. code that contains template code to emit must use braces, you cannot do a single-line if-then type block. See below for the method-call limitation.
The data parameter corresponds to whatever was passed in as the parameter to the .Generate(x) method from your application, and is of the same type. If you pass in an object you have defined in your own class libraries, you need to add a reference to the template code in order to properly access it. (<%# reference your.class.library.dll %>)
If you reuse the compiled template, it will in essence only be a method call to a class, no additional overhead is done on the actual call to .Generate(). If you don't call .Compile() yourself, the first call to .Generate() will take care of it. Also note that the code runs in a separate appdomain, so there's a slight marshalling overhead related to copying the parameter and result back and forth. The code, however, runs at normal JITted .NET code speed.
Example of if-block:
<% if (a == b) { %>
This will only be output if a==b.
<% } %>
There's no artificial limits on formatting the code either, pick the style that suits you best:
<%
if (a == b)
{
%>
This will only be output if a==b.
<%
}
%>
Only note that all non-code parts of the template will pretty much be output as-is, which means tabs and such following %> blocks will be output as well.
There is one limit, all the code you write must fit inside a single method call.
Let me explain.
The way the template engine works is that it produces a .cs file and feeds it to the C# compiler, this .cs file roughyly looks like this:
using directives
namespace SomeNamespace
{
public class SomeClass
{
public string Render(object data)
{
... all your code goes here
}
}
}
This means that you cannot define new classes, new methods, class-level fields, etc.
You can, however, use anonymous delegates to create functions internally. For instance, if you want a uniform way of formatting dates:
Func<DateTime, string> date2str = delegate(DateTime dt)
{
return dt.ToString("G");
};
then you can simply use that in the rest of the template code:
<%= date2str(DateTime.Now) %>
Only requirement I have is that you don't upload the files onto the web and claim you wrote the code, other than that you're free to do what you want with it.
Edit 23.04.2011: Fixed links to CodePlex project.
If you can use Visual Studio 2010 for template creation and editing, then you can use precompiled templates, which were designed for exactly this scenario and are the supported option from Microsoft.
You design the template in Visual Studio, precompile it and deploy an assembly that has no dependencies on Visual Studio along with your application.
http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/
The assembly that implements T4 text transformation is Microsoft.VisualStudio.TextTemplating.dll, which ships with Visual Studio.
If you want to start from first principles, you need to implement Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost, and pass your implementation of it as an argument to Microsoft.VisualStudio.TextTemplating.Engine.ProcessTemplate(), which will perform the transformation.
This gives you more flexibility than calling out to TextTransform.exe.
However, if your code is a shipping product, it is unclear what the licensing of this assembly is, and whether you have the rights to redistribute it with your application.
Redistributing this assembly would avoid the need for Visual Studio to be installed.
The T4 templates can be compiled with the TextTransform.exe command line tool. You
could have your application create a .tt file, then call TextTransform.exe to generate the output.
It is completely possible to use T4 at runtime.
Microsoft doesn't really support this scenario in any reasonable way in .NET 3.5. It sounds like .NET 4.0 will have better support from Microsoft.
Mono does provide some support for this scenario in .NET 3.5.
I have proven out this concept successfully with .NET 3.5 with help from the Mono T4 implementation, but an off the shelf solution for this problem for .NET 3.5 would require a ton more effort than I have invested so far.
You can find the Mono T4 implementation here:
https://github.com/mono/monodevelop/tree/master/main/src/addins/TextTemplating
I have documented some of the issues I encountered trying to run T4 templates from .NET code here:
Options for running T4 templates from .NET code
One mistake I made is I added a "Text Template" file. To generate text at runtime, pick the "Preprocessed Text Template" instead. If you originally picked "Text Template", it's an easy change to set the Custom Tool to "TextTemplatingFilePreprocessor" in the file properties in VS.
Liquid might be a good choice for this. This is an open-source template language, read more about the language here:
https://shopify.github.io/liquid/
Here is an implementation for .NET:
https://github.com/dotliquid/dotliquid
The syntax is quite nice. Here is some sample code for C#:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Friends { get; set; }
}
static void Main(string[] args)
{
Template.RegisterSafeType(typeof(Person), new string[]
{
nameof(Person.Name),
nameof(Person.Age),
nameof(Person.Friends),
});
Template template = Template.Parse(
#"<h1>hi {{name}}</h1>
<p>You are{% if age > 42' %} old {% else %} young{% endif %}.</p>
<p>You have {{ friends.size }} friends:</p>
{% assign sortedfriends = friends | sort %}
{% for item in sortedfriends -%}
{{ item | escape }} <br />
{% endfor %}
");
string output = template.Render(
Hash.FromAnonymousObject(
new Person()
{
Name = "James Bond",
Age = 42,
Friends = new List<string>()
{
"Charlie",
"<TagMan>",
"Bill"
}
} ));
Console.WriteLine(output);
/* The output will be:
<h1>hi James Bond</h1>
<p>You are young.</p>
<p>You have 3 friends:</p>
<TagMan> <br />
Bill <br />
Charlie <br />
*/
}

Categories

Resources