Cull'log

Stefan Cullmann's Blogging

<September 2008>
SuMoTuWeThFrSa
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011


Navigation

CodeGen

Blog roll

Nice to have

Code Generation

Subscriptions

Post Categories

Article Categories



GotDotNet Workspaces

I tried to add an existing project to a solution that is placed under the source control of GotDotNet Workspaces. This finally results in nearly destroying my solution file, I can't save it under the original name. I am not able to check in or out using the visual studio workspace plug in any more. Opening the solution file again doesn't work. No Fun.

posted Sunday, March 28, 2004 7:53 PM by stefan@cullnet.de

Adventures writing Visual Studio Add-Ins

I thought it would be nice to integrate an ASP.NET like template language inside my Greenator-AddIn. Instead of reinventing the wheel, I decided to use the m3rlin.engine Assembly. m3rlin is a XML-centric templating code generator by Joseph Cooney. It generates code by hosting the ASP.NET runtime.
In my last post, I described an issue about creating an appdomain; which is needed to host the asp.net runtime. This problem was solved in signing the assembly and publishing the assembly in the GAC.
Today I examined another really strange behaviour inside of Visual Studio Add-Ins. M3rlin.engine calls HttpRuntime.AspInstallDirectory(), and that call gets me a System.ArgumentNullExeption (Parameter name str). First I thought that I might not be allowed to call it inside of a com interop. I decided to examine this in a separate add in. I generated a new visual studio add in (“AddInTest”) and placed the following code inside the Connect class.:

public void Exec(string commandName, EnvDTE.vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
     handled =
false
;
    
if
(executeOption == EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault)
     {
         
if
(commandName == "AddInTest.Connect.AddInTest")
          {
              
try
              
{
                   
string
x = System.Web.HttpRuntime.AspInstallDirectory;
                    MessageBox.Show (x);
               }
              
catch
(SystemException ex)
               {
                    MessageBox.Show (ex.GetType().ToString()+": "+ ex.Message);
               }
               handled =
true
;
              
return
;
          }
     }
}

I started the project and clicked the „AddInTest“ button and was surprised to get the wanted result: “C:\Windows\Microsoft.Net\Framework\v1.1.4322”. Opening a solution and executing the button again is still ok.
But starting VS-Studio, first opening a solution and then executing the button raises the System.ArgumentNullExeption. Even more confusing: it depends on the opened solution. Some of them will reproduce the error. others will give me the right result. I can't get why.

M3rlin.engine needs the value of HttpRuntime.AspInstallDirectory to set the “hostingInstallDir” of the created appdomain and run the ASP.NET host. I moved the function call inside of the new appdomain (AppDomain.CurrentDomain.SetData(".hostingInstallDir", HttpRuntime.AspInstallDirectory). Now every thing runs fine.

posted Sunday, March 28, 2004 7:41 PM by stefan@cullnet.de

Working with AppDomains inside a VisualStudio Add-In

The VisualStudio Add-In "MyTestPlugIn" is installed by default at %Program Files%\MyTestPlugIn. I have to create an AppDomain inside the Add-In and to create an instance of a Worker Class. This will result in an InvalidCastException.

This code is called from the exec command inside the connect class:

try
{
    AppDomainTest.Worker Worker = AppDomainTest.Factory.CreateWorker ();
    Worker.DoIt();
}
catch
(SystemException ex)
{
     MessageBox.Show (ex.GetType().ToString()+": "+ ex.Message);
}

The appdomain factory and worker class look like this: 

using System;
using System.Runtime.Remoting;
using System.Reflection;

namespace AppDomainTest

{
     public class
Worker:MarshalByRefObject 
     {
         
public
Worker(){}
         
public void
DoIt()
          {
              
System.Windows.Forms.MessageBox.Show ("Hello World");
          }
     }

     public class Factory
     {
         
public static Worker CreateWorker()
          {
               Assembly currentAssembly =Assembly.GetExecutingAssembly();
               AppDomain ad = AppDomain.CreateDomain("WorkerTest"); 
               ObjectHandle oh = ad.CreateInstanceFrom 
                         (currentAssembly.Location,
typeof(Worker).FullName );
              
return (Worker) oh.Unwrap(); //InvalidCastException
          }
     }
}

Note:
The call will work without raising an exception if called from a winform or console. It seems that the add-in assembly can not be found by visual studio to decide if it is the same assembly and type. As a matter of fact copying the add-in assembly inside the Visual Studio\common7\ide directory solves this problem.

But I don't want to place my add-in dlls at two different locations and certainly not under the Visual Studio Path.

Playing around with AppDomain.AppendPrivatePath, added an AppDomainSetup setting the ApplicationBase and PrivateBinPath but this problem remains unsolved.

posted Sunday, March 21, 2004 5:13 PM by stefan@cullnet.de

Greenator Documentation updated

Until now I finished three articles:

  • First steps using Greenator
  • "Simple" Template Language
  • Rules
  • posted Saturday, March 20, 2004 9:52 AM by stefan@cullnet.de

    Greenator V0.1 published

    Greenator V0.1 published at http://workspaces.gotdotnet.com/greenator!
    First steps in using Greenator are descriped in a  article.

    posted Friday, March 19, 2004 2:07 AM by stefan@cullnet.de

    HTML Generation vs. Code Generation

    Before talking about application code generation, let’s have a closer look at the generator techniques we are all familiar with; let’s examine html generators.

    In the old days, at the beginning of the internet time age, some geeks discovered very fast the power of generators. The first generators were written in C or Perl and got famous under the term CGI.

    Later some template language based generators like ASP and PHP appeared. A lot of people started to use them. The ice for html generation was broken.

    Later was recognized that it wasn’t really a good idea to mix code and design at one place. That’s one point what ASP.NET is about. Code and Design are now separated into two files. In addition an even higher abstraction level was introduced by using the OO features of the .NET Framework. We are now able to add objects like tables, rows and cells to controls without using a template. Due to this fact it is possible to create the output for different targets like Internet Browsers and mobile devices.

    Let’ summarize this in a fact sheet and compare it to active code generation:

     

    CGI

    ASP/PHP…

    ASP.NET/code behind

    name proposal

    script

    template language

    object model

    Code looks like

    write ("<table>");
    write ("  <tr>");
    write ("    <td>");
    write ("      "+content);
    write ("    </td>");
    write ("  </tr>");
    write ("</table>");

    <table>
       <tr>
          <td>
             <%=Content%>
         
    </td>
       </tr>
    </table>

    Table     table = new Table();
    TableRow  row   = new TableRow();
    TableCell cell  = new TableCell();
    cell.Controls.Add (new
             LiteralControl(content));
    row.Cells.Add (cell);
    table.Rows.Add (row);
    this.Controls.Add (table);

    viable for html creation

    yes

    yes

    yes

    ease of maintain source

    easy

    easy

    easy

    ease of pasting
    in sample code

    difficult

    easy

    nearly impossible,
    aside from
    controls.add(new literalcontrol(“…samplecode..”))

    presentiment of output

    yes

    yes

    no

    abstraction level

    low

    low

    high

    other benefits 

    total flexibility

    easy to read while developing

    output to multiple targets 

    application range

    closed application

    template based html generation

    user controls (compiled)

     

    Symmetries to application code generation/ using these to generate code instead of html

    CGIA

     tier generator 

    tier generator 

    code munger

    KaDGen

     brute force

    not mentioned *

    codeDOM 

     

     

     

     

    primary domain (IMHO)

     wizard

    template based code generation

    on the fly code generation,
    powerfull in conjunction with parser,
    code generation controls?

    * Using template languages in general is not mentioned in Code Generation in Microsoft .NET. Kathleen targets only XSLT, which is in fact a template language. But it is totally unfair to compare XSLT with “brute force” and codeDOM. That’s like explaining our modern road traffic like this: On the roads you will find trucks, busses and Porsches. And not telling that there are Ford, Mercedes, Toyota and many other cars too. By the way, I like her book very much. Kathleen has done an excellent work. I am just reading her second chapter, extracting Metadata.

    posted Wednesday, March 17, 2004 7:50 PM by stefan@cullnet.de

    Flashback

    At the end of the last century the corporate homepage of my employer celebrated its fourth birthday. The site was hosted by a provider who didn’t support any dynamic features like CGI. Most of the pages have been static and have been updated once in two month. There was only one exception; a calendar site that should always be actual. All changes have been transmitted to our external web designer. He adjusted the appropriate HTML page and sent it to our provider.
    I was asked to simplify that procedure. At this time I have never written a web page before. I knew the basics and started my first web adventure. I examined the current calendar page and guess what, it was a simple html table included in a customized head and footer. I moved the calendar data to an access database and wrote a small VB6 form. The data was edited in a grid and a click on a button produced the html file and uploaded it to our homepage with ftp. The html creating function looked something like that:

    Public Function MakeHTML(rs As recordset) as string
        Dim html As String
        html = html + "<html>"
        html = html + "  <body>"
        html = html + "    <table>"
        While Not rs.EOF
          html = html + "  <tr><td>"
          html = html + rs!Date + " " + rs!event
          html = html + "  </td></tr>"
          rs.MoveNext
        Wend
        html = html + "    </table>"
        html = html + "  </body>"
        html = html + "</html>"
        MakeHTML=html
    End function

    This calendar has been so popular that a subset of this data should have been published to a second internet domain. This page had a different design. Moreover the design of our home page changed frequently too. I changed my approach. I installed PHP locally and batched it from my application to produce the html pages. I can’t remember the proper PHP syntax, but the templates looked similar to that:

    <html>
       <body>
          <table>
    <? php while (not rs->eof): ?>
             <tr>
                 <td>
                      <?php echo rs->fields(“date”) +” “+ rs->fields(“event”);  % >
                 </td>
             </tr>
    <?php
        rs->MoveNext;
        end while; ?>
       </table>
    </body>
    </html>

    In my memory the creation of these html files are my really first steps in "code" generation. Ok, the output is not a programming language, just html. We use it daily in our asp.net, asp, php, jsp...pages. Nothing special. 
     
    By the way, until now the calendar is still present in internet. The dates are nowadays maintained in a Windows Sharepoint Service list inside our intranet. XSLT-Stylesheets transform the list on the fly to our customers at our home page.

    posted Tuesday, March 16, 2004 9:14 PM by stefan@cullnet.de

    Motivation III: Using XSLT as code generator

    I like XSLT. I use it on several occasions; mostly in asp.net context or sharepoint portal server. I am quit familiar with the XSLT syntax.

    Why start with code generation? It is no "hen or egg" question. The code you want to generate has been written several times by you. .Net has powerful libraries; you complemented them with your own. You refactored your code. But you couldn't avoid writing boring code again and again. You see the repeating pattern and starts to extract the metadata.

    All times I did this; I felt it naturally to write down this metadata in form of XML. No problem to build up hierarchies and transform the XML so it is a real abstraction of your domain. I invent my own tags and I am every time enthusiastic about the result.

    As I mentioned in a post yesterday, my first generator generated ascx User Contols. Because I knew XSLT, it was the self-evident idea to use XSLT to transform XML to a HTML-like syntax.

    Some weeks ago I had to wrap a set of web services with an object model. Writing the second class in this project I’ve caught the pattern and developed the abstraction as XML. Now I was looking for a code generator that targets C# and searched the web. First hit has been CodeSmith, I installed it and I was really disappointed. I recognized the well known ASP.NET like way, but I was shocked to see that CodeSmith force me to give up my XML representation and to transform it to a .NET based property set. ( to Eric: I studied “PurchaseOrderXML.cst”, that is not what I dream of, sorry). I can imagine requirements where CodeSmith will be the tool of my choice; if have to extract the Meta data out of a database or other sources.

    I remembered the XP wisdom “Do the Simplest Thing that Could Possibly Work". I know XSLT, it works. I know how to implement my generator using IE and notepad. That is simple. It doesn’t handicaps me in representing the metadata in its elemental form. Sole constraint: XSLT is different from C# or VB, so you will have a longer learning curve.

    It would be easier (not simpler) to have the generator integrated in my IDE: Visual Studio. That is why I started Greenator. Greenator has yet three different generators built in: XSLT, “Simple” and the possibility to configure an external generator like CodeSmith. In a later post I will show you my favourite, “Simple”.

    posted Monday, March 15, 2004 7:29 PM by stefan@cullnet.de

    Code Generation in Microsoft .NET: Generator types

    Today I got the book Code Generation in Microsoft .NET. I was really surprised, I have read the interviews with her at Code Generation Network but I was totally impressed of getting such a huge tome.

    In chapter one Kathleen Dollard distinguish between three main types of code generators; "brute force", CodeDOM and XSLT. In a comparison table she evaluates the ease of pasting in sample code: XSLT easy, "brute force" difficult and CodeDOM effectively impossible.

    I would agree totally but I think that one technique is totally missing; an ASP.NET like approach like CodeSmith, M3rlin, Cube or MyGeneration. CodeSmith and Cube uses "brute force" as engine behind, Cube loads the ASP.NET engine. Pasting in sample code into the templates is easy; the principle is powerful and familiar to all .NET users.

    I prefer the way of XSLT, mainly because you are not "overlaying the syntax of the output code with the code that runs the template".  But I will not ignore ASP.LIKE techniques.

    I can’t wait to read on.

    posted Monday, March 15, 2004 4:13 PM by stefan@cullnet.de

    Greenator Features: Visual Studio .Net integration

    VS .NET has a built in interface for integrating Code Generation called custom tool. Two Custom Tools (also called Generators) come with VS.NET, MSDataSetGenerator for strongly-typed DataSets, and MSDiscoCodeGenerator for WebService proxy classes.

    Once you have set the property custom tool the generator starts and generates a subordinate project item with the generated source. Every time you change and save your base definition file,  the source file is generated again.

    I like the transparent way how the generation works. In fact, at first sight it is a miracle how the strongly typed dataset is generated from a Schema.

    It is possible to write your own custom tools. All you need is to implement one function:

    public override byte[] GenerateCode(string file, string contents)
    {
    string code = "<<generated code>>";
    return System.Text.Encoding.ASCII.GetBytes(code);
    }


    On a second sight, this approach limits the scope for active code generation. Code generation should be under your control, you should e.g. set the templates to be used for the code generation. It is not possible to set a further argument inside the properties of the definition file.

    Some code generators that implement custom tool cheat; they add the reference of the template inside the model definition. That is not orthogonal.

    Furthermore it is not possible to generate two code files out of one model.

    Greenator is written as Visual Studio Add-In and for this reason Greenator is not limited by the design of custom tool. But Greenator supplements custom tools behaviour, it watches all templates and models and generates the code file or even files transparent on the fly every time it must.

    posted Sunday, March 14, 2004 9:40 PM by stefan@cullnet.de

    Motivation II

    I used consciously code generation one year ago. Nearly every day I was asked to implement and publish another contact form at our company’s homepage: Address fields, email address, custom validations…Actual a common task, but none of these forms looked like another, all of them asked for at least one different field. It was a stupid and boring. The approach was simple too: The form definition has been reduced to a xml based model. I used XSLT successful to transform these models to .ascx user controls.

    The model files have been maintained by some power users. They did not know much about XML, but they have been able to alter existing model files to their needs. My function was reduced to validate the assigned model, to run the transformation and to publish the output to a web server. The time was reduced from about one hour per form to few minutes. As a side effect oversights diasppeared.

    posted Sunday, March 14, 2004 8:00 PM by stefan@cullnet.de

    Motivation

    Did you ever have a "Deja vu" in your daily programming live? Do you have too the feeling of repeating again and again similar lines of code? Do you used to copy and paste your source code?

    No? You must be lucky. Perhaps you are using a language like ruby, which is dynamic enough to let be do what you want without leaving the language.

    Yes? But you worked hard, you have powerfull libraries. You have refactored your code again and again, but this feeling never moved away?

    Now its time for Code Generation!

    posted Sunday, March 14, 2004 6:51 PM by stefan@cullnet.de




    Powered by Dot Net Junkies, by Telligent Systems