<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-18278253</id><updated>2011-11-01T00:38:56.941-07:00</updated><title type='text'>code dojo</title><subtitle type='html'>"the art of coding without coding"       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mario.l.gutierrez _at_ gmail.com</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>50</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-18278253.post-114597865266043997</id><published>2006-04-25T08:24:00.000-07:00</published><updated>2006-04-25T08:24:12.670-07:00</updated><title type='text'>LCD Image Persistence</title><content type='html'>&lt;p&gt;Most of us have long forgotten about CRT burn-in that plagued early monitors. Did you know LCDs have a similiar problem? It happened last night on my high-end 20" LCD. Image persistence results from displaying a static image on your screen for an extended period of time. In my case, it was a black color scheme for Windows. The icon and title 'persisted' on my screen. I usually work in maximized mode meaning the windows title bar for any application is at the top. I'm stumped, however, why my taskbar doesn't have the same symptoms. (I autohid it to check).&lt;/p&gt;&lt;p&gt;Fortunately this state is reversible in most cases. I am following Apple's advice since I need to use my computer:&lt;/p&gt;&lt;p&gt;&lt;a href="http://docs.info.apple.com/article.html?artnum=88343"&gt;Avoiding image persistence on Apple LCD displays&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I went beyond the white background and switched to a Milk scheme for windows. I've noticed an improvement over night. There's still a slight hint of persistence which I hope will disappear in the next couple of days.&lt;/p&gt;&lt;p&gt;The other recommended solution is to shut off the LCD for several days. I'm not sure why this would be more  effective than say shutting it off for one day. I'll try it if Apple's recommendation doesn't remedy the problem.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114597865266043997?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114597865266043997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114597865266043997' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114597865266043997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114597865266043997'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/04/lcd-image-persistence.html' title='LCD Image Persistence'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-114515984493893220</id><published>2006-04-15T20:15:00.000-07:00</published><updated>2006-04-15T20:59:17.823-07:00</updated><title type='text'>XmlUnit</title><content type='html'>&lt;p&gt;&lt;a href="http://xmlunit.sourceforge.net"&gt;XMLUnit&lt;/a&gt; is a utility class to aid unit testing of XML processing. I've used it before but gave up on it too quickly mainly because it didn't ignore whitespace. I'm inundated with XML work. XMLUnit's differencing is too strict and is not very useful for me in its current state. So I downloaded the source, made it compliant with &lt;a href="http://nunit.org"&gt;NUnit 2&lt;/a&gt;, modified a few unit tests so they run successfully from &lt;a href="http://www.testdriven.net/"&gt;TestDriven.NET&lt;/a&gt; and finally added a property to ignore whitespace differences.&lt;/p&gt;&lt;p&gt;These two XML are now considered equal:&lt;/p&gt;&lt;pre&gt;
string control = "&amp;lt;a color=' red'&amp;gt;&amp;lt;empty/&amp;gt;APPLE ORANGE&amp;lt;/a&amp;gt;";
string test = "&amp;lt;a color=\"red\"&amp;gt;&amp;lt;empty&amp;gt;        \t\r\n&amp;lt;/empty&amp;gt;          APPLE   ORANGE          &amp;lt;/a&amp;gt;";
XmlAssert.AreSimiliar(control, test);
&lt;/pre&gt;&lt;p&gt;Notice the library treats these as similiar (not identical): &lt;/p&gt;&lt;ul&gt;&lt;li&gt;"&lt;tt&gt;&amp;lt;empty/&amp;gt;&lt;/tt&gt;" == "&lt;tt&gt;&amp;lt;empty&amp;gt; &amp;lt;empty/&amp;gt;&lt;/tt&gt;" &lt;/li&gt;&lt;li&gt;&lt;tt&gt;"APPLE ORANGE"&lt;/tt&gt; == &lt;tt&gt;" APPLE ORANGE "&lt;/tt&gt; &lt;/li&gt;&lt;li&gt;&lt;tt&gt;"red"&lt;/tt&gt; == &lt;tt&gt;'red'&lt;/tt&gt; (use of single or double quotes for attributes)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I no longer have to worry about my xml editor reformatting my files and finding out later all my unit tests are broken. I'm considering starting a new project based on XMLUnit so I may enhance it and also rename methods to align it more closely with NUnit.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114515984493893220?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114515984493893220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114515984493893220' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114515984493893220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114515984493893220'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/04/xmlunit.html' title='XmlUnit'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-114515716699160430</id><published>2006-04-15T20:03:00.000-07:00</published><updated>2006-04-15T20:15:21.930-07:00</updated><title type='text'>XSLT: How to autonumber all elements and attributes.</title><content type='html'>&lt;p&gt;I'm doing more XSLT transformations and there's a lot of mapping to be done. I want to automate as much of the testing as I can. The first thing in order is how do I easily create a control sample so I can automate all attributes and fields mapped? Another stylsheet of course.&lt;/p&gt;&lt;pre&gt;
&amp;lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"&amp;gt;
    
    &amp;lt;xsl:output indent="yes" encoding="utf-8"/&amp;gt;
    &amp;lt;xsl:template match="/"&amp;gt;
        &amp;lt;xsl:apply-templates /&amp;gt;
    &amp;lt;/xsl:template&amp;gt;

    &amp;lt;xsl:template match="text()"&amp;gt;
        &amp;lt;xsl:number level="any" format="0001" count="text()|@*"/&amp;gt;
    &amp;lt;/xsl:template&amp;gt;
    
    &amp;lt;xsl:template match="@*"&amp;gt;
        &amp;lt;xsl:attribute name="{name()}"&amp;gt;
            &amp;lt;xsl:number level="any" format="0001" count="text()|@*"/&amp;gt;
        &amp;lt;/xsl:attribute&amp;gt;
        
    &amp;lt;/xsl:template&amp;gt;
        
    &amp;lt;xsl:template match="*"&amp;gt;
        &amp;lt;xsl:copy&amp;gt;
            &amp;lt;xsl:apply-templates select="@*|node()"/&amp;gt;
        &amp;lt;/xsl:copy&amp;gt;
    &amp;lt;/xsl:template&amp;gt;
&amp;lt;/xsl:stylesheet&amp;gt;
&lt;/pre&gt;&lt;p&gt;This simple stylesheet replaces the value of all attributes and elements with a sequential number  from 0001 to &lt;tt&gt;n&lt;/tt&gt;. The result looks like this.&lt;/p&gt;&lt;pre&gt;
&amp;lt;recipes&amp;gt;
    &amp;lt;recipe name="0001" prep_time="0002" cook_time="0003"&amp;gt;
        &amp;lt;title&amp;gt;0004&amp;lt;/title&amp;gt;
        &amp;lt;ingredient amount="0005" unit="0006"&amp;gt;0007&amp;lt;/ingredient&amp;gt;
        &amp;lt;ingredient amount="0008" unit="0009"&amp;gt;0010&amp;lt;/ingredient&amp;gt;
        &amp;lt;ingredient amount="0011" unit="0012" state="0013"&amp;gt;0014&amp;lt;/ingredient&amp;gt;
        &amp;lt;instructions&amp;gt;
            &amp;lt;step&amp;gt;0015&amp;lt;/step&amp;gt;
            &amp;lt;step&amp;gt;0016&amp;lt;/step&amp;gt;
            &amp;lt;step&amp;gt;0017&amp;lt;/step&amp;gt;
        &amp;lt;/instructions&amp;gt;
    &amp;lt;/recipe&amp;gt;
&amp;lt;/recipes&amp;gt;
&lt;/pre&gt;&lt;p&gt;This line needs a little explanation.&lt;/p&gt;&lt;pre&gt;
&amp;lt;xsl:number level="any" format="0001" count="text()|@*"/&amp;gt;
&lt;/pre&gt;&lt;p&gt;It says, create a counter for element text (&lt;tt&gt;text()&lt;/tt&gt;) or attribute value (&lt;tt&gt;@*&lt;/tt&gt;) encountered at any level, then format the number returning a four-digit number with leading zeros. The rest 
of the stylesheet is a modified &lt;tt&gt;identity&lt;/tt&gt; template.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114515716699160430?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114515716699160430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114515716699160430' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114515716699160430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114515716699160430'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/04/xslt-how-to-autonumber-all-elements.html' title='XSLT: How to autonumber all elements and attributes.'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-114493985255175439</id><published>2006-04-13T07:50:00.000-07:00</published><updated>2006-04-13T09:58:21.673-07:00</updated><title type='text'>XslTransform and xsl:document() woes</title><content type='html'>&lt;p&gt;This little .NET &lt;strong&gt;&lt;em&gt;feature&lt;/em&gt;&lt;/strong&gt; consumed half my day (sarcasm intended). &lt;a href="http://www.topxml.com/XmlDocument/re-1101_Calling-document-in--NET.aspx"&gt;XslTransformation and document('')&lt;/a&gt;. .NET XSL transformations may behave unexpectedly when a stylesheet invokes the &lt;tt&gt;xsl:document()&lt;/tt&gt; function. The &lt;b&gt;same&lt;/b&gt; stylesheet results in two different outputs. If the stylesheet is loaded from a URI, such as a file, transformations produce expected results. Loading the stylesheet from a stream or  a string, however, requires the workaround as described in the article above.&lt;/p&gt;&lt;p&gt;Why would one opt to load a stylesheet from a &lt;tt&gt;Stream&lt;/tt&gt; or &lt;tt&gt;string&lt;/tt&gt;? I prefer to embed test files and test stylesheets into an assembly by selecting the &lt;tt&gt;Embedded Resource&lt;/tt&gt; action in Visual Studio.  This is a neat trick if building  with both &lt;tt&gt;NAnt&lt;/tt&gt; and Visual Studio. Most &lt;tt&gt;NAnt&lt;/tt&gt; projects build assemblies into a &lt;tt&gt;build&lt;/tt&gt;, &lt;tt&gt;dist&lt;/tt&gt; or &lt;tt&gt;bin&lt;/tt&gt; directory. Visual Studio defaults to &lt;tt&gt;bin\debug&lt;/tt&gt; and &lt;tt&gt;bin\release&lt;/tt&gt;. An embedded resource always  has the same path regardless where your assembly is located.&lt;/p&gt;&lt;p&gt;Loading a stylesheet from a non-URI location may reduce I/O as hinted in the article above. XSLT is ubiquitous. As sectors move towards standardization stylesheets become larger and larger. Most developers laboriously  map one element to another. I treat XSLT as a cool programming language with a funky syntax. XML is structured and soon a resourceful developer realizes there's a pattern to the transformation. I tend to use lookup tables with the &lt;tt&gt;xsl:document()&lt;/tt&gt; function. Resolving &lt;tt&gt;document('')&lt;/tt&gt; to memory instead of a file reduces I/O.&lt;/p&gt;&lt;p&gt;I created a utility function to load stylesheets that use &lt;tt&gt;xsl:document()&lt;/tt&gt;.&lt;/p&gt;&lt;pre&gt;
XmlReader stylesheet = XmlUtils.LoadNonUriStylesheet(IOUtils.OpenEmbeddedResource("res/test.xls"));
&lt;/pre&gt;&lt;p&gt;&lt;tt&gt;LoadNonUriStylesheet&lt;/tt&gt; loads the stylesheet assigning it an arbitrary URI. The URI is resolved by a custom resolver during transformation. &lt;tt&gt;OpenEmbeddedResource&lt;/tt&gt; converts the &lt;tt&gt;res/test.xls&lt;/tt&gt; path to a fully qualified namespace path then opens a &lt;tt&gt;Stream&lt;/tt&gt; for the resource.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114493985255175439?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114493985255175439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114493985255175439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114493985255175439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114493985255175439'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/04/xsltransform-and-xsldocument-woes.html' title='XslTransform and xsl:document() woes'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-114479999758259424</id><published>2006-04-11T16:58:00.000-07:00</published><updated>2006-04-11T17:08:00.136-07:00</updated><title type='text'>Test-Driven Development to the Rescue</title><content type='html'>&lt;p&gt;My first project at my current job was to write some business rules against XML. At first, it seemed liked a daunting task. To write and test a rule required knowledge of the backend framework, the servers, many applications and patience to push a document through the framework. There was no way I could push through 420 test scenarios doing that. I spent several days analyzing what was in place to isolate my task, refactoring existing code etc (though i did not merge it back) to create a test harness. I even fibbed to the project manager on my progess knowing that I would make up the time later. That's how much confidence I have in Test-Driven Development. At first, things were slow-going. The pressure was mounting. Once I had my test harness in place, I'm guessing not only did I do this task faster than anyone before me, I also had reproduceable tests. To top of it, I had code generators to automate SQL scripting, etc. Testing was smooth as butter.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114479999758259424?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114479999758259424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114479999758259424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114479999758259424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114479999758259424'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/04/test-driven-development-to-rescue.html' title='Test-Driven Development to the Rescue'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-114479838446517445</id><published>2006-04-11T16:32:00.000-07:00</published><updated>2006-04-11T16:58:29.226-07:00</updated><title type='text'>Thinking Dependency Injection</title><content type='html'>&lt;p&gt;I'm creating components to convert proprietary source files into a standardized XML format. The legacy backend business components get their settings from  disparate sources. Some settings are retrieved via a custom configuration object  while others are read using stored procedures. Writing a unit test requires knowledge of how  to retrieve those settings.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Point 1 - Components should be focused on business logic not infrastructure logic. &lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Here's a contrived example.&lt;/p&gt;&lt;pre&gt;
class XmlConverter {
    void Convert(int orderId)
    {
        // get settings from a database
        DbSettings dbSettings = GetDbMetadata(orderId);

        // get from config object
        string targetFile = OurConfig.GetPath("StandardStore") + dbSettings.OrderNumber + ".xml";
        
        string sourceXmlFile = dbSettings.XmlFile;
        string stylesheet = dbSettings.Stylesheet;
            
        string standardXml = XmlUtils.XslTransform(sourceXmlFile, stylesheet);
        
        using (TextWriter tw = new StreamWriter(targetFile))
        {
            tw.Write(standardXml);
        }
    }
}
&lt;/pre&gt;&lt;p&gt;The preceding code looks &lt;em&gt;normal&lt;/em&gt; for most of us. And if you are the developer who wrote the code you know how to setup the database and you could select a valid order id so everything works when you test it. In addition, you know how the configuration object works and you can change its value blindfolded. It's so darn easy. Or is it?&lt;/p&gt;&lt;p&gt;Along comes poor me. I'm assigned to the project to fix an issue with the stylesheet. I hold a black-belt in stylesheet code-fu. Puh-leeze, I'll knock this task out in less than an hour. Then, why did it take me all day? Well because all that information you have in your head is too much to grasp for someone new to a project. The object knows too much. You know too much.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Point 2 - Objects should be a on a need-to-know basis. &lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;How do we fix this with dependency injection? First, think backwards. Give the component the information it needs, instead of that component retrieving what it needs. That is the basic paradigm shift of &lt;em&gt;Dependency Injection&lt;/em&gt;. A component is injected with the  dependencies it needs. Let's rewrite this.&lt;/p&gt;&lt;pre&gt;
class XmlConverter {
    void Convert(string sourceXmlFile, string stylesheet, string targetFile)
    {
        string standardXml = XmlUtils.XslTransform(sourceXmlFile, stylesheet);
        
        using (TextWriter tw = new StreamWriter(targetFile))
        {
            tw.Write(standardXml);
        }
    }
}
&lt;/pre&gt;&lt;p&gt;Now the component is focused on what it has to do---converting a file and saving it to  some known location. I can go in there and fix the stylesheet in 15 minutes and everyone is happy. What about configuration? First, let's look at the advantage of what just happened.  To write a unit test, I simply pass in source XML file, a stylesheet file and the absolute path to where the transformed file is persisted. If everything works, I'm 99.9% sure my fix will close the ticket. I didn't have to know about infrastructure nor could I have affected it.&lt;/p&gt;

&lt;p&gt;What about the settings? Someone has to retrieve it and inject it into the object. If you're  the original coder, you would have already done this. If you're a maintainer, don't worry about it. You don't need to know to do your job.  The infrastructure code is separate from business component logic. The application is easy to maintain. &lt;/p&gt;&lt;p&gt;&lt;em&gt;Dependency Injection&lt;/em&gt; containers help in this effort by allowing you to wire objects together declaritively. For example, why build a &lt;tt&gt;SqlConnection&lt;/tt&gt; object when you can ask the container for pre-built one?&lt;/p&gt;&lt;pre&gt;
SqlConnection connection = Container.GetObject("sqlconnection");
&lt;/pre&gt;&lt;p&gt;The container will cache it, or return a &lt;tt&gt;singleton&lt;/tt&gt; or create a &lt;tt&gt;prototype&lt;/tt&gt; when asked. Object instantiation is controlled declaritively either through a configuration file or a compiled script. The same kind of things you're doing now. Now it's done in one place and you don't have to build any infrastructure code. Use the container. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114479838446517445?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114479838446517445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114479838446517445' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114479838446517445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114479838446517445'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/04/thinking-dependency-injection.html' title='Thinking Dependency Injection'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-114464906994054256</id><published>2006-04-09T23:04:00.000-07:00</published><updated>2006-04-11T08:41:31.863-07:00</updated><title type='text'>Markdown vs. Markup</title><content type='html'>&lt;p&gt;Today I stumbled upon &lt;a href="http://www.aspnetresources.com/blog/markdown_announced.aspx"&gt;Markdown.NET&lt;/a&gt;. I've been using my own homegrown text to HTML converter, &lt;tt&gt;MGutz.Markup&lt;/tt&gt;, for a while now. I created a WinForms utility to convert text to HTML on-the-fly giving immediate feedback. I prefer the utility for the generation of plain HTML documents over DreamWeaver. I've changed the utility to support both &lt;tt&gt;Markdown&lt;/tt&gt; and &lt;tt&gt;MGutz.Markup&lt;/tt&gt;. &lt;/p&gt;&lt;p&gt;My disappointment with &lt;tt&gt;Markdown&lt;/tt&gt; is it lacks markup for quick tables. &lt;tt&gt;MGutz.Markup&lt;/tt&gt; supports nested tables as well as nested elements. Overall, &lt;tt&gt;Markdown&lt;/tt&gt; has a cleaner syntax. &lt;tt&gt;MGutz.Markup&lt;/tt&gt;'s syntax tries to avoid escaping of characters used in code like &lt;strong&gt;'[', ']', '*', '_', '-'&lt;/strong&gt; and &lt;strong&gt;'+'&lt;/strong&gt;. As a consequence, &lt;tt&gt;MGutz.Markup&lt;/tt&gt; source files are not as eye-friendly.I like &lt;tt&gt;Markdown&lt;/tt&gt; and will probably use it for most day-to-day documents but I use tables a lot. I may change the grammar for &lt;tt&gt;MGutz.Markup&lt;/tt&gt; since most of my code is usually eclosed in &lt;tt&gt;&amp;lt;pre&amp;gt;&amp;lt;/pre&amp;gt;&lt;/tt&gt; blocks. &lt;/p&gt;&lt;p&gt;I have security concerns about &lt;tt&gt;Markdown&lt;/tt&gt;. It's not suitable for use on Wiki's or CMS web sites as-is. It accepts raw HTML elements which could allow someone to insert javascript. &lt;tt&gt;MGutz.Markup&lt;/tt&gt;, by default, does not allow the insertion of raw HTML elements. The escape sequence in &lt;tt&gt;MGutz.Markup&lt;/tt&gt; tells the lexer to not evaluate the rule. Escaped tag sequences are still processed by &lt;tt&gt;HtmlEscape()&lt;/tt&gt; . &lt;tt&gt;MGutz.Markup&lt;/tt&gt; allows insertion of raw HTML tags only if a developer explicitly sets the &lt;tt&gt;EnableRawXml&lt;/tt&gt; property. Likewise, links will not be generated unless &lt;tt&gt;EnableLinks&lt;/tt&gt; is explicitly set.&lt;/p&gt;&lt;p&gt;Here's a quick comparison of the two:&lt;/p&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;html output &lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Markdown &lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;MGutz.Markup &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;this is a para&lt;/p&gt;&lt;p&gt;HTML special chars: &amp;amp; &amp;lt; &amp;gt; &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
this is
  a
    para

HTML special chars: &amp;amp; &amp;lt; &amp;gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
this is
  a
    para

HTML special chars: &amp;amp; &amp;lt; &amp;gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a href="http://www.google.com"&gt;google&lt;/a&gt; &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;[google](http://www.google.com) &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&amp;lt;&amp;lt;google, http://www.google.com&amp;gt;&amp;gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;apple &lt;/li&gt;&lt;li&gt;orange &lt;/li&gt;&lt;li&gt;pear  &lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
- apple
- orange
- pear
&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
// newline not requierd
@- apple 
@- orange 
@- pear
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;ol&gt;&lt;li&gt;one &lt;/li&gt;&lt;li&gt;two &lt;/li&gt;&lt;li&gt;three &lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
1. one
2. two
3. three
&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
@+ one @+ two @+ three
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;ol&gt;&lt;li&gt;one &lt;ul&gt;&lt;li&gt;apple &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;two &lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;p&gt;&lt;strong&gt;?&lt;/strong&gt; &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;@+ one @&amp;gt; @- apple @+ two &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;column heading &lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;languages &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;&lt;p&gt;right &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;C#, Boo &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;left &lt;/p&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;p&gt;centered &lt;/p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;sub-table&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;p&gt;&lt;strong&gt;?&lt;/strong&gt; &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
[[* column heading || languages ]]
[[&amp;gt; right || C#, Boo ]]
[[ left ||| centered [[sub-table]] ]]
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;bold&lt;/strong&gt; &lt;em&gt;italic&lt;/em&gt; &lt;tt&gt;code&lt;/tt&gt; &lt;em&gt;&lt;strong&gt;italic bold&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;_italic_ **bold** `code` _**italic bold**_   &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;**bold** //italic// ::code:: //**italic bold**// &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;img src="http://buttons.blogger.com/bloggerbutton1.gif" /&gt; &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;![alt text](http://buttons.blogger.com/bloggerbutton1.gif "Title")  &lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;@[http://buttons.blogger.com/bloggerbutton1.gif] &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;blockquote&gt;&lt;p&gt;one two three &lt;/p&gt;&lt;/blockquote&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
&amp;gt; one
&amp;gt; two
&amp;gt; three
&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
@bq
one
two
three
bq@
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114464906994054256?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114464906994054256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114464906994054256' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114464906994054256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114464906994054256'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/04/markdown-vs-markup.html' title='Markdown vs. Markup'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-114430487220783159</id><published>2006-04-05T23:27:00.000-07:00</published><updated>2006-04-05T23:37:44.256-07:00</updated><title type='text'>Merging XML with XUpdate</title><content type='html'>&lt;p&gt;I'm currently working on a backend process that receives two separate XML documents from different sources. The backend process must first transform each document, using XSLT, to conform to the company's standard format. The process then merges the two transformed documents into a single document. The merging operation requires some thought as the two documents share elements. Some elements are added while others are updated.&lt;/p&gt;
&lt;p&gt;I wanted to automate this as much possible. The easy way out is to write some C# code and merge the documents using two XmlDocuments. But surely someone must have already thought of a better approach to this problem. My thought was to transform the first document like normal but transform the second document into an update document to be applied against the first document. The second document will contain embedded instructions on how to update the first.&lt;/p&gt;
&lt;p&gt;After some googling, I found three solutions:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://apps.gotdotnet.com/xmltools/xmldiff/Xml%20Diff%20Language%20(Diffgram).html"&gt;Microsoft XML Diff Language v.1.0 Beta&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://xmldb-org.sourceforge.net/xupdate/xupdate-wd.html"&gt;XUpdate Working Draft&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www2.informatik.hu-berlin.de/~obecker/XSLT/#merge"&gt;Merging two XML Documents [using XSLT] by Oliver Becker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Microsoft XML diff approach defines an XML &lt;em&gt;diffgram&lt;/em&gt; language to describe the operations necessary to update a target document. It's not very readable using code numbers, etc for operations.&lt;/p&gt;

&lt;p&gt;XUpdate follows a similiar approach defining basic commands and operations to update a target document. The language is much more readable and there exists several implementations for non-.NET languages. As a bonus I found a decent .NET implementation on &lt;a href="http://www.openvue.net/projects.php?menu=4&amp;amp;PHPSESSID=adb9acc23070c8c3a7c8ef3c94d3122d"&gt;Xinjie ZHANG's Homepage&lt;/a&gt;. The working draft, however, has not been touched for many years. I updated the DTD as well as the &lt;tt&gt;XUpdate&lt;/tt&gt; class to support &amp;lt;xupdate:document-fragment/&amp;gt;.&lt;/p&gt;
&lt;p&gt;Oliver Becker's approach is pure XSL. While I consider myself pretty darn good at XSL, XSL is just too much damn work. And trying to decipher someone else's XSL stylesheet takes at least three times the effort of trying to understand say C# code.&lt;/p&gt;
&lt;p&gt;Here's an example using the XUpdate approach:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;!-- baseline.xml: target document --&amp;gt;
&amp;lt;recipes&amp;gt;
    &amp;lt;recipe name="unsalted bread" prep_time="5 mins" cook_time="3 hours"&amp;gt;
        &amp;lt;title&amp;gt;Basic bread&amp;lt;/title&amp;gt;
        &amp;lt;ingredient amount="3" unit="cups"&amp;gt;Flour&amp;lt;/ingredient&amp;gt;
        &amp;lt;ingredient amount="0.25" unit="ounce"&amp;gt;Yeast&amp;lt;/ingredient&amp;gt;
        &amp;lt;ingredient amount="1.5" unit="cups" state="warm"&amp;gt;Water&amp;lt;/ingredient&amp;gt;
        &amp;lt;instructions&amp;gt;
            &amp;lt;step&amp;gt;Mix all ingredients together, and knead thoroughly.&amp;lt;/step&amp;gt;
            &amp;lt;step&amp;gt;Cover with a cloth, and leave for one hour in warm room.&amp;lt;/step&amp;gt;
            &amp;lt;step&amp;gt;Knead again, place in a tin, and then bake in the oven.&amp;lt;/step&amp;gt;
        &amp;lt;/instructions&amp;gt;
    &amp;lt;/recipe&amp;gt;
&amp;lt;/recipes&amp;gt;
&lt;/pre&gt;
&lt;pre&gt;
&amp;lt;!-- diffgram.xml: contains an append and update command --&amp;gt;
&amp;lt;xupdate:modifications version="1.0" xmlns:xupdate="http://www.xmldb.org/xupdate"&amp;gt;
    &amp;lt;!-- append the Salt ingredient --&amp;gt;
    &amp;lt;xupdate:append select="/recipes/recipe[@name='unsalted bread']"&amp;gt;
        &amp;lt;xupdate:document-fragment&amp;gt;
            &amp;lt;ingredient amount="1" unit="teaspoon"&amp;gt;Salt&amp;lt;/ingredient&amp;gt;
        &amp;lt;/xupdate:document-fragment&amp;gt;
    &amp;lt;/xupdate:append&amp;gt;

    &amp;lt;!-- change the recipe name to 'Salted Bread' --&amp;gt;
    &amp;lt;xupdate:update select="/recipes/recipe[@name='unsalted bread']/@name"&amp;gt;Salted Bread&amp;lt;/xupdate:update&amp;gt;
&amp;lt;/xupdate:modifications&amp;gt;
&lt;/pre&gt;
&lt;pre&gt;
// unit test
XmlDocument baseline = new XmlDocument();
baseline.Load(IOUtils.OpenEmbeddedResource("Xml/res/baseline.xml"));

XmlDocument diffgram = new XmlDocument();
diffgram.Load(IOUtils.OpenEmbeddedResource("Xml/res/diffgram.xml"));

XUpdate update = new XUpdate(baseline, diffgram);
update.Execute();

&lt;/pre&gt;
&lt;pre&gt;
&amp;lt;!-- result of XUpdate.Execute() --&amp;gt;
&amp;lt;recipes&amp;gt;
    &amp;lt;recipe name="Salted Bread" prep_time="5 mins" cook_time="3 hours"&amp;gt;
        &amp;lt;title&amp;gt;Basic bread&amp;lt;/title&amp;gt;
        &amp;lt;ingredient amount="3" unit="cups"&amp;gt;Flour&amp;lt;/ingredient&amp;gt;
        &amp;lt;ingredient amount="0.25" unit="ounce"&amp;gt;Yeast&amp;lt;/ingredient&amp;gt;
        &amp;lt;ingredient amount="1.5" unit="cups" state="warm"&amp;gt;Water&amp;lt;/ingredient&amp;gt;
        &amp;lt;instructions&amp;gt;
            &amp;lt;step&amp;gt;Mix all ingredients together, and knead thoroughly.&amp;lt;/step&amp;gt;
            &amp;lt;step&amp;gt;Cover with a cloth, and leave for one hour in warm room.&amp;lt;/step&amp;gt;
            &amp;lt;step&amp;gt;Knead again, place in a tin, and then bake in the oven.&amp;lt;/step&amp;gt;
        &amp;lt;/instructions&amp;gt;
        &amp;lt;ingredient amount="1" unit="teaspoon"&amp;gt;Salt&amp;lt;/ingredient&amp;gt;
    &amp;lt;/recipe&amp;gt;
&amp;lt;/recipes&amp;gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114430487220783159?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114430487220783159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114430487220783159' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114430487220783159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114430487220783159'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/04/merging-xml-with-xupdate.html' title='Merging XML with XUpdate'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-114365901137284089</id><published>2006-03-29T11:03:00.000-08:00</published><updated>2006-03-29T11:03:31.876-08:00</updated><title type='text'>MSDN: Stored Procedure Object Interface Layer</title><content type='html'>&lt;p&gt;MSDN has an article on a stored procedure data layer using attributes.&lt;/p&gt;&lt;p&gt;&lt;a href="http://msdn.microsoft.com/architecture/default.aspx?pull=/library/en-us/dnbda/html/SPOIL.asp"&gt;Stored Procedure Object Interface Layer&lt;/a&gt;&lt;/p&gt;&lt;p&gt;As usual, the open source community has been doing this sort of thing for a while&amp;mdash;iBATIS. It can handle both stored procedures and straight SQL. iBATIS is much more flexible. There are some codegen tools that will do the mappings for you.&lt;/p&gt;&lt;p&gt;&lt;a href="http://ibatis.apache.org/"&gt;iBATIS&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-114365901137284089?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/114365901137284089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=114365901137284089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114365901137284089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/114365901137284089'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/03/msdn-stored-procedure-object-interface.html' title='MSDN: Stored Procedure Object Interface Layer'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113985432440762624</id><published>2006-02-13T10:05:00.000-08:00</published><updated>2006-02-13T10:13:15.116-08:00</updated><title type='text'>I'm Back</title><content type='html'>&lt;p&gt;Geez, it's been a while. I moved back to sunny San Diego and started a new contract today. Im familiar with the area as I went to college here and lived here for many years. It really is the finest city in the US. You can't beat it for weather and there's everything around.&lt;/p&gt;

&lt;p&gt;I'm working on .NET stuff as usual. The company I work for is using all three versions of Visual Studio---2002, 2003 and 2005 which means I'm restricted to using C# 1.0 features. FUN FUN FUN. This is common in the real world. While it's neat to read and play with the latest software technologies, most companies are content using an older version against which legacy applications are built. There is a huge amount of resources deploying, regression testing enterprise applications. Definitely no generics, etc.&lt;/p&gt;

&lt;p&gt;Is Boo dead? I dont see much activity.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113985432440762624?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113985432440762624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113985432440762624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113985432440762624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113985432440762624'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2006/02/im-back.html' title='I&apos;m Back'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113390302031760057</id><published>2005-12-06T13:02:00.000-08:00</published><updated>2005-12-06T13:46:58.056-08:00</updated><title type='text'>Object&lt;T&gt;</title><content type='html'>&lt;p&gt;It's good practice to override &lt;tt&gt;Equals()&lt;/tt&gt; and &lt;tt&gt;GetHashCode()&lt;/tt&gt; in your classes. Well, that's what they say anyway, I rarely do. But, with generics and &lt;tt&gt;org.apache.commons.lang.builder.HashCodeBuilder&lt;/tt&gt; (one of my java ports) it's easy to do. I created a generic base Object class:&lt;/p&gt;
&lt;pre&gt;
public class Object&amp;lt;T&amp;gt; {
    public override int GetHashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    public bool Equals(T obj) {
        if (obj == null) {
            return false;
        }
        return obj.GetHashCode() == GetHashCode();
    }

    public override bool Equals(object obj) {
        if (obj == null) {
            return false;
        }

        if (obj is T) {
            return GetHashCode() == obj.GetHashCode();
        }
        else {
            return false;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;&lt;tt&gt;HashCodeBuilder.reflectionHashCode(this)&lt;/tt&gt; introspects all the fields of the class and creates a HashCode. To create a class with this functionality, derive from &lt;tt&gt;Object&amp;lt;T&amp;gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;
public class Book : Object&amp;lt;Book&amp;gt; {
    string author = null;
    public string Title = null;
    public string Author {
        get { return author; }
        set { author = value;}
    }
}
&lt;/pre&gt;
&lt;p&gt;This trick is great for unit testing where you need to compare the inner value of classes. Unfortunately you can seldom use this trick in C#, a single-inheritance language, unless you're building a framework and you derive from a single base. For performance, use &lt;tt&gt;HashCodeBuilder&lt;/tt&gt;'s append functions instead of reflection.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113390302031760057?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113390302031760057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113390302031760057' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113390302031760057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113390302031760057'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/12/objectt.html' title='Object&amp;lt;T&gt;'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113386016181809268</id><published>2005-12-06T00:37:00.000-08:00</published><updated>2005-12-06T01:10:41.410-08:00</updated><title type='text'>I Miss Java</title><content type='html'>&lt;p&gt;While I have a lot more experience with C# and .NET, I have good experience with Java. I like both C# and Java. I especially like Java for open-source. There's so many well-designed open-source Java projects. Whatever open source projects there are for .NET, there's bound to be a multitude of projects that are stable and more mature on the Java side. And there are many Java projects that simply do not have a counterpart on the .NET side. One library I really miss is Jakarta Commons, a comprehensive set of utility classes for your day to day coding. I'm porting functions/classes as I need them. Fortunatley, the MS Java Conversion assistant is helping in this effort, doing most of the work.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113386016181809268?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113386016181809268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113386016181809268' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113386016181809268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113386016181809268'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/12/i-miss-java.html' title='I Miss Java'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113376998427353044</id><published>2005-12-04T23:51:00.000-08:00</published><updated>2005-12-05T00:34:26.366-08:00</updated><title type='text'>Switching to LGPL</title><content type='html'>&lt;p&gt;After reading the history of AJAX.NET it really bothers me that open-source on the .NET is greedy. Many open-source .NET projects that have become successful have turned commercial leaving behind many developers who contributed, tested and offered ideas while it was open source. What a shame. There are many projects that are close-sourced and proclaim to be &lt;b&gt;free&lt;/b&gt; for .NET. You're a &lt;b&gt;SUCKER&lt;/b&gt; if you're contributing your time to one of these projects.&lt;/p&gt;

&lt;p&gt;I'm switching all my open-source projects to LGPL, GNU Lesser General Public License. This means you can use the library as-is in a commercial application without any issues and give credit in a credits.txt file. You can't create a derivative of it by changing the source, recompiling and using it commercially without my permission. If you fix bugs or enhance it, then send a diff of those modifications and you are granted automatic permission to use the libary commercially again. I don't care about your proprietary code, only changes/enhancements to the library. I think this is more than fair. I'm not sure if LGPL is the right license for all I said, but it's a good start.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113376998427353044?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113376998427353044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113376998427353044' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113376998427353044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113376998427353044'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/12/switching-to-lgpl.html' title='Switching to LGPL'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113376890185099429</id><published>2005-12-04T23:15:00.000-08:00</published><updated>2005-12-05T00:30:01.186-08:00</updated><title type='text'>JSON Serializer/Deserialier</title><content type='html'>&lt;p&gt;I have a working JSON (JavaScript Object Notation) serializer/deserializer for .NET. I can marshall complex types between the browser and server using JSON. This is for my AJAX &lt;tt&gt;Behaviour.NET&lt;/tt&gt; library but like all my stuff you're free to use under the terms of the license. This was not an easy task. JSON is typeless which makes it very difficult to deserialize into strongly typed language like C#. I resorted to encoding the type of an object or array (collection) into the document itself:&lt;/p&gt;
&lt;pre&gt;
{
    "__objtype__" : "Test.Amelgy.Ajs.Json.Person, Test.Amelgy.Ajs",
    "Name" : null,
    "Sex" : "\u0000",
    "__arrtype__Pets" : "System.String[], mscorlib",
    "Pets" : [
        "sam-sam",
        "chili"
    ],
    "__arrtype__Books" : "System.Collections.ArrayList, mscorlib",
    "Books" : [
        {
            "__objtype__" : "Test.Amelgy.Ajs.Json.Book, Test.Amelgy.Ajs",
            "Author" : "Tom Archer",
            "Title" : "Inside C#"
        },
        {
            "__objtype__" : "Test.Amelgy.Ajs.Json.Book, Test.Amelgy.Ajs",
            "Author" : "GOF",
            "Title" : "Design Patterns"
        }
    ],
    "Weight" : 160
}
&lt;/pre&gt;
&lt;p&gt;This has potential for a security risk, but I'll give the end developer an option to encrypt the type and assembly. Deserializing is a matter of building C# code and using the CSharpCodeDom to compile it. Here's a sample of C# code generated by the deserializer. Still very readable, good for debugging.&lt;/p&gt;
&lt;pre&gt;
namespace nsc2fc87b2d1d5450a8080dd6f0168da50 { class Foo { public object GetObject() {
Test.MGutz.Json.Person object0 = new Test.MGutz.Json.Person();
object0.Name = null;
object0.Sex = "\u0000";
System.String[] array1 = new System.String[2];
object0.Pets = array1;
array1[0] = "sam-sam";
array1[1] = "chili";
System.Collections.ArrayList array2 = new System.Collections.ArrayList();
object0.Books = array2;
Test.MGutz.Json.Book object3 = new Test.MGutz.Json.Book();
array2.Add(object3);
object3.Author = "Tom Archer";
object3.Title = "Inside C#";
Test.MGutz.Json.Book object4 = new Test.MGutz.Json.Book();
array2.Add(object4);
object4.Author = "GOF";
object4.Title = "Design Patterns";
object0.Weight = 160;
return object0; }}}
&lt;/pre&gt;
&lt;p&gt;The only remaining issue is nested anonymous arrays. That'll be ugly cuz I think I'm too far in the parser and I'm using my JsonTextWriter which is not random access. A slight challenge is all.&lt;/p&gt;
&lt;pre&gt;
{
    "__arrtype__nested" : "ArrayList, mscorlib : int[], mscorlib"
    "nested" = [
        [1, 2, 3]
    ]
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113376890185099429?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113376890185099429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113376890185099429' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113376890185099429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113376890185099429'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/12/json-serializerdeserialier.html' title='JSON Serializer/Deserialier'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113372885723465921</id><published>2005-12-04T12:40:00.000-08:00</published><updated>2005-12-04T12:57:36.546-08:00</updated><title type='text'>ASP.NET aaargh!</title><content type='html'>&lt;p&gt;I'm deciding how to expose server-side methods to AJAX clients of non-Gamba developers. I want &lt;tt&gt;Behaviour.NET&lt;/tt&gt; to be usable outside of Gamba. AJAX is easy for Gamba or any MVC2 framework for that matter. A controller can expose any combination of views or methods. In Gamba's case, a server-method's logic is as simple as changing the response content type to &lt;tt&gt;Content.TextPlain&lt;/tt&gt;, &lt;tt&gt;Content.TextXml&lt;/tt&gt; or the default &lt;tt&gt;Context.TextHtml&lt;/tt&gt; then return data directly bypassing the usual logic of rendering views.&lt;/p&gt;
&lt;p&gt;In ASP.NET you don't get a controller, you get a stupid page. I have some options. I can derive from the ASP.NET &lt;tt&gt;Page&lt;/tt&gt; to create a &lt;tt&gt;BehaviourPage&lt;/tt&gt;. Developers then change their code behind to inherit from &lt;tt&gt;BehaviourPage&lt;/tt&gt;. This lets me create a page controller for pages taking advantage of &lt;tt&gt;Behaviour.NET&lt;/tt&gt;. Remote call would need be encoded in the query string of that page. But, what if a shop already has custom page in place? This folks is one of the many reasons why the ASP.NET page framework sucks!&lt;/p&gt;
&lt;p&gt;The other option is to commandeer the &lt;tt&gt;.ashx&lt;/tt&gt; extension and create an MVC framework strictly for AJAX methods like web services does with &lt;tt&gt;.asmx&lt;/tt&gt;. I could use a different extension but &lt;tt&gt;.ashx&lt;/tt&gt; is supported natively by ASP.NET. Using a different extension would prohibit its use in a hosted environment where you can't change IIS mappings. Even worse, &lt;tt&gt;.ashx&lt;/tt&gt; may already be in use.&lt;/p&gt;
&lt;p&gt;Yet another option is to hook into the lifecycle events. Seems too manual for me, but it maybe the only option I have.&lt;/p&gt;

&lt;p&gt;If anyone has any other suggestion please speak up. It's why I think aloud on my blog. It's a think-tank.&lt;/p&gt;
&lt;p&gt;I've told some people interested in this library it would take about a week to create a standalone version of &lt;tt&gt;Behaviour.NET&lt;/tt&gt;. I forgot about the pains of ASP.NET. I'll get it out guys. I want to make it simple for you, so don't shoot me if it's not out in a week.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113372885723465921?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113372885723465921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113372885723465921' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113372885723465921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113372885723465921'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/12/aspnet-aaargh.html' title='ASP.NET aaargh!'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113367324272134308</id><published>2005-12-03T21:11:00.000-08:00</published><updated>2005-12-03T22:25:08.060-08:00</updated><title type='text'>Behaviour.NET  - Real Open Source AJAX for .NET</title><content type='html'>&lt;p&gt;Real open source meaning Apache License 2.0 instead of the mess with AJAX.NET.&lt;/p&gt;
&lt;p&gt;So I thought I had discovered a better way to do AJAX. Well, it looks like the MS Atlas folks and I think alike. I haven't really looked Atlas, and today I saw a screenshot of it with the word behaviour. What's funny is behaviours are the foundation of &lt;tt&gt;Behaviour.NET&lt;/tt&gt;, a standalone AJAX library for my Gamba framework. I'd have to look at some samples to verify. What is that old adage? "Great minds think alike." I won't go that far, but this seems a better approach than what I've seen.&lt;/p&gt;
&lt;p&gt;If you remember my previous article &lt;a href="http://codedojo.blogspot.com/2005/12/gamba-helpers-or-components.html"&gt;Helpers or Components?&lt;/a&gt; I could not decide whether to create an AJAX API using helper functions or a lightweight component framework. After some contemplation it's my humble opinion helper functions are evil. We're back to ASP spaghetti again. Let's compare the two approaches, here's the helper function style:&lt;/p&gt;
&lt;pre&gt;
class Test(AjaxController):
    def Foo():
        ViewMethod = FooView

    def SayHello() as string:
        ContentType = Content.TextPlain
        return "Hello world!"
&lt;/pre&gt;
&lt;pre&gt;
&amp;lt;!-- Test.FooView.tpl --&amp;gt;
&amp;lt;%= CreateButtonDoRemote("Invoke Remote", Urlize("SayHello")
        , {"onsuccess" : "$('input1').value = request.responseText;"
        , "onfailure" : "alert('Unable to get information from server.')"}
    )
%&amp;gt; &amp;amp;nbsp; &amp;lt;input id="input1"/&amp;gt;
&lt;/pre&gt;
&lt;p&gt;It's typical ASP coding. Here's how it's done with &lt;tt&gt;Behaviour.NET&lt;/tt&gt;, with behaviours code residing in the controller.&lt;/p&gt;
&lt;pre&gt;
class Test(AjaxController):
    def Foo():
        button = Button("button1")
        with method = RemoteMethod(Test, "SayHello"):
            OnSuccess += Prototype.SetValue("input1")
            OnFailure += Prototype.MsgBox("Unable to get information from server.")
        button.OnClick += Prototype.InvokeRemote(method)

        Behaviours.AttachBehaviour(button)
        ViewMethod = FooView

    def SayHello():
        ContentType = Content.TextPlain
        return "Hello world!"
&lt;/pre&gt;
&lt;pre&gt;
&amp;lt;!-- Test.FooView.tpl --&amp;gt;
&amp;lt;input id='button1' type='button' value="Invoke Remote"/&amp;gt; &amp;amp;nbsp; &amp;lt;input id="input1"/&amp;gt;
&lt;/pre&gt;
&lt;p&gt;It's a little bit more coding, but here are some advantages off the top of my head&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;It's readable and easy to understand. &lt;/li&gt;&lt;li&gt;Errors are minimized. Event names are checked at run-time &lt;/li&gt;&lt;li&gt;Separation of code and view (developers vs. designers). &lt;/li&gt;&lt;li&gt;Developer's are shielded from the underlying AJAX engine. &lt;/li&gt;&lt;li&gt;The generated javascript is as lean and syntax correct the first time.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;One disadvantage is a slight performance loss, but that's minimal. I've looked at some implementations of AJAX generic helper functions and they use a maze of functions to generate a script. These objects are very light and for now all they do is encapsulate some javascript code. This lightweight component framework coincidentally fits in very well with Gagamba, my plans for a fully componentized version of Gamba. I wanted to do a basic core framework first before starting Gagamba.&lt;/p&gt;

&lt;p&gt;Oh, I almost forgot. Thanks to Ben Nolan, the author of the &lt;a href="http://bennolan.com/behaviour"&gt;Behaviour&lt;/a&gt; JavaScript library for inspiration.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113367324272134308?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113367324272134308/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113367324272134308' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113367324272134308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113367324272134308'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/12/behaviournet-real-open-source-ajax-for.html' title='Behaviour.NET  - Real Open Source AJAX for .NET'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113356449040820929</id><published>2005-12-02T14:34:00.000-08:00</published><updated>2005-12-02T15:05:00.123-08:00</updated><title type='text'>Gamba: A New Beginning</title><content type='html'>&lt;p&gt;Hmm, maybe Boo is a language for three developers (quote from somewhere). Noone seems to be interested in a web framework for Boo. Eventually I'd like to enlist people to contribute but I dont see much interest. That's a little disconcerting, but time to move on. Maybe I'll contribute to Boo in other ways, but for now I'll concentrate on C#. Boo's architect, bamboo, has some good ideas with Boo but I don't think people realize how things like AstAttributes let you be more expressive and creative. Code injection, for example, is very powerful. You can get close with an MSBuild preprocessor and partial classes with C# 2.0 but you don't get the AST. I've only touched the surface, you could change the behaviour of a class instead of just mixing in other behaviour. Anyway, it's all for not.&lt;/p&gt;

&lt;p&gt;If you're interested in Boo for web stuff you still have Brail and MonoRail.&lt;/p&gt;

&lt;p&gt;I still have plans for Gamba, which as of today starts anew with focus on ASPX pages, MS Enterprise Blocks and C#. My real experience lies in enteprise development and so it's my comfort zone. Sadly, I can only do a pseudo-MVC2 approach but it fits in well with how most Microsoft developers do web development.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113356449040820929?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113356449040820929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113356449040820929' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113356449040820929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113356449040820929'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/12/gamba-new-beginning.html' title='Gamba: A New Beginning'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113354915307976832</id><published>2005-12-02T10:45:00.000-08:00</published><updated>2005-12-02T12:00:11.340-08:00</updated><title type='text'>Gamba: Helpers or Components?</title><content type='html'>&lt;p&gt;I can't decide how Gamba should present AJAX to the end developer. After analyzing the &lt;a href="http://prototype.conio.net/"&gt;prototype&lt;/a&gt; javascript library, which is the foundation for most AJAX functionality these days, should Gamba provide helper functions or create a component model? AJAX lends itself to the component model. You're forced to deal with synchronous/ asynchronous events. Events fired by one element may result in the update of another element. For example, clicking a button calls a remote function updating an input box.&lt;/p&gt;
&lt;p&gt;Gamba can follow &lt;a href="http://www.castleproject.org/index.php/MonoRail"&gt;MonoRail&lt;/a&gt; and provide helper functions. This requires the developer to learn the prototype javascript library. Gamba can shield the end developer by creating a bunch of helper functions as MonoRail does. Here's an example:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;%= CreateButtonDoRemote("Invoke Remote", Urlize("SayHello")
        , {"onsuccess" : "$('input1').value = request.responseText;"
        , "onfailure" : "alert('Unable to get information from server.')"}
    )
%&amp;gt; &amp;amp;nbsp; &amp;lt;input id="input1"/&amp;gt;
&lt;/pre&gt;

&lt;p&gt;It's just not simple, which goes against the KISS principle. The other option is to create a lightweight component model with pseudo-events. Here's the equivalent behaviour as above:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;%
text = TextBox('input1')
with button = Button(Caption: 'Invoke Remote'):
    OnClick += Client.CallRemote(Urlize('SayHello'))
    OnSuccess += Client.SetValue(text)
    OnFailure += Client.MsgBox('Unable to get information from server.')
%&amp;gt;

${button} &amp;amp;nbsp; ${text}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113354915307976832?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113354915307976832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113354915307976832' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113354915307976832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113354915307976832'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/12/gamba-helpers-or-components.html' title='Gamba: Helpers or Components?'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113342143278743246</id><published>2005-11-30T23:11:00.000-08:00</published><updated>2005-11-30T23:22:26.086-08:00</updated><title type='text'>SVN access for Reflex and CodeInjection</title><content type='html'>&lt;p&gt;I've moved the source for the &lt;tt&gt;CodeInjection&lt;/tt&gt; and &lt;tt&gt;Reflex&lt;/tt&gt; library to ckknight's SVN box. NovellForge was too much of a pain with passwords. I'll import the rest of the Gamba framework to there once I feel the core interfaces and implementations won't change. The libraries above may be used separately from Gamba and are licensed under APL 2.0 .&lt;/p&gt;

&lt;p&gt;Here's the address: &lt;tt&gt;svn://ckknight.no-ip.org/mgutz/trunk&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;There isn't much documentation, well because I've been lax and Boo doesn't have a formal documentation tags syntax. Your best bets are the articles I've written in this blog and the examples or unit tests.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113342143278743246?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113342143278743246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113342143278743246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113342143278743246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113342143278743246'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/svn-access-for-reflex-and.html' title='SVN access for Reflex and CodeInjection'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113341977454051676</id><published>2005-11-30T22:48:00.000-08:00</published><updated>2005-12-01T00:03:32.880-08:00</updated><title type='text'>Gamba: First-Class Branding</title><content type='html'>&lt;p&gt;More refactoring today. I've promoted the branding idea to a full pledged object model. The entry point (after front controller) into Gamba will not be a controller as in traditional MVC2, rather a brand. The importance of this is a brand controls access to a set of controllers and also encapsulates look-and-feel. For example, an executive brand of a corporate website allows the use of the &lt;tt&gt;FinancialsController&lt;/tt&gt; and &lt;tt&gt;CorporateStrategiesController&lt;/tt&gt; as well as any other controllers it inherits through derivation.&lt;/p&gt;
&lt;p&gt;If developers do not wish to use brands, then the &lt;tt&gt;DefaultBrand&lt;/tt&gt; will simply be a pass-through to a controller as in normal MVC2. Here's a simplified UML diagram. (There's actually a few classes between dispatchers and brands like &lt;tt&gt;IActionProxy&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img225.imageshack.us/img225/3039/snap10dz.png"&gt;&lt;/img&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113341977454051676?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113341977454051676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113341977454051676' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113341977454051676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113341977454051676'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/gamba-first-class-branding.html' title='Gamba: First-Class Branding'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113341961441298352</id><published>2005-11-30T22:45:00.000-08:00</published><updated>2005-11-30T22:48:02.280-08:00</updated><title type='text'>Gamba: Purpose</title><content type='html'>&lt;p&gt;I should have formally announced what Gamba is. Gamba is a web framework built on a well understood design pattern, MVC2. MVC2, unlike ASP.NET which is a simple page controller model, has a front controller directing actions to sub controllers. The duty of the front controller is to further separate the concerns of what a page has to do from what an infrastructure should provide. Every page should not be concerned with user authentication or how to handle exceptions. In the ASP.NET model where users are accessing the page directly, you're forced to handle it on the page or by inheritance. Ideally a page should only be concerned about rendering data its given, nothing more. The front controller also insulates your users from changes in the backend since URLs are logical paths not physical paths as in ASP.NET. I would highly recommend googling front controller or MVC2 to get a better understanding of this pattern.&lt;/p&gt;

&lt;p&gt;My goal for Gamba is to create a web framework suitable for consulting work. Gamba has first class infrastructure support for things like branding. The HTML templates will be editable in design tools like DreamWeaver. The data templates will use normal SQL queries or stored procedures making it easier to integrate with legacy data. Gamba is based on Boo because I believe and have shown it to be more flexible than any other .NET language. In the end, I'll show how you can build a blog in less time than Ruby on Rails and have a fully compiled application with no templates. It will be more scalable and faster.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113341961441298352?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113341961441298352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113341961441298352' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113341961441298352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113341961441298352'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/gamba-purpose.html' title='Gamba: Purpose'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113335022341958021</id><published>2005-11-30T03:30:00.000-08:00</published><updated>2005-11-30T03:32:12.270-08:00</updated><title type='text'>KISS and the 80/20</title><content type='html'>&lt;p&gt;I design with two principles in mind, KISS (keep it simple stupid) and the 80/20 % rule. Ckknight asked a question today in IRC about the data layer using hardcoded SQL. What if you want to switch databases? My reply was something to the effect "if you're not using generic SQL then you'll have to change templates. There's no way to get around it." The Gamba data layer implements the basic DAO design pattern, using SQL queries is by design and may be changed without affecting the rest of the application.&lt;/p&gt;
&lt;p&gt;In all my years of development, I've only had to change the backend database once on a production application! Thankfully stored procedures were used and the DBAs did most of the work. Our DAOs worked pretty much as is, except SQL Server returns a dataset whereas Oracle returns a cursor. Most companies simply &lt;b&gt;do not&lt;/b&gt; switch out databases because one is better. If something works, maintain it.&lt;/p&gt;
&lt;p&gt;On a sidenote, what a mistake switching from MS/SQL Server to Sun/J2EE/Oracle was. No big gains at all. The new CIO had a thing against Microsoft. Funny how we spent literally a million dollars on servers and J2EE/Oracle licenses. Guess which applications are still handling millions of transactions? VB6 MTS components running in a web farm on cheap $5000 Windows servers compared to $30000 Sun boxes. The other is the C# application I architected. This was the application we switched to Oracle to supposedly gain performance. In Oracle's defense, we had to use Microsoft's Oracle drivers. At that time Oracle's driver was still in beta. The moral is no fancy J2EE distributed gumbo. Each core application relied on MSMQ with a 20 or so server farm hiding behind a round-robin TCP-IP dispatcher. KISS at the enterprise level.&lt;/p&gt;
&lt;p&gt;Back on topic. Gamba will be flexible, but not to the point where it becomes over-architected, over-engineered, over-OOPsed as I like to say. It will be simple and 80% of what AJAX web developers need will be very easy to do. The other 20% will require the usual manual effort by the developer. What you get is a fast, light framework without the bloat. Features will be added as needed not what I think the future will need. Who knows, AJAX may be gone in a few years when the next big thing hits.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113335022341958021?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113335022341958021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113335022341958021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113335022341958021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113335022341958021'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/kiss-and-8020.html' title='KISS and the 80/20'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113333204416501201</id><published>2005-11-29T22:27:00.000-08:00</published><updated>2005-11-29T22:42:13.143-08:00</updated><title type='text'>Gamba: Data</title><content type='html'>&lt;p&gt;As I thought more about a data access layer for Gamba, my ever flickering idea light came on and the solution was right in front of me. One of the goals of Gamba is to use Boo for everything, configuration, templates and so on. Why not use the &lt;tt&gt;CodeInjection&lt;/tt&gt; library to simplify data access?&lt;/p&gt;
&lt;p&gt;No matter which data access library is used, the library has to be told via a metadata file what data is queried and how to map those results to objects. (The exception being code generators which may need as little info as a connection string.) With the magic of &lt;tt&gt;CodeInjection&lt;/tt&gt; metadata files can be transformed into managed code. And thus the genesis of Boo Data Templates.&lt;/p&gt;
&lt;p&gt;Some advantages:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Fields/Properties are checked at compile-time &lt;/li&gt;&lt;li&gt;No performance hit for dynamic run-time mapping to classes &lt;/li&gt;&lt;li&gt;Supports both plain and dynamic SQL queries as well as stored procs &lt;/li&gt;&lt;li&gt;Code is cleaner. The code is not marked with a ton of attributes. &lt;/li&gt;&lt;li&gt;Classes are not overwritten by a code generator. &lt;/li&gt;&lt;li&gt;Less XML configuration!&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Disadvantages:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;No runtime query language which most ORMs provide. It's nice to be able to query a result set. &lt;/li&gt;&lt;li&gt;You have to write SQL queries. Most ORMs shield you from this.&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;Boo Data Templates&lt;/h3&gt;
&lt;p&gt;Here's the bird's eye view of Boo Data Templates:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img345.imageshack.us/img345/6802/bdt6fn.png"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;Each template contains a query and possibly a map definition if the result of the query is to be mapped to properties of the class. The templates are injected into &lt;tt&gt;Person&lt;/tt&gt; via the &lt;tt&gt;MixinDataTemplates&lt;/tt&gt; attribute. As an example, the &lt;tt&gt;Person.SelectAll.bdt&lt;/tt&gt; template contains this:&lt;/p&gt;

&lt;pre&gt;
query:
    Select = "select person_name, person_gender from person"

map:
    Name = person_name
    Gender = person_gender
&lt;/pre&gt;
&lt;p&gt;The class which uses the template looks like this:&lt;/p&gt;
&lt;pre&gt;
[MixinDataTemplates]
class Person:

    [property(Name)]
    _name = ""

    [property(Gender)]
    _gender = "M"
&lt;/pre&gt;
&lt;p&gt;After compilation, the class looks like this:&lt;/p&gt;
&lt;pre&gt;
class Person:
    [property(Name)]
    _name = ""

    [property(Gender)]
    _gender = "M"

    def SelectAll() as (Person):
        people = ExecuteQuery(queryFromTemplate)

        for p in people:
            person = Person()
            person.Name = people['person_name']
            person.Gender = people['person_gender']

    def Find(key) as Person:
        ...

    def Update():
        ...
&lt;/pre&gt;
&lt;h3&gt;Next Steps&lt;/h3&gt;
&lt;p&gt;Cameron Kenneth Knight (ckknight) is taking this idea forward. This will be a very nice data layer. More details will come as the library progresses.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113333204416501201?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113333204416501201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113333204416501201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113333204416501201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113333204416501201'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/gamba-data.html' title='Gamba: Data'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113325061079944930</id><published>2005-11-28T23:06:00.000-08:00</published><updated>2005-11-28T23:54:39.753-08:00</updated><title type='text'>Just Data Please</title><content type='html'>&lt;p&gt;Why is it so difficult to do generic data access with .NET? Why not follow JDBC? Universal data access, remember that MS technology, not in .NET. Abstract as they might, ADO.NET still sucks. Is it that hard for MS to swallow their pride and implement a JDBC model? Or, is being able to create a SQL Server specific driver the reason ADO.NET sucks? MS knows how to do it they refuse to in ADO.NET. Every other data access library from Perl, Python, Ruby ... Java does it right.&lt;/p&gt;

&lt;p&gt;I need a nice Data Access library for Gamba. I like iBATIS.NET mapper but it's doing more than I want. iBATIS has a lower level dData access library which may suit my needs. My ideal data access would be the MS DAAB (Data Access Application Block) but a truly generic version without needing any of the other MS blocks like configuration, logging. I don't find ORMS to be appealing as they assume 1) you have control of the database, 2) I prefer metadata and 3) stored procedures are good.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113325061079944930?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113325061079944930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113325061079944930' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113325061079944930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113325061079944930'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/just-data-please.html' title='Just Data Please'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113322697932589796</id><published>2005-11-28T17:16:00.000-08:00</published><updated>2005-11-28T19:53:00.306-08:00</updated><title type='text'>Gamba: Branding</title><content type='html'>&lt;p&gt;Gamba, the Boo MVC2/Rails framework is coming along nicely. As I add features to Gamba I'll write a short article explaining the usefulness of the feature. This article focuses on branding, the ability for a multi-user website to appear and behave differently based on the user.&lt;/p&gt;
&lt;h3&gt;Motivation&lt;/h3&gt;
&lt;p&gt;A very simple type of branding is achieved by most blog hosts. They allow users to specify a different template for their personal blog. For enterprise websites branding requires more than a new 'skin'. Sub applications of an enterprise-level web application may access a different database or perform specific business logic tailored for the client.&lt;/p&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;In this example, we'll create a simple web app which changes behavior based on the brand's URL. Since Gamba is an MVC2 framework, pages are not directly accessible as they are in ASP.NET. Don't let this dissuade you. Creating a view is as easy as deriving from &lt;tt&gt;DefaultController&lt;/tt&gt; and a template for each view.&lt;/p&gt;
&lt;pre&gt;
// Foo.boo - controller
[MixinTemplates]
class Foo(DefaultController):
    def Hello():
        ViewMethod = HelloView

    def Name():
        Model["name"] = "mario"
        ViewMethod = NameView
&lt;/pre&gt;

&lt;pre&gt;
// Hello.HelloView.tpl - template for HelloView
&amp;lt;p&amp;gt;Hello world!&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;pre&gt;
// Hello.NameView.tpl - template for NameView
&amp;lt;p&amp;gt;Hello ${Model['name']}&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Gamba's &lt;tt&gt;IController&lt;/tt&gt; has many views whereas an ASP.NET page has one view, the &lt;tt&gt;.aspx&lt;/tt&gt; page itself. Gamba may choose not to call any views of a controller if, for example, the user has not logged in. To view the views, compile the class above and drop the assembly into Gamba's &lt;tt&gt;bin&lt;/tt&gt; folder, then browse:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://img104.imageshack.us/img104/4773/foohello2uf.png"&gt;&lt;/img&gt;&lt;img src="http://img104.imageshack.us/img104/6549/fooname6su.png"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;Let's do something different for any user of the &lt;tt&gt;boo&lt;/tt&gt; sub application. A sub application is accessed via a different URL prefix - &lt;tt&gt;http:://localhost:8080/gamba/boo&lt;/tt&gt;. Gamba will automatically reuse the controller above if we don't do any modifications. Let's create a new layout and also create a controller for the &lt;tt&gt;boo&lt;/tt&gt; sub application. The layout is basic, we'll just change the background to green. I don't use a template here just to show you don't have to use templates at all:&lt;/p&gt;
&lt;pre&gt;
class BooLayout(DefaultLayout):
    override def Execute() as List:
        htmlTop = "&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body bgcolor='green'&amp;gt;"
        htmlBottom = "&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"

        return [htmlTop, _child.ViewMethod(), htmlBottom]

&lt;/pre&gt;
&lt;p&gt;Let's assume &lt;tt&gt;Foo&lt;/tt&gt; has a lot of functionality in it and we want to modify one view. Using OOP derive a controller from &lt;tt&gt;Foo&lt;/tt&gt;.&lt;/p&gt;
&lt;pre&gt;
[MixinTemplates]
class Bar(Foo):
    override def Name():
        Model['names'] = ['mgutz', 'bamboo', 'ckknight']
        ViewMethod = NamesView
&lt;/pre&gt;
&lt;pre&gt;
# Bar.NamesView.tpl - template for NamesView
&amp;lt;% for name in Model['names']: %&amp;gt;
&amp;lt;p&amp;gt;Hello ${name}&amp;lt;/p&amp;gt;

&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Again, compile the classes and drop into Gamba's &lt;tt&gt;bin&lt;/tt&gt; folder. Browse the two pages noting the use of 'boo/bar':&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img104.imageshack.us/img104/1373/barhello3as.png"&gt;&lt;/img&gt;&lt;img src="http://img104.imageshack.us/img104/2055/barname7wj.png"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This article described how Gamba solves one of the challenges facing web developers, branding. In particular, Gamba uses object-oriented programming to alter behaviour and appearance unlike some other frameworks which resort to using a template hierarchy.&lt;/p&gt;

&lt;p&gt;BTW, as someone commented, I use &lt;b&gt;FireFox&lt;/b&gt;. I used IE so I could capture the address bar in a small window.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113322697932589796?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113322697932589796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113322697932589796' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113322697932589796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113322697932589796'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/gamba-branding.html' title='Gamba: Branding'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113291724797173652</id><published>2005-11-25T03:10:00.000-08:00</published><updated>2005-11-25T03:14:07.983-08:00</updated><title type='text'>Delaying Code Execution with Reflex</title><content type='html'>&lt;p&gt;I've already found a nice benefit of using my &lt;tt&gt;Reflex&lt;/tt&gt; library. I can delay the execution of an entire block of code. Here's the scenario. A user browses this address:&lt;/p&gt;
&lt;pre&gt;
http://www.mgutz.org/gamba/person/show?id=1
&lt;/pre&gt;
&lt;p&gt;To Gamba (Boo web framework) it means invoke &lt;tt&gt;Person.Show()&lt;/tt&gt;. When the URL above is received, Gamba forwards the URL to &lt;tt&gt;ReflexDispatcher&lt;/tt&gt; for dispatching. &lt;tt&gt;ReflexDispatcher&lt;/tt&gt; returns a &lt;tt&gt;ReflexActionProxy&lt;/tt&gt; object which may be executed at any time. Delaying execution of the action makes Gamba flexible. The action could be chained with pre and post interceptors, it could be queued, or completely discarded by a filter in the pipeline. Here' the pseudo-logic in &lt;tt&gt;ReflexDispatcher&lt;/tt&gt;.&lt;/p&gt;
&lt;pre&gt;
    def Execute():
        klass = ParseClass(_context)
        method = ParseMethod(_context)

        script = """
            ${klass}.new() {
                Context = $0
                ${method}()
                return this
            }
        """

        return ReflexActionProxy(script, _context)
&lt;/pre&gt;
&lt;p&gt;How does it work? First remember Gamba has to parse the class and method from URL. Gamba creates a &lt;tt&gt;Reflex&lt;/tt&gt; script to avoid doing any reflection manually. The script is then packaged into an action proxy along with argument &lt;tt&gt;$0&lt;/tt&gt; (&lt;tt&gt;_context&lt;/tt&gt; object). The script above, after string interpolation looks like this:&lt;/p&gt;
&lt;pre&gt;
    Person.new() {
        Context = $0
        Show()
        return this
    }
&lt;/pre&gt;
&lt;ol&gt;&lt;li&gt;Create Person() controller&lt;/li&gt;&lt;li&gt;Assign the HttpContext &lt;/li&gt;&lt;li&gt;Invoke Show() &lt;/li&gt;&lt;li&gt;return the instanstiated Controller&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;To do all of this, &lt;tt&gt;ReflexActionProxy&lt;/tt&gt; simply evaluates the script.&lt;/p&gt;
&lt;pre&gt;
    return Reflex.Eval(script, context)
&lt;/pre&gt;
&lt;p&gt;You may be wondering is &lt;tt&gt;Reflex&lt;/tt&gt; using CodeDom? DEFINITELY NOT! &lt;tt&gt;Reflex&lt;/tt&gt; is optimized for small, reflection-based scripts. &lt;tt&gt;Reflex&lt;/tt&gt; caches types, methods and properties to minimize performance loss.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113291724797173652?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113291724797173652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113291724797173652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113291724797173652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113291724797173652'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/delaying-code-execution-with-reflex.html' title='Delaying Code Execution with Reflex'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113256552636670879</id><published>2005-11-21T01:22:00.000-08:00</published><updated>2005-11-21T01:32:07.476-08:00</updated><title type='text'>VS2005 Tip - How to Rename a Class (not so obvious)</title><content type='html'>&lt;p&gt;If you rename a class by refactoring, VS2005 does not prompt to rename the file to match the new class name. It's good practice for the file to be named after the class.&lt;/p&gt;

&lt;p&gt;Here's the trick. Rename the file in Solution Explorer first and VS2005 will ask to rename the class and update all references.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113256552636670879?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113256552636670879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113256552636670879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113256552636670879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113256552636670879'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/vs2005-tip-how-to-rename-class-not-so.html' title='VS2005 Tip - How to Rename a Class (not so obvious)'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113251806775516068</id><published>2005-11-20T11:36:00.000-08:00</published><updated>2005-11-20T13:00:58.366-08:00</updated><title type='text'>XmlDocument for AST?</title><content type='html'>&lt;p&gt;I played with Coco/R (lexer/parser generator) last week and was a little disappointed Coco doesn't have a quick way to build an AST like ANTLR. For small utilities, the built-in AST library of ANTLR is sufficient. ANTLR's parser grammar uses a &lt;tt&gt;'^'&lt;/tt&gt; character to indicate the root of the AST node for the production rule. Very simple. To do the same with Coco, you add attributes to each element that becomes part of an AST in your production rules. The grammar file quickly becomes a hybrid of EBNF fules interlaced with C# code. To be fair, ANTLR requires interlacing of C# when creating a grammar of any complexity, but the amount of C# code is much less.&lt;/p&gt;
&lt;p&gt;On the other hand, Coco is lightweight and doesn't require a run-time library. The reason for trying it in the first place. Coco is supposedly faster. Parsing does seem faster but I haven't built a complex parser with it.&lt;/p&gt;
&lt;p&gt;I went back to ANTLR. Then, this little programmer demon in my head would not succumb to such an easy defeat. I'm now back on Coco for this project. Yep, i'm a flip-flopper. Since .NET doesn't provide a tree collection, I decided to use the XmlDocument for my AST instead of spending a few minutes to create an AST Node. This has many advantages:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Quick hierarchical representation of the tree. &lt;tt&gt;Console.WriteLine(tree.InnerXml);&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;Employ XPath to search the tree. &lt;/li&gt;&lt;li&gt;Employ XSL to convert the tree into another tree.&lt;/li&gt;&lt;li&gt;Create AST externally using your favorite XML editor. (for experimenting with optimizations, etc)&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I'm not a compiler guy but I see this approach having many advantages (and disadvantages such as performance). Imagine being able to convert from one language to another using XSLT. Or, to simplify the use of AstMacros or NRefactory refactoring? Most of us know how to manipulate XmlDocument and even write XSLT. There is huge potential here.&lt;/p&gt;

&lt;p&gt;The idea came from an article I read on the web. Something to do with running multiple languages using common XML ASTs on an XML virtual machine. Interesting read, I wish I saved the link.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113251806775516068?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113251806775516068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113251806775516068' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113251806775516068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113251806775516068'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/xmldocument-for-ast.html' title='XmlDocument for AST?'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113237756707953966</id><published>2005-11-18T21:04:00.000-08:00</published><updated>2005-11-18T21:48:07.320-08:00</updated><title type='text'>Why not MonoRail?</title><content type='html'>&lt;p&gt;I almost have the core libraries to start a Boo web framework. Someone in the IRC asked why not build on MonoRail or use Brail? The main reason is the use of NVelocity as the official view engine. Brail emulates NVelocity. They completely missed the point of Ruby on Rails.&lt;/p&gt;
&lt;p&gt;NVelocity is a full blown language. Why learn another language? NVelocity isn't object-oriented so you have to do something like this:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;head&amp;gt;
$AjaxHelper2.GetJavascriptFunctions()
$Effects2Helper.GetJavascriptFunctions()
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
Auto completion:&amp;lt;br&amp;gt;
$AjaxHelper2.InputTextWithAutoCompletion( "name", "nameautocompletion.rails", null, null )
&amp;lt;/body&amp;gt;
&lt;/pre&gt;
&lt;p&gt;MonoRail pushes two objects into the NVelocity context. These objects provide functions to aid in the creation of AJAX controls. I would prefer to have a controller derived from AjaxController that adds the javascript functions to the header as well as provide additional functions.&lt;/p&gt;

&lt;p&gt;NVelocity's purpose is to be a template engine. It interprets a template at runtime to render a view. It might be worth incurring a performance hit if NVelocity provided some advantage. I've shown in a previous article how Boo can be used as a &lt;a href="http://codedojo.blogspot.com/2005/10/boo-as-template-compiler.html"&gt;template compiler&lt;/a&gt;. In short, the article shows how Boo's compiler attributes let you transform a template into managed code.&lt;/p&gt;
&lt;p&gt;How would I approach all of this using Boo? First, using OOP I would derive AjaxController from DefaultController:&lt;/p&gt;
&lt;pre&gt;
class AjaxController(DefaultController):
    // add javascript functions to html
    private def AddJavascriptFunctions():
        pass

    // create an AJAX input text control with auto copmletion
    def InputTextWithAutoCompletion():
        pass
&lt;/pre&gt;
&lt;p&gt;To create an actual controller:&lt;/p&gt;
&lt;pre&gt;
[Template('person.tpl', 'RenderFind')]
class Person(AjaxController):
    def Find():
        RenderFind()

    def Auto():
        // logic to return matches for autocompletion
&lt;/pre&gt;
&lt;pre&gt;
&amp;lt;!-- person.tpl, compiled as RenderPerson() --&amp;gt;
Auto completion:&amp;lt;br&amp;gt;
$InputTextWithAutoCompletion("name", "person/auto", $Model.Name)
&lt;/pre&gt;
&lt;p&gt;The &lt;tt&gt;Template&lt;/tt&gt; compiler attribute transforms &lt;tt&gt;person.tpl&lt;/tt&gt; into a &lt;tt&gt;RenderFind()&lt;/tt&gt; method. You can add multiple &lt;tt&gt;Template&lt;/tt&gt; attributes. To render a person, call &lt;tt&gt;Person.Find()&lt;/tt&gt;. There is no need to &lt;i&gt;send&lt;/i&gt; variables to a template. The template is part of the class and has access to any property, field or method of the class. We're not setting up some context and passing it to an engine like NVelocity does. &lt;tt&gt;Person&lt;/tt&gt; is derived from &lt;tt&gt;AjaxController&lt;/tt&gt; giving this class AJAX functionality by inheritance. As an added bonus, you can debug through the generated code of the template. (Boo does not yet have a #line directive. When Boo does, you'll be able to debug the template directly.)&lt;/p&gt;

&lt;p&gt;Are templates the way to go? It's an outdated idea for web frameworks. I may go down the road similiar to XAML, instead I'll use Glade markup. Imagine being able to draw your GUI in Glade and having it run as a web app?&lt;/p&gt;
&lt;p&gt;If you want to create an innovative web framework, you have to start with an innovative language and take advantage of its features. That's what ROR did. I think the same can be done using Boo.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113237756707953966?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113237756707953966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113237756707953966' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113237756707953966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113237756707953966'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/why-not-monorail.html' title='Why not MonoRail?'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113225639056698050</id><published>2005-11-17T11:14:00.000-08:00</published><updated>2005-11-17T12:20:02.316-08:00</updated><title type='text'>Mint-Green Tea Theme for Blogger</title><content type='html'>&lt;p&gt;I became bored of not doing any web stuff so I created a mint-green tea theme for Blogger. Actually, I modified the old orange theme I was using. I'm not that good of a designer but I have a utility called ColorImpact (Windows). It lets you pick a main color then based on different formulas (complements, triad, monochrome, etc) ColorImpact presents a palette of harmonius or complementary colors. I simply used the colors it gave me. I'm a little concerned about not using web safe colors so please let me know if the site looks funky!&lt;/p&gt;

&lt;p&gt;I cleaned up the blogger template to maximize use of space, to focus on content. Nobody likes looking at dead space or scrolling just to read an entry. Most developer's use a theme good for general thoughts but not very good for describing and presenting source examples. I even indented the post bodies ala Boo. I don't know if that's functional but it says this site is about coding. I also de-empasized dates and static links on the sidebar. I removed extraneous information like "posted by Mario Gutierrez". Yeah, it's my blog who else posted it? The only thing left to do is to float the links sidebar and have a minimize button to shrink it. I could not make it work in both IE and FireFox. I used to be a die-hard IE fan, not anymore. Get Firefox!&lt;/p&gt;

&lt;p&gt;It wasn't just a color update! If the layout is distracting, seems crammed or if you have any other suggestions, please leave a comment. I keep these things in mind when building web pages.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113225639056698050?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113225639056698050/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113225639056698050' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113225639056698050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113225639056698050'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/mint-green-tea-theme-for-blogger.html' title='Mint-Green Tea Theme for Blogger'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113216822852470473</id><published>2005-11-16T10:23:00.000-08:00</published><updated>2005-11-16T11:21:24.030-08:00</updated><title type='text'>SharpDevelop, NRefactory Doing it Right</title><content type='html'>&lt;p&gt;If you're like me you probably didn't like SharpDevelop 1.1 too much. It was prone to crash. Since I've been using Boo lately, I gave SharpDevelop 2.0 a look. I build it manually from SVN. What have these guys been drinking? I want some. It's a drastic improvement over the previous version. You still encounter errors here and there but mostly for unimplemented features. It's not ready for prime time as it's a work-in-progress but it's very usable.&lt;/p&gt;

&lt;p&gt;Daniel Grunwald is a machine. In addition to being a mad coder on SharpDevelop team, he's created tutorial videos on how to create add-ins and NRefactory. Check out this video on &lt;a href="http://laputa.sharpdevelop.net/content/binary/NRefactory.wmv"&gt;NRefactory&lt;/a&gt;. Wow! It's only a matter of time before SharpDevelop 2.0 rivals Eclipse in refactoring. Personally, I'd rather have Eclipse-like refactoring and integrated unit-testing than the new stuff in VS2005. I've also heard good comments from the Boo masters the add-in architecture is well thought out. Maybe SharpDevelop will start a trend like Eclipse did for Java. &lt;b&gt;BIG KUDOS&lt;/b&gt; to the SharpDevelop team.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113216822852470473?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113216822852470473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113216822852470473' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113216822852470473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113216822852470473'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/sharpdevelop-nrefactory-doing-it-right.html' title='SharpDevelop, NRefactory Doing it Right'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113212778960987296</id><published>2005-11-15T23:56:00.000-08:00</published><updated>2005-11-16T00:28:26.433-08:00</updated><title type='text'>Reflex Syntax Change</title><content type='html'>&lt;p&gt;After some tinkering with Reflex's grammar, I decided on this (very &lt;a href='http://groovy.codehaus.org'&gt;Groovy&lt;/a&gt;-like):&lt;/p&gt;
&lt;pre&gt;
01: #ref "../../MGutz.Test.dll"
02:
03: new Person() {
04:     Name = 'mario'
05:     Weight = 160
06:     Hobbies = new string['scuba', 'biking']
07:     ID = GetUserID(Name)
08:     Vehicle = new Car('Infiniti', 'G35') {
09:         Color = 'Silver'
10:         Horses = 260
11:     }
12:     return this
13: }
&lt;/pre&gt;
&lt;p&gt;In English, just in case it doesn't make sense:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Load "../../MGutz.Test.dll" &lt;/li&gt;&lt;li&gt;Create a new Person object using default constructor. &lt;/li&gt;&lt;li&gt;Set Name, Weight and Hobbies property &lt;/li&gt;&lt;li&gt;Create a new string array having two values ('scuba' and 'biking') then assign to instance.Hobbies. &lt;/li&gt;&lt;li&gt;Call a method to get information from the database. &lt;/li&gt;&lt;li&gt;Create a new Car object of make 'Infiniti', model 'G35' through the constructor, and assign to vehicle. &lt;/li&gt;&lt;li&gt;Set car's Color, Horses property &lt;/li&gt;&lt;li&gt;Return the root object (if return is omitted the root object is returned). &lt;tt&gt;return&lt;/tt&gt; is used to return the value of a method or property.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Again, Reflex is not meant to be a full blown scripting language. It's a quick, easy way to create objects and invoke methods and properties using reflection with simple syntax. I plan to use it to map database tables and stored procedure results to objects and to map URLs to classes and methods. And, anywhere else I need to do reflection. (A Boo Web 2.0 Framework is coming).&lt;/p&gt;
&lt;pre&gt;
// example in Boo

name = "mario"
weight = "160"
hobbies = "'scuba', 'biking', 'rugby'"

snippet = """
    #ref '../../MGutz.Test.dll'
    new Person() {
        Name = '${name}'
        Weight = ${weight}
        Hobbies = new string[${hobbies}]
    } 
"""

p = Reflex.Eval(snippet) as Person
&lt;/pre&gt;
&lt;pre&gt;
// example in C#

string name = "mario";
string weight = "160";
string hobbies = "'scuba', 'biking', 'rugby'";

string template = @"
    #ref '../../MGutz.Test.dll'
    new Person() {
        Name = '{0}'
        Weight = {1}
        Hobbies = new string[{2}]
    }
";

string snippet = string.Format(template, name, weight, hobbies);
Person p = Reflex.Eval(snippet) as Person;
&lt;/pre&gt;
&lt;p&gt;Reflex is white space agnostic (except for #ref pragma). This is equivalent:&lt;/p&gt;
&lt;pre&gt;
#ref '../../MGutz.Test.dll'
new Person() { Name = '{0}' Weight = '{1}' Hobbies = new string[{2}] }
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113212778960987296?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113212778960987296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113212778960987296' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113212778960987296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113212778960987296'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/reflex-syntax-change.html' title='Reflex Syntax Change'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113212328315425260</id><published>2005-11-15T22:26:00.000-08:00</published><updated>2005-11-15T22:47:18.416-08:00</updated><title type='text'>VS 2005 Annoyance</title><content type='html'>&lt;p&gt;Here's an annoying bug. Look where I'm setting the breakpoint with the mouse. VS2005 isn't even close. This is an intermittent issue. I've always been fond of MS products but i'm not at all impressed with VS2005. VS2003 + Resharper was a much better product. Maybe Resharper spoiled me.&lt;/p&gt;

&lt;img src="http://img230.imageshack.us/img230/300/badbkpoint4vf.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113212328315425260?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113212328315425260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113212328315425260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113212328315425260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113212328315425260'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/vs-2005-annoyance.html' title='VS 2005 Annoyance'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113200740983406417</id><published>2005-11-14T14:29:00.000-08:00</published><updated>2005-11-14T16:02:23.483-08:00</updated><title type='text'>Reflex Reflection Library</title><content type='html'>&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Reflex, short for reflection expressions, is a library in the works to simplify the use of the .NET reflection library. Simply put a consutrctor, method and property class in a string and let Reflex do the work:&lt;/p&gt;
&lt;pre&gt;
// instantiate Math using default constructor, then invoke Add(1,2)
string expression = "Math()::Add(1,2)";
int result = (int) Reflex.Eval(expression);
&lt;/pre&gt;
&lt;p&gt;Without Reflex you would have to get the type, find the constructor, invoke the constructor, cast the the returned type, get the method, build the parameters, then invoke it. What if you already have an instance?&lt;/p&gt;
&lt;pre&gt;
Math m = new Math();
rx = new Reflex(m);
expression = "Add(1,2)";
int result = (int) rx.Invoke(expression);
&lt;/pre&gt;
&lt;h3&gt;Expressions&lt;/h3&gt;&lt;table&gt;&lt;tr&gt;&lt;td align="right"&gt;
&lt;p&gt;&lt;tt&gt;[../../some.dll] SomeClass()::Method()&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;

&lt;p&gt;Loads &lt;tt&gt;some.dll&lt;/tt&gt;, instantiate &lt;tt&gt;SomeClass&lt;/tt&gt; using default constructor, invoke &lt;tt&gt;Method()&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;
&lt;p&gt;&lt;tt&gt;SomeClass::Method()&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Invoke static method &lt;tt&gt;Method()&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;
&lt;p&gt;&lt;tt&gt;Languages["Boo"].Url&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Get the &lt;tt&gt;"Boo"&lt;/tt&gt; entry from dictionary &lt;tt&gt;Languages&lt;/tt&gt;, then get the &lt;tt&gt;Url&lt;/tt&gt;property from the object. &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;

&lt;p&gt;&lt;tt&gt;Languages.Boo.Url&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Same as above, dictionary entries are treated as properties. &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;
&lt;p&gt;&lt;tt&gt;Languages[0].Url&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Get the first entry from dictionary &lt;tt&gt;Languages&lt;/tt&gt;, then get the &lt;tt&gt;Url&lt;/tt&gt;property &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;h3&gt;Require Attribute&lt;/h3&gt;
&lt;p&gt;In some scenarios, Reflex should be prohibited from blindly invoking methods. For example, mapping a URL to classes and methods is a huge security hole. Create an attribute to mark the methods you wish to expose, then use the overloaded &lt;tt&gt;Eval()&lt;/tt&gt; or &lt;tt&gt;Invoke()&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;
// throws an exception, Fibonacci is not marked with [Expose]
Reflex.Eval("Math::Fibonacci(3)", typeof(Expose));
&lt;/pre&gt;
&lt;pre&gt;
class Math {
 [Expose]
 public int Add(int a, int b) {
  return a + b;
 }

 public int Fibonacci(int n) {
 ...
 }
}
&lt;/pre&gt;
&lt;h3&gt;Usage&lt;/h3&gt;
&lt;p&gt;Map a data row to a class.&lt;/p&gt;
&lt;pre&gt;
string template = @"
My.Person()::
    Name = ""{0}""
    Age = {1}
    Height = {2}
";
expression = string.Format(template, row.Name, row.Age, row.Height);
Person p = (Person) Reflex.Eval(expression);
&lt;/pre&gt;
&lt;p&gt;Map url to execute method.&lt;/p&gt;
&lt;pre&gt;
string queryString = "Math/Add?a=1&amp;b=2";
expression = ToExpression(queryString); // convert to "Math()::Add(1, 2)"
int result = (int) rx.Eval(expression);

&lt;/pre&gt;
&lt;p&gt;Instantiate an object from Web.Config setting.&lt;/p&gt;
&lt;pre&gt;
// retrieve from config
string value = "MGutz.Person, Person";
expression = ToExpression(value); // convert to "[MGutz.Person] Person()"
IPerson person = (IPerson) Reflex.Eval(expression);
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113200740983406417?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113200740983406417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113200740983406417' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113200740983406417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113200740983406417'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/reflex-reflection-library.html' title='Reflex Reflection Library'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113182360150160860</id><published>2005-11-12T11:25:00.000-08:00</published><updated>2005-11-12T15:18:51.800-08:00</updated><title type='text'>ne paroli Esperanto</title><content type='html'>&lt;p&gt;i don't speak Esperanto...&lt;/p&gt;
&lt;p&gt;I remember chatting with &lt;em&gt;ckknight&lt;/em&gt; in the IRC and he brought up the Esperanto language. He typed a few phrases and translated. Wow! I didn't really say that but it was interesting. The moral is I didn't know anything about the language, and with the help of a translator I was able to comprehend the sentence.&lt;/p&gt;
&lt;p&gt;Boo has a fantastic extensible compiler. The &lt;tt&gt;InjectCode&lt;/tt&gt; attribute I've been writing about has many possibilities. Yet, I doubt it will get much use outside my projects. If the C# compiler allowed something like &lt;tt&gt;InjectCode&lt;/tt&gt;, there would be some interesting projects around it. C# has partial classes which functionally is what &lt;tt&gt;InjectCode&lt;/tt&gt; does. It builds a partial class in memory at compile time. The important difference is by using &lt;tt&gt;InjectCode&lt;/tt&gt; a source file becomes multi-lingual in the computer language sense. C# only understands C#. &lt;tt&gt;InjectCode&lt;/tt&gt; has the potential to understand any language whether it be in XML, XMI (UML), SQL, etc with the appropriate translator (&lt;tt&gt;ICodeBuilder&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;No programming language or approach has yet solved the dilemma of how to get every member of a team---DBAs, visual designers, coders, architects, analysts ...---to seamlessly work together. Some, like MDA zealots, believe that creating one visual language is the solution. A picture may be worth a thousand words but it takes a thousand pictures to explain the &lt;strong&gt;low-level&lt;/strong&gt; details of an application. I may be reaching here but I think a multi-lingual language that allows each specialist to speak in their domain language may be a big stepping stone in harmonious development. For example, imagine injecting an analyst's use-case constraints directly into a class or method? Yes, some UML tools do that but it's an external, not integrated process. Good IDEs come close to being a multi-lingual language as they can draw forms, create HTML, etc but they're still well-coordinated individual pieces.&lt;/p&gt;
&lt;p&gt;Hmm...maybe it's time to go back to college and do some graduate work.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113182360150160860?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113182360150160860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113182360150160860' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113182360150160860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113182360150160860'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/ne-paroli-esperanto.html' title='ne paroli Esperanto'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113166968706515294</id><published>2005-11-10T16:40:00.000-08:00</published><updated>2005-11-10T20:29:17.640-08:00</updated><title type='text'>Use XSLT Transformations to Ease Glade#</title><content type='html'>&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;This article describes how to use the &lt;tt&gt;XslCodeBuilder&lt;/tt&gt; to simplify cross-platform Gtk# application development.&lt;/p&gt;&lt;h3&gt;Introduction&lt;/h3&gt;&lt;p&gt;In a previous article, I described the implementation of &lt;tt&gt;XslCodeBuilder&lt;/tt&gt; to inject code generated by an XSLT transformation. In this article we'll apply &lt;tt&gt;XslCodeBuilder&lt;/tt&gt; to ease Gtk# development.&lt;/p&gt;&lt;p&gt;There are at least two ways to build a Gtk# application. The first is to use the Gtk# library as is, manually creating widgets and compose them in a hierarchy to build your GUI. The easier way is to use the Glade# library. Draw your GUI using the Glade 2 utility then save the project creating XML metadata in a &lt;tt&gt;.glade&lt;/tt&gt; file. The &lt;tt&gt;.glade&lt;/tt&gt; file is loaded by the &lt;tt&gt;glade-sharp&lt;/tt&gt; library to render your GUI.&lt;/p&gt;&lt;p&gt;Glade development is summed up in these steps:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Draw your GUI - use the glade utility to generate a &lt;tt&gt;.glade&lt;/tt&gt; file &lt;/li&gt;&lt;li&gt;Declare variables for widgets - each widget in a &lt;tt&gt;.glade&lt;/tt&gt; file has a unique id &lt;/li&gt;&lt;li&gt;Set event handlers - each widget has a set of 'signals' or events &lt;/li&gt;&lt;li&gt;Load the &lt;tt&gt;.glade&lt;/tt&gt; file and run&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The rest of the article describes the use of &lt;tt&gt;XslCodeBuilder&lt;/tt&gt; to semi-automate these steps.&lt;/p&gt;&lt;h3&gt;XslCodeBuilder and the Glade stylesheet&lt;/h3&gt;&lt;p&gt;A &lt;tt&gt;.glade&lt;/tt&gt; file is simply an XML file. It's simple enough to create a stylesheet to generate Boo code to perform the steps described above:&lt;/p&gt;&lt;pre&gt;
01 &amp;lt;xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&amp;gt;
02  &amp;lt;xsl:output method="text" /&amp;gt;
03  &amp;lt;xsl:template match="/"&amp;gt;
04      &amp;lt;xsl:apply-templates  select="glade-interface/widget[1]"/&amp;gt;
05      def RunGlade():
06              RunGlade(null)
07      end
08
09      def RunGlade(init as callable):
10          Application.Init()
11          gxml = Glade.XML("view.glade", "window1", null)
12          gxml.Autoconnect(self)
13
14          if init != null:
15              init()
16          end
17
18          Application.Run()
19      end
20  &amp;lt;/xsl:template&amp;gt;
21
22  &amp;lt;!-- build variables --&amp;gt;
23  &amp;lt;xsl:template match="widget"&amp;gt;
24      [Widget]
25      &amp;lt;xsl:value-of select="@id"/&amp;gt; as &amp;lt;xsl:value-of select="substring(@class, 4)"/&amp;gt;
26      &amp;lt;xsl:apply-templates select="child/widget" /&amp;gt;
27  &amp;lt;/xsl:template&amp;gt;
28 &amp;lt;/xsl:stylesheet&amp;gt;
&lt;/pre&gt;&lt;p&gt;Line 03 is the entry point into the stylesheet. The &lt;tt&gt;apply-templates&lt;/tt&gt; statement starts a recursive descent into the XML file invoking any template that matches the current XML node. In this example, there is a template defined for &lt;tt&gt;match="widget"&lt;/tt&gt;. The template emits a declaration like this:&lt;/p&gt;&lt;pre&gt;
[Widget]
id as widgetClass
&lt;/pre&gt;&lt;p&gt;After all the widgets are found, processing continues at line 05 which emits overloaded methods of &lt;tt&gt;RunGlade()&lt;/tt&gt;. The XSL-savvy will realize this stylesheet only acts on the first widget from the root and all its children. This is just a sample stylesheet. In all honesty I'm a Glade# NoOB. I need a better understanding of Glade to create a robust stylesheet.&lt;/p&gt;&lt;p&gt;Anyway, here is the source of a basic Glade# application using &lt;tt&gt;XslCodeBuilder&lt;/tt&gt; and the stylesheet:&lt;/p&gt;&lt;pre&gt;
import Gtk from "gtk-sharp"
import Glade from "glade-sharp"
import MGutz.CodeInjection from "MGutz.CodeInjection"

[InjectCode(XslCodeBuilder, "view.glade;glade.xsl")]
public class GladeView:
    def Run():
        RunGlade()
&lt;/pre&gt;
&lt;p&gt;&lt;tt&gt;InjectCode&lt;/tt&gt; generates this code and stores it in a file
so you can step through it in the debugger if needed:&lt;p&gt;
&lt;pre&gt;
    [Widget]
    window1 as Window
    [Widget]
    vbox1 as VBox
    [Widget]
    toolbar1 as Toolbar
    [Widget]
    openButton as ToolButton
    [Widget]
    quitButton as ToolButton
    [Widget]
    scrolledwindow1 as ScrolledWindow
    [Widget]
    textview1 as TextView

    def RunGlade():
            RunGlade(null)
    end

    def RunGlade(init as callable):
        Application.Init()
        gxml = Glade.XML("view.glade", "window1", null)
        gxml.Autoconnect(self)

        if init != null:
            init()
        end

        Application.Run()
    end
&lt;/pre&gt;

&lt;p&gt;Create and compile a simple controller then run it:&lt;/p&gt;&lt;pre&gt;
o = GladeView()
o.Run()
&lt;/pre&gt;&lt;p&gt;&lt;img src="http://img45.imageshack.us/img45/4172/window16bv.png"&gt;&lt;/img&gt;&lt;/p&gt;&lt;p&gt;If you click on either button nothing will happen. We need to hook events and display a &lt;tt&gt;FileChooserDialog&lt;/tt&gt; when the Open button is clicked.&lt;/p&gt;&lt;pre&gt;
[InjectCode(XslCodeBuilder, "view.glade;glade.xsl")]
public class GladeView:
    def Run():
        RunGlade(Init)

    def Init():
        quitButton.Clicked += OnQuitButtonClicked
        openButton.Clicked += OnOpenButtonClicked

    def OnQuitButtonClicked():
        Application.Quit()

    def OnOpenButtonClicked():
        fcd = FileChooserDialog(Title: "Select File")
        fcd.AddButton("OK", ResponseType.Accept)
        fcd.AddButton("Cancel", ResponseType.Cancel)
        try:
            response = cast(ResponseType, fcd.Run())
            if (response == ResponseType.Accept):
                file = fcd.Filename
                using reader = StreamReader(file):
                    textview1.Buffer.InsertAtCursor(reader.ReadToEnd())
        ensure:
            fcd.Destroy()
&lt;/pre&gt;&lt;p&gt;The overloaded &lt;tt&gt;RunGlade(callable)&lt;/tt&gt; is used to set event handlers. The handlers are self-explanatory. Run the controller, then click open&lt;/p&gt;&lt;p&gt;&lt;img src="http://img45.imageshack.us/img45/3981/window24ov.png"&gt;&lt;/img&gt;&lt;/p&gt;&lt;p&gt;File loaded&lt;/p&gt;&lt;p&gt;&lt;img src="http://img45.imageshack.us/img45/5408/window39kf.png"&gt;&lt;/img&gt;&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;I've shown how to use &lt;tt&gt;XslCodeBuilder&lt;/tt&gt; to transform Glade's XML metadata to inject Boo code into a class.&lt;/p&gt;&lt;p&gt;Glade masters are probably thinking this doesn't save much time. I agree somewhat. The point is it does save time. When &lt;tt&gt;partial&lt;/tt&gt; classes are merged into Boo event handlers can be autogenerated into a &lt;tt&gt;partial&lt;/tt&gt; file to survive round-trips between regeneration. I didn't attempt to do that in this example as it's bad kharma to modify the source of the decorated class.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113166968706515294?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113166968706515294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113166968706515294' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113166968706515294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113166968706515294'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/use-xslt-transformations-to-ease-glade.html' title='Use XSLT Transformations to Ease Glade#'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113165850639359991</id><published>2005-11-10T13:33:00.000-08:00</published><updated>2005-11-10T20:50:25.866-08:00</updated><title type='text'>How to Inject Code from XSLT Transformations</title><content type='html'>&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;This tutorial describes how to implement an &lt;tt&gt;ICodeBuilder&lt;/tt&gt; class to inject code from the result of an XSLT transformation.&lt;/p&gt;&lt;h3&gt;Introduction&lt;/h3&gt;&lt;p&gt;Application frameworks and GUI builders create and store metadata in XML format. We can take advantage of this metadata to autogenerate code. We can not only generate code, we can attach metadata to a class by utilizing the &lt;tt&gt;MGutz.CodeInjection&lt;/tt&gt; library. When the metadata changes the booc compiler will update the class during the compilation phase.&lt;/p&gt;&lt;p&gt;The compiler cannot perform this magic on its own. We must create a class derived from &lt;tt&gt;AbstractAstAttribute&lt;/tt&gt; to manipulate the AST nodes the compiler works with. The &lt;tt&gt;MGutz.CodeInjection.InjectCodeAttribute&lt;/tt&gt; does exactly that, it uses 'lower-level' operations to inject code. &lt;tt&gt;InjectCodeAttribute&lt;/tt&gt; is flexible in the sense that it can use any &lt;tt&gt;ICodeBuilder&lt;/tt&gt; object to build a string containing Boo code.&lt;/p&gt;&lt;p&gt;The rest of the tutorial describes the steps to implement &lt;tt&gt;XslCodeBuilder&lt;/tt&gt;, an &lt;tt&gt;ICodeBuilder&lt;/tt&gt; derived object that uses the result of an XSLT transformation to inject code.&lt;/p&gt;&lt;h3&gt;Implementing XslCodeBuilder&lt;/h3&gt;&lt;p&gt;We have two options to process XML metadata: 1) create a dedicated &lt;tt&gt;ICodeBuilder&lt;/tt&gt; to process specific XML metadata with &lt;tt&gt;XmlTextReader&lt;/tt&gt; and Boo code, or 2) use XSL transformations. The first option is the most flexible as you have the entire framework class library at your disposal. The second option is an all-purpose solution using XSL stylesheets. I'll take the second approach for this article. The end goal is to decorate a class with an attribute that says take this xml file, transform it to Boo code then inject the code into the class during compile time. In other words,&lt;/p&gt;&lt;pre&gt;
[InjectCode(XslCodeBuilder, "metadata.xml;test.xsl")]
class XslTest:
    pass
&lt;/pre&gt;&lt;p&gt;To create a code builder implement the &lt;tt&gt;MGutz.CodeInjection.ICodeBuilder&lt;/tt&gt; interface. The source for XslCodeBuilder is fairly simple.&lt;/p&gt;&lt;pre&gt;
01 public class XslCodeBuilder(ICodeBuilder):
02  TargetParser as BooParserType:
03      get:
04          return BooParserType.WSABooParser
05
06  def BuildCode([required] arg as string, [required] klass as ClassDefinition) as string:
07      // parse xml and xsl file name
08      args = arg.Split(char(';'))
09      if args.Length &amp;lt; 2:
10          raise ArgumentOutOfRangeException("arg", "Expected '&amp;lt;xml-file&amp;gt;;&amp;lt;xsl-file&amp;gt;', received: " + arg)
11      xml = args[0].Trim()
12      xsl = args[1].Trim()
13
14      // files are located in same folder as class
15      xml = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(klass.LexicalInfo.FileName)), xml)
16      xsl = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(klass.LexicalInfo.FileName)), xsl)
17
18      // transform to WSABoo code
19      using reader = StreamReader(xml):
20          xmlDoc = XPathDocument(reader)
21          stylesheet = XslTransform()
22          stylesheet.Load(xsl)
23          writer = StringWriter()
24          stylesheet.Transform(xmlDoc, null, writer, null)
25          return writer.ToString()
&lt;/pre&gt;&lt;p&gt;At line 02, &lt;tt&gt;TargetParser&lt;/tt&gt; informs &lt;tt&gt;InjectCode&lt;/tt&gt; that &lt;tt&gt;XslCodeBuilder&lt;/tt&gt; is building WSABoo (white space agnostic) code. It's very difficult to control indentation in an XSL file. Don't waste any time making it pretty. This is a shortcoming of languages like Boo that rely on indentation. Fortunately, the Boo masters realized this and provide a &lt;tt&gt;WSABooParser&lt;/tt&gt; class to handle the situation.&lt;/p&gt;&lt;p&gt;At line 16, &lt;tt&gt;InjectCode&lt;/tt&gt; calls &lt;tt&gt;BuildCode()&lt;/tt&gt; to build code. It has two arguments. &lt;tt&gt;arg&lt;/tt&gt; is the argument from the attribute declaration, e.g. &lt;tt&gt;"metadata.xml;test.xsl"&lt;/tt&gt;. &lt;tt&gt;klass&lt;/tt&gt; is the AST node of the decorated class.&lt;/p&gt;&lt;p&gt;The rest of the code converts the arguments into absolute paths then performs the XSLT transformation. The transformation result is returned to &lt;tt&gt;InjectCode&lt;/tt&gt; as a string.&lt;/p&gt;&lt;h3&gt;Using XslCodeBuilder&lt;/h3&gt;&lt;p&gt;This example is found in the &lt;tt&gt;example/xsl&lt;/tt&gt; directory.&lt;/p&gt;&lt;p&gt;First, decorate the class with &lt;tt&gt;InjectCode&lt;/tt&gt; attribute. The example specifies &lt;tt&gt;test.xml&lt;/tt&gt; as the metadata and &lt;tt&gt;test.xsl&lt;/tt&gt; as the stylesheet.&lt;/p&gt;&lt;pre&gt;
# XslView.boo
import MGutz.CodeInjection from MGutz.CodeInjection

[InjectCode(XslCodeBuilder, "test.xml;test.xsl")]
class XslTest:
    pass
&lt;/pre&gt;&lt;pre&gt;
# test.xml - metadata
&amp;lt;def name="KR" comment="white book"&amp;gt;
    print "Hello world!"
&amp;lt;/def&amp;gt;
&lt;/pre&gt;&lt;pre&gt;
# test.xsl - stylesheet to transform metadata into WSABoo code
&amp;lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&amp;gt;
    &amp;lt;xsl:output method="text"/&amp;gt;
    &amp;lt;xsl:template match="/"&amp;gt;
        &amp;lt;xsl:apply-templates /&amp;gt;
    &amp;lt;/xsl:template&amp;gt;

    &amp;lt;xsl:template match="def"&amp;gt;
        # &amp;lt;xsl:value-of select="@comment"/&amp;gt;
        def &amp;lt;xsl:value-of select="@name"/&amp;gt;():
            &amp;lt;xsl:value-of select="."/&amp;gt;
        end
    &amp;lt;/xsl:template&amp;gt;

&amp;lt;/xsl:stylesheet&amp;gt;
&lt;/pre&gt;&lt;p&gt;Create a simple controller to use the &lt;tt&gt;XslTest&lt;/tt&gt;.&lt;/p&gt;&lt;pre&gt;
o = XslTest()
o.KR()
&lt;/pre&gt;&lt;p&gt;Compile it all together, then run it. The build file for the example creates an executable &lt;tt&gt;xsl.exe&lt;/tt&gt;:&lt;/p&gt;&lt;pre&gt;
&amp;gt; xsl
Helo world!
&lt;/pre&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;This article described the implementation of &lt;tt&gt;XslCodeBuilder&lt;/tt&gt;, an &lt;tt&gt;ICodeBuilder&lt;/tt&gt; derived class to perform XSLT transformations on XML metadata generating Boo code. The Boo code is injected into a decorated class each time the class is compiled syncing the class with the metadata.&lt;/p&gt;&lt;p&gt;A future article applies &lt;tt&gt;XslCodeBuilder&lt;/tt&gt; to Glade#/Gtk# application development.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113165850639359991?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113165850639359991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113165850639359991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113165850639359991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113165850639359991'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/how-to-inject-code-from-xslt.html' title='How to Inject Code from XSLT Transformations'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113152982499958258</id><published>2005-11-09T01:45:00.000-08:00</published><updated>2005-11-09T12:16:42.886-08:00</updated><title type='text'>Dependency Injection and Scripted Configuration for Enterprise Development - Part 2</title><content type='html'>&lt;h3&gt;Nano and a Configuration Script - Thinking Outside the Box&lt;/h3&gt;
&lt;p&gt;In this part of the article series, I discuss the external configuration file NanoContainer compiles and invokes to create a managed container of objects. An application retrieves objects from this managed container to perform business logic. These objects are not necessarily instantiated. They may be lazy-loaded for performance and resource considerations.&lt;/p&gt;
&lt;p&gt;To get a better idea how Nano integrates with an application, consider this sequence diagram:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img346.imageshack.us/img346/8605/seqdiag11xd.png" /&gt;
&lt;/p&gt;&lt;ol&gt;
 &lt;li&gt;Administrator starts an application. &lt;/li&gt;
 &lt;li&gt;Application asks Nano to create a container. &lt;/li&gt;
 &lt;li&gt;Nano compiles the configuration script. &lt;/li&gt;
 &lt;li&gt;Nano sets IScript.Parent to a default container. &lt;/li&gt;
 &lt;li&gt;Nano asks the script to Compose() the container. &lt;/li&gt;
 &lt;li&gt;Script returns a container. &lt;/li&gt;
 &lt;li&gt;Nano returns the container to the application. &lt;/li&gt;
 &lt;li&gt;Application requests objects from the container and uses them to perform busines logic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pretty simple, eh? It's worth reiterating that Nano can use a script written in practically any .NET supported language---Boo, C#, VB, JS, JavaScript, VBScript or even an XML configuration file.
 Pick your poison. One benefit of using Boo (other than it's more elegant than the other .NET languages) is that a Boo install has an interpreter which may be used to run the script independent of the application! Nano gives a team the full power of any .NET language to configure an application. At first this may not seem to be much of an advantage. Think outside of the box! What if a a configuration file could test itself? What if a configuration file could perform a check on its environment before running an application? What if a configuration file could test for missing property values? What if a configuration file could swap in mock objects? A scripted configuration file's behaviour is only limited by your coding skills. Before we go into the actual configuration file, consider the class diagram for this configuration block.&lt;/p&gt;&lt;img src="http://img346.imageshack.us/img346/7417/clsdiag10xc.png" /&gt;&lt;/img&gt;

&lt;table cellpadding="4"&gt;&lt;tr&gt;&lt;th&gt;
&lt;p&gt;Class &lt;/p&gt;&lt;/th&gt;&lt;th&gt;
&lt;p&gt;Purpose &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;ConfigBase &lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Is the base class for all configuration files. The class contains methods to check for missing keys, test settings any other future features. It also contains a &lt;tt&gt;Settings&lt;/tt&gt; hash to hold objects derived from &lt;tt&gt;SettingBase&lt;/tt&gt;.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;SettingBase &lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Is the base class for all settings. This class defines an abstract test method that must be implemented.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;RequiredSetting &lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Defines a setting that is required. When &lt;tt&gt;Test()&lt;/tt&gt; is executed it always throws an exception. Must be replaced by another setting.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;StringSetting &lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Defines a string setting. &lt;tt&gt;Test()&lt;/tt&gt; simply returns with no side effect&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;td&gt;
&lt;p&gt;SafeCreateDirSetting &lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Safely creates a directory. &lt;tt&gt;Test()&lt;/tt&gt; creates the directory if it does not exist. It's assumed &lt;tt&gt;Test()&lt;/tt&gt; will be called once.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;
&lt;p&gt;SqlConnectionStringSetting &lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Defines a SqlConnection string. &lt;tt&gt;Test()&lt;/tt&gt; will attempt to open a connection to the database.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;BooConfig &lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Is the external script file. It does not reside in the &lt;tt&gt;ConfigBlock&lt;/tt&gt; assembly.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;The complete source of the configuration file follows:&lt;/p&gt;&lt;pre&gt;
# BooConfig.boo - compiled by NanoContainer when an application starts.
01 class BooConfig(ConfigBase):
02     # Gets or sets check mode.
03     [property(IsCheck)]
04     _isCheck = false
05
06     # Populates the master settings hash.
07     override def PopulateSettings():
08         Settings = {
09             "name" : StringSetting("mgutz"),
10             "connectionString" : RequiredSetting(),
11             "logDirectory" : SafeCreateDirSetting("/temp/log")
12         }
13
14     # Set the environment for DEV.
15     private def DEV():
16         Settings["connectionString"] = SqlConnectionStringSetting("Server=(local);Database=devapp;uid=boodev;pwd=boodev")
17
18     # Set the envrionment for TEST.
19     private def TEST():
20         pass
21
22     # Set the environment for PROD.
23     private def PROD():
24         Settings["connectionString"] = SqlConnectionStringSetting("Server=(local);Database=prodapp;uid=booprod;pwd=booprod")
25
26     # Composes the object container used by an application.
27     # This method is invoked by an application.
28     override def Compose() as IMutablePicoContainer:
29         _container = DefaultPicoContainer(Parent)
30
31         # change to match environment, could be automated by pinging a unique serverr
32         EnvironmentMethod = DEV
33         ConfigureEnvironment(_isCheck)
34
35         # register an instance of an object
36         _container.RegisterComponentInstance("name", Settings["name"].ToString())
37
38         # lazy-load a connection object by registering its implementation not instance
39         _container.RegisterComponentInstance("dbConnectionString", Settings["connectionString"].ToString())
40         params = array (IParameter, (ComponentParameter("dbConnectionString"),))
41         _container.RegisterComponentImplementation("dbConnection", SqlConnection, params)
42
43         # return the container
44         return _container
45
46 # A check on the environment is performed when this script is called from
47 # booi interpreter. When this script compiled by Nano, this method is not invoked.
48 # These are the same steps taken by the NanoBoo contaienr except the .IsCheck
49 # attribute is not set.
50 def main():
51     config = BooConfig()
52     config.Parent = DefaultPicoContainer()
53     config.IsCheck = true
54     config.Compose()
55
56 main()
&lt;/pre&gt;
&lt;p&gt;The Boo file contains a single class &lt;tt&gt;BooConfig&lt;/tt&gt; derived from &lt;tt&gt;ConfigBase&lt;/tt&gt;. Line 32 must be changed based on which environment the application is deployed. This could be automated by pinging a unique server in each environment. If the server pings back, use the appropriate environment method. Additionally, the file contains a &lt;tt&gt;main()&lt;/tt&gt; method that is executed when the file is run from the command line:&lt;/p&gt;&lt;pre&gt;
&amp;gt; booi BooConfig.boo
&lt;/pre&gt;
&lt;p&gt;So, what is happening?&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img346.imageshack.us/img346/8110/seqdiag26oc.png" /&gt;&lt;/p&gt;
&lt;p&gt;First, excuse the sequence diagram. Apparently my UML CASE tool can't handle         wierd sequences. The lifeline of the methods should be continous as all of this is actioned in one call to Compose().&lt;/p&gt;&lt;ol&gt;
 &lt;li&gt;Nano, if application is running, or &lt;tt&gt;booi&lt;/tt&gt;, if run from command line, invokes &lt;tt&gt;Compose()&lt;/tt&gt; to create a container.&lt;/li&gt;
 &lt;li&gt;Script file creates a container to hold objects it builds. &lt;/li&gt;
 &lt;li&gt;Script file sets the environment method callback. &lt;/li&gt;
 &lt;li&gt;Script file asks &lt;tt&gt;ConfigBase&lt;/tt&gt; to configure the environment. &lt;/li&gt;
 &lt;li&gt;&lt;tt&gt;ConfigBase&lt;/tt&gt; in turn asks the script file to populate the &lt;tt&gt;Settings&lt;/tt&gt; hash. &lt;/li&gt;
 &lt;li&gt;&lt;tt&gt;ConfigBase&lt;/tt&gt; then invokes the environment method, say &lt;tt&gt;DEV()&lt;/tt&gt; to use settings specific to the &lt;tt&gt;DEV&lt;/tt&gt; environment. &lt;/li&gt;
 &lt;li&gt;If checkEnvironment was true, &lt;tt&gt;ConfigBase&lt;/tt&gt; checks for missing keys by iterating over the hash looking for &lt;tt&gt;null&lt;/tt&gt; or &lt;tt&gt;RequiredSetting()&lt;/tt&gt; objects. &lt;/li&gt;
 &lt;li&gt;If checkEnvironment was true, &lt;tt&gt;ConfigBase&lt;/tt&gt; iterates over the &lt;tt&gt;Settings&lt;/tt&gt; hash invoking &lt;tt&gt;SettingBase.Test()&lt;/tt&gt; on each object. This tests database connections, missing directories, web service connections, etc. &lt;/li&gt;
 &lt;li&gt;Flow returns to the script file, where it nows registers implementations and instance of objects storing them into the container previously built. See lines 35-41 where objects are inserted into the container. &lt;/li&gt;
 &lt;li&gt;The container is returned ending the sequence diagram.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you can see, a script configuration file can be much more than static key and value pairs. With a little bit of thought, it's very easy to create a
 configuration block of your own that goes far beyond the Microsoft Enterprise Configuration Block.This article described a simple, yet powerful configuration block that:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;Adapts an application to different server environments &lt;/li&gt;
 &lt;li&gt;Validates the existence of required settings &lt;/li&gt;
 &lt;li&gt;Performs test based on the type of setting &lt;/li&gt;
 &lt;li&gt;May be edited and tested by an administrator before running an application &lt;/li&gt;
 &lt;li&gt;Inserts object instances and implementations (lazy-loading) into a managed container&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The block could easily be extended by creating additional &lt;tt&gt;SettingBase&lt;/tt&gt;-derived classes. Some examples include:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;PingSetting - ability to ping expected servers &lt;/li&gt;
 &lt;li&gt;FtpSetting - checks an FTP connection and perhaps drop files into it &lt;/li&gt;
 &lt;li&gt;HTTPSSetting - ensure SSL certificates are accepted &lt;/li&gt;
 &lt;li&gt;EmailSetting - validate mail servers &lt;/li&gt;
 &lt;li&gt;etc., etc., etc.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;To be continued...&lt;/h3&gt;
&lt;p&gt;Indeed this is just the tip of the iceberg. I intend to create a Utility class to faciliate use of PicoContainer. It's just too much typing and looks more complicated than it really is. In the next part, I'll cover a few scenarios describing the tangible benefits of NanoContainer in testing and refactoring.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113152982499958258?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113152982499958258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113152982499958258' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113152982499958258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113152982499958258'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/dependency-injection-and-scripted_09.html' title='Dependency Injection and Scripted Configuration for Enterprise Development - Part 2'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113149416743468403</id><published>2005-11-08T15:45:00.000-08:00</published><updated>2005-11-08T15:56:45.520-08:00</updated><title type='text'>C#, VB to Boo Converter in SharpDevelop</title><content type='html'>&lt;p&gt;I just did an svn update on SharpDevelop. Daniel Grunwald imported a standalone C#/VB to Boo converter. Awesome! I was about to do this myself. Anyways, it's as simple as this:&lt;/p&gt;
&lt;pre&gt;    StandaloneConverter -o boofiles d:\temp\someCsProject&lt;/pre&gt;
&lt;p&gt;This recursively converts any C# or VB source file found under &lt;code&gt;d:\temp\someCsProject&lt;/code&gt; into a Boo file into &lt;code&gt;boofiles&lt;/code&gt;. The directory structure is maintained. A huge time saver! Wish it had a simpler name though like csvb2boo.&lt;/p&gt;
&lt;p&gt;This has been a good week for updates: TestDriven.NET, GhostDoc, StandAloneConverter&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113149416743468403?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113149416743468403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113149416743468403' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113149416743468403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113149416743468403'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/c-vb-to-boo-converter-in-sharpdevelop.html' title='C#, VB to Boo Converter in SharpDevelop'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113147808646334152</id><published>2005-11-08T11:16:00.000-08:00</published><updated>2005-11-08T11:47:35.236-08:00</updated><title type='text'>Dependency Injection and Scripted Configuration for Enterprise Development - Part 1</title><content type='html'>&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;This article describes how script-like configuration files and the Dependency Injection pattern (DI) prevent many of the issues encountered when building an enterprise-level application. Two relatively unknown and powerful open source technologies are used: &lt;b&gt;NanoContainer.NET&lt;/b&gt; IoC framework and the agile .NET language &lt;b&gt;Boo&lt;/b&gt;.&lt;/p&gt;
&lt;h3&gt; Application Configuration&lt;/h3&gt;
&lt;p&gt;An application typically configures itself by retrieving settings from a static configuration file in the form of XML, property files, registry values or some other text format. The setting values are used to instantiate objects, then objects are wired together to perform the functions of the application. If implemented poorly, this infrastructure logic is the source of many bugs and wasted man hours. Even when implemented properly the infrastructure logic is intertwined with business logic deviating from the Separation of Concerns principle.&lt;/p&gt;
&lt;p&gt;The dependency injection pattern (DI), in practical terms, is the opposite. DI injects dependencies into an application instead of the application pulling and building its dependencies in code. DI injects pre-wired, ready-to-use objects into an application. The application simply asks for a database connection from a managed container instead of retrieving a connection string then instantiating a database connection object. An application simply uses a pipeline object containing wired pipes and filters without having any knowledge of sequence or how to instantiate pipes and filters. The developer focuses on business logic. Factories, singletons become redundant. Unit testing is easier as mock objects are easily injected without any change to the application.&lt;/p&gt;
&lt;p&gt;I use the term DI very loosely. DI is not a design pattern in the sense that it can described within a UML class diagram. DI is a methodology. DI is the fundamental principle behind Inversion of Control (IoC) frameworks. These frameworks not only build and instantiate objects, they provide additional benefits such as interceptors, object pooling, objects lifecycles, etc.&lt;/p&gt;
&lt;h3&gt;Application Deployment&lt;/h3&gt;
&lt;p&gt;Most medium to large teams deploy aplications to different server environments as an application matures in the development cycle. Environments have a similar network infrastructure and run the same version of software as the actual production environment. Each environment serves a specific purpose whether it be for integration, testing or staging for actual deployment. Here are some common environments utilized within a development cycle:&lt;/p&gt;&lt;table cellpadding="4"&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;&lt;tt&gt;PERSONAL&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;Individual developer box with isolated database, web server, etc. Virtual machine software is an indispensible tool for emulating the servers found in production. &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;&lt;tt&gt;DEV&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;An application is deployed to DEV when a developer has met all requirement for his task including successful unit tests. Developer's are usually given admin access to servers in this environment to facilitate diagnosis of issues that surface. Preliminary black-box testing is performed against this environment in preparation for formal testing. (Try to run the same tests as QA). Developers must resist the urge to deploy a single web page or assembly. Fully automated installations are a must. &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;&lt;tt&gt;TEST&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;The quality assurance (QA) team's environment. Developers do not have server access to this environment. Installation, database script issues, trivial bugs should have been caught in the &lt;tt&gt;DEV&lt;/tt&gt; environment. The QA team tests the application at a much higher level and more than likely different than developers ensuring the application meets business requirements. It behooves the development team to build or reuse a logging framework to not only log diagnostic messages but also have a website/tool to view and query the logs. &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;p&gt;&lt;tt&gt;PROD&lt;/tt&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;
&lt;p&gt;The &lt;strong&gt;exact same&lt;/strong&gt; application bits passed in &lt;tt&gt;TEST&lt;/tt&gt; are deployed to &lt;tt&gt;PROD&lt;/tt&gt;. The logging threshold is increased to log info and errors. &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;What can go wrong? Many things, and it will! Some of the culprits are access permissions, invalid or missing configuration settings, DLL hell (Java and .NET too), different software on the servers, bad network connection, missing keys in the database, human error, etc---so much can go wrong.&lt;/p&gt;
&lt;h3&gt;To be continued...&lt;/h3&gt;
&lt;p&gt;In the next article I'll detail how configuration scripts, written in any .NET supported language (Boo, C#, VB, J#, JavaScript and VBScript), and the NanoContainer.NET IoC framework alleviate configuration and deployment issues. I'll cover Boo specifically as it provides additional benefits over C# and VB.NET.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113147808646334152?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113147808646334152/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113147808646334152' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113147808646334152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113147808646334152'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/dependency-injection-and-scripted.html' title='Dependency Injection and Scripted Configuration for Enterprise Development - Part 1'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113095423695284774</id><published>2005-11-02T09:42:00.000-08:00</published><updated>2005-11-02T10:04:39.450-08:00</updated><title type='text'>When is a PDB not a PDB?</title><content type='html'>&lt;p&gt;I have been trying all week to debug the CodeInjection library using the .NET SDK's CLR debugger &lt;tt&gt;clrdebug.exe&lt;/tt&gt;. I was able to step through several examples but not the library itself. I checked for the .PDB file and it was there! WTF is going on? I searched the web for a PDB dumper/lister/viewer, nothing. I had no choice but to break out a hex editor. Voila. I don't know what the heck I was looking at but I noticed the executables I could debug had the source filenames embedded into them, my library did not.&lt;/p&gt;&lt;p&gt;I was building them differently. It turns out booc, the command line version, has Parameters.Debug set to true by default, and booc, the NANT task has it false by default even though it generates a .PDB file. Make sure to set &lt;tt&gt;debug&lt;/tt&gt; to &lt;tt&gt;true&lt;/tt&gt; if you want to use &lt;tt&gt;clrdbg&lt;/tt&gt;.&lt;/p&gt;&lt;pre&gt;
    &amp;lt;booc output="${build.dir}/MGutz.CodeInjection.dll" target="library" debug="${debug}"&amp;gt;
        ...
    &amp;lt;/booc&amp;gt;
&lt;/pre&gt;&lt;p&gt;Here's another tip. If you want the debugger to come up automatically, put this in your code.&lt;/p&gt;&lt;pre&gt;
    // Windows will prompt to start the debugger (if you have SDK installed)
    System.Diagnostics.Debugger.Break() 
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113095423695284774?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113095423695284774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113095423695284774' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113095423695284774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113095423695284774'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/when-is-pdb-not-pdb.html' title='When is a PDB not a PDB?'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113087562643936381</id><published>2005-11-01T12:02:00.000-08:00</published><updated>2005-11-01T12:11:10.296-08:00</updated><title type='text'>CodeInjection uploaded to boo-contrib</title><content type='html'>&lt;p&gt;I've uploaded the CodeInjection library to boo-contrib. The SVN adress:&lt;/p&gt;&lt;blockquote&gt;svn+ssh://anonymous@forgesvn1.novell.com/svn/boo-contrib/trunk/mgutz&lt;p&gt;password: anonymous&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;You'll have to enter the password several times if you're using TortoiseSVN.&lt;/p&gt;&lt;p&gt;You'll need the SVN version of Boo. I'm using a helper method in CompilerErrorFactory not found in the current binary release.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113087562643936381?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113087562643936381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113087562643936381' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113087562643936381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113087562643936381'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/11/codeinjection-uploaded-to-boo-contrib.html' title='CodeInjection uploaded to boo-contrib'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113079192111109621</id><published>2005-10-31T12:41:00.000-08:00</published><updated>2005-10-31T17:08:18.686-08:00</updated><title type='text'>Brail, the genesis</title><content type='html'>&lt;p&gt;A Jason fellow left a &lt;a href="http://www.blogger.com/comment.g?blogID=18278253&amp;amp;postID=113026082912568931"&gt;comment&lt;/a&gt; about the simliarities of &lt;tt&gt;TemplateCodeBuilder&lt;/tt&gt; to Ayende's &lt;a href="http://www.ayende.com/projects/brail.aspx"&gt;Brail&lt;/a&gt;. Funny he should mention that. I have been thinking about creating an open-source project for quite some time. I initially wanted to create a .NET Web MVC framework but stumbled upon &lt;a href="http://www.castleproject.org"&gt;Castle&lt;/a&gt;. Why build yet another web framework?&lt;/p&gt;&lt;p&gt;Castle has multiple view engines. I found Brail intriguing because of Ayende's choice of language, Boo. I knew Ayende was a keen guy based on the ideas written on his blog, so Boo was worth a looksie. Wow!&lt;/p&gt;&lt;p&gt;One day I was coding and it hit me ... In one hand I had just discovered a great .NET language, Boo, built on an exensible compiler architecture. In my other hand I was creating a &lt;a href="http://www.sqlite.org"&gt;SQLite&lt;/a&gt; provider for &lt;a href="http://www.codesmithtools.com"&gt;CodeSmith&lt;/a&gt;. Why not create an open source code generation framework? Why not extend Boo to convert templates into code so you don't need CodeSmith or &lt;a href="http://www.mygenerationsoftware.com"&gt;MyGeneration&lt;/a&gt;? Why not generalize the idea and transform any metadata into code? Why not indeed.&lt;/p&gt;&lt;p&gt;It comes as no surprise then that my first example is Brail like. It's funny how things come full circle.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113079192111109621?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113079192111109621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113079192111109621' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113079192111109621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113079192111109621'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/10/brail-genesis.html' title='Brail, the genesis'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113073055186630492</id><published>2005-10-30T19:48:00.000-08:00</published><updated>2005-10-30T19:58:18.983-08:00</updated><title type='text'>CodeInjection next steps</title><content type='html'>&lt;p&gt;I'm close to releasing the &lt;tt&gt;CodeInjection&lt;/tt&gt; library. The only issue I have left is how to force the debugger to step into the intermediate files &lt;tt&gt;InjectCode&lt;/tt&gt; generates. I'll chat with the Boo masters on IRC and get some ideas.&lt;/p&gt;&lt;p&gt;So, what's next? I'll write yet another article on how to use this new facility to fill in your classes from an iBATIS.NET data mapping.&lt;/p&gt;&lt;p&gt;iBATIS.NET is a data access framework. If I had to categorize it, it's somewhere between &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/daab.asp"&gt;Microsoft's Enterprise DAAB&lt;/a&gt; and &lt;a href="http://wiki.nhibernate.org/display/NH/Home"&gt;NHibernate&lt;/a&gt;. Most enterprise projects I've been involved with forbid me or any developer from touching the database. (They eventually let me since I'm pretty good with T-SQL). In general, DBAs are responsible for creating stored procs and permissions. No direct SQL to the database. iBATIS is perfect for this since it can map any SQL including stored procedures to objects. It doesn't try to do what NHibernate does but it does map to objects which the DAAB doesn't. With code injection your code will always be in sync with your data mapping file. Of course, you could take it a step further and generate your data mapping file using &lt;tt&gt;AspTemplateCodeBuilder&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;FYI: The ANTLR packaged with Boo generates Boo code. NICE! I found a couple of bugs and entered them into JIRA but they're minor. I used it to parse the ASP-like template files.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113073055186630492?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113073055186630492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113073055186630492' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113073055186630492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113073055186630492'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/10/codeinjection-next-steps.html' title='CodeInjection next steps'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113072954386896663</id><published>2005-10-30T19:22:00.000-08:00</published><updated>2005-10-30T20:20:24.776-08:00</updated><title type='text'>Boo as a configuration language</title><content type='html'>&lt;p&gt;I wrote an article for CodeProject.com extolling the benefits of scripting (Boo, C#) over static XML, INI files for application configuration. I never submitted and now I can't find it! It explained how a script file can perform a precheck of the environment before starting the application. For example, the configuration file could check a database connection, pull down a WSDL to validate a web service connection, etc. Boo is perfect for this since an administrator can change a value in the Boo script and simply run it again with &lt;tt&gt;booi&lt;/tt&gt;. The application uses the script file to configure itself without having to do any casts to strings, etc. Moreover, scripts can detect missing key values across different environments---development, test and production.&lt;/p&gt;&lt;p&gt;I'll write it up again. If you're wondering, it's Boo + dependency injection, a potent combination.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113072954386896663?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113072954386896663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113072954386896663' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113072954386896663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113072954386896663'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/10/boo-as-configuration-language.html' title='Boo as a configuration language'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113063308872862838</id><published>2005-10-29T17:44:00.000-07:00</published><updated>2005-10-29T19:20:13.446-07:00</updated><title type='text'>Boo is mixin it up</title><content type='html'>&lt;p&gt;What is a &lt;em&gt;mixin&lt;/em&gt;? A &lt;em&gt;mixin&lt;/em&gt; is an interface with implemented methods. When a class includes a &lt;em&gt;mixin&lt;/em&gt;, the class implements the interface and includes, &lt;strong&gt;not inherits&lt;/strong&gt;, all the &lt;em&gt;mixin&lt;/em&gt;'s attributes and methods. They become part of the class during compilation. Interestingly enough &lt;em&gt;mixins&lt;/em&gt; don't need to implement an interface. The advantage of implementing an interface is obvious so that the class may be passed to methods requiring that interface.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.ayende.com/Blog"&gt;Ayende's&lt;/a&gt; idea about using code injection to implement &lt;tt&gt;static&lt;/tt&gt; mixins motivated me. How would you define a mixin? You could try this, but Boo wouldn't like it. It's not an interface:&lt;/p&gt;&lt;pre&gt;

interface IMath:
 def Add(a as int, b as int):
  return a + b
&lt;/pre&gt;&lt;p&gt;Here is what I've come up with. To create a mixin define the interface as usual, then define mixin attributes and methods in a separate file and inject them during compilation.&lt;/p&gt;&lt;pre&gt;
# IMath.boo - interface to our math mixin
interface IMath:
 def Add(a as int, b as int) as int:
  pass

# IMath.mxn - implementation of the interface with a bonus
[property(Result)]
_result as int

def Add(a as int, b as int) as int:
 _result = a + b
 return _result
&lt;/pre&gt;&lt;p&gt;The first file is self explanatory. The second is interesting in that it implements the &lt;tt&gt;IMath.Add()&lt;/tt&gt; method and a &lt;tt&gt;Result&lt;/tt&gt; accessor. To mix this in with a class use the &lt;tt&gt;InjectCode&lt;/tt&gt; attribute using &lt;tt&gt;MixinCodeBuilder&lt;/tt&gt;.&lt;/p&gt;&lt;pre&gt;

# english.boo
import MGutz.CodeInjector from "MGutz.CodeInjector"

[InjectCode(MixinCodeBuilder, "IMath.mxn")]
class English(IMath):
 def construtor():
  pass

 def Noun() as string:
  return "Boo"
&lt;/pre&gt;&lt;p&gt;When booc compiles &lt;tt&gt;english.boo&lt;/tt&gt;, &lt;tt&gt;MixinCodeBuilder&lt;/tt&gt; comes alive and parses the code in &lt;tt&gt;"IMath.mxn"&lt;/tt&gt; and adds &lt;tt&gt;Add()&lt;/tt&gt; and &lt;tt&gt;Result&lt;/tt&gt; to &lt;tt&gt;English&lt;/tt&gt;. Here is the test:&lt;/p&gt;&lt;pre&gt;

mixin = English() as IMath
print mixin.Add(2, 3)

o = English()
o.Add(6,6)
print o.Result
&lt;/pre&gt;&lt;p&gt;As you can see, &lt;tt&gt;English&lt;/tt&gt; implements IMath as well as has a &lt;tt&gt;Result&lt;/tt&gt; accessor. I like this approach as you have the option to implement the mixin methods by simply not injecting the mixin code. The downside is declaring the interface and injecting the code are two steps.&lt;/p&gt;&lt;p&gt;This wasn't that difficult to implement. To be honest the CodeInjector is probably less than 400 lines of code and that may be an exaggerated number. Boo just does so much. OK, I haven't really tested other scenarios but so far, so good!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113063308872862838?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113063308872862838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113063308872862838' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113063308872862838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113063308872862838'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/10/boo-is-mixin-it-up.html' title='Boo is mixin it up'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113056776099810568</id><published>2005-10-28T23:19:00.000-07:00</published><updated>2005-10-29T11:48:09.873-07:00</updated><title type='text'>Must-have free Win utilities</title><content type='html'>&lt;p&gt;&lt;a href="http://www.autohotkey.com"&gt;AutoHotKey&lt;/a&gt;: Program your keyboard to do anything. Use it to map or remap your entire keyboard. For example, I have Win+V start Visual Studio, Win+space to start a command window, PrtScrn to start Snagit. More powerful than any commercial keyboard utility, guaranteed.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.sysinternals.com/Utilities/Autoruns.html"&gt;Autoruns&lt;/a&gt;: These guys probably know more about Windows internals than Microsoft. This utility shows you *every* exe, dll that runs at startup with the option to prevent them.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.vector.co.jp/download/file/win95/util/ff170615.html"&gt;CDX&lt;/a&gt;: A change directory utility for the command line. When you type &lt;tt&gt;cdx&lt;/tt&gt; an Explorer dialog pops up to select your folder. Use the arrows key to select your folder. Right arrow to expand. Left arrow to contract. Hit enter. You don't need no stinkin' mouse and the focus remains on the command line. It's faster than Tab. The link is direct to the download since I don't read Japanese. Winrar will open the LZH file.&lt;/p&gt;&lt;p&gt;&lt;a href="http://sourceforge.net/projects/keynote"&gt;KeyNote&lt;/a&gt;: Jot your ideas down in a tree-type (outline) metaphor. Use it to store code snippets, URLs or whatever.&lt;/p&gt;&lt;p&gt;&lt;a href="http://regex.osherove.com"&gt;Regulator&lt;/a&gt;: A regular expression builder, tester focused on .NET regular expressions. This was featured on &lt;a href="http://msdn.microsoft.com/msdnmag/issues/04/07/MustHaveTools/default.aspx"&gt;"Ten must have tools..."&lt;/a&gt;. I don't mention the others in that article, you probably use or know of them.&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/alex_papadimoulis/archive/2004/05/25/141400.aspx"&gt;Smart Paster&lt;/a&gt;: Grabs text from the clipboard and pastes it into Visual Studio as a StringBuilder, string, comment, etc. Saves you from having to escape newline, tabs, quotes, etc.&lt;/p&gt;&lt;p&gt;I think a generic taskbar applet that has the functionality of Smart Paster would be neat. This way it could be used in any editor, IDE. Hmmm ... maybe my first GUI-based Boo app. Of course it would have to be extensible so you could do things like convert to HTML.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113056776099810568?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113056776099810568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113056776099810568' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113056776099810568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113056776099810568'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/10/must-have-free-win-utilities.html' title='Must-have free Win utilities'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113055554301204752</id><published>2005-10-28T19:50:00.000-07:00</published><updated>2005-10-29T00:42:37.236-07:00</updated><title type='text'>Visual Studio 2005 Gotcha</title><content type='html'>&lt;p&gt;I guess I'm old school in that I always partition my drives into an operating system drive (C:) and an applications/data drive (D:). My small form factor PC allows for a single drive. When I partitioned the drive, I figured 6 gigs would be enough for the Windows operating system.&lt;/p&gt;&lt;p&gt;Apparently not! Microsoft and other companies tend to install parts of its application on the C: drive even if you tell it to install in D:\program files. The .NET Framework for example will always install itself in the Windows directory. I finally finished downloading Visual Studio 2005 and tried to install it. Bam!&lt;/p&gt;&lt;blockquote&gt;You cannot change the installation location for these products. These products have a dependency on a file already installed in another location, which prevents these products from being installed in a custom directory.

The products you are trying to install are dependent on the following programs:

    * Microsoft .NET Framework 2.0 SDK - ENU 
&lt;/blockquote&gt;&lt;p&gt;What? I installed the .NET 2.0 SDK on my &lt;em&gt;D:&lt;/em&gt; drive earlier in the day. Further reading tells me I should first uninstall then reinstall the Framework to the drive where I want to install Visual Studio. Where do you think it is dummy?! VS needs 2.6 GB of space and my C: drive has 3.0 GB of free space. That doesn't leave Windows enough room to download and apply upgrades, etc. Been there, done that. Aaargh. I have an old version of Partition Magic, I hope it works on XP SP2. Otherwise, I'll have to run to the nearest software store to buy partitioning software. I bet this eats up one day. Visual Studio 2005 better be worth it!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113055554301204752?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113055554301204752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113055554301204752' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113055554301204752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113055554301204752'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/10/visual-studio-2005-gotcha.html' title='Visual Studio 2005 Gotcha'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113040003697867613</id><published>2005-10-27T00:51:00.000-07:00</published><updated>2005-10-28T20:48:02.226-07:00</updated><title type='text'>Boo as a template compiler</title><content type='html'>&lt;p&gt;Lazy Style Code Fu master (ahem) me presents Boo the template compiler. &lt;/p&gt;&lt;p&gt;If you read &lt;a href="http://codedojo.blogspot.com/2005/10/custom-preprocessor-idea-for-boo.html"&gt;"custom preprocessor idea for Boo"&lt;/a&gt; then now you'll see the start of one of the projects I had in mind. Thanks to the Boo newsgroup I discovered Boo has compiler attributes that have the behaviour I want. I started working on it yesterday and code generation works.&lt;/p&gt;&lt;p&gt;Say you want to generate classes for tables in your databases. First retrieve the database metadata. I represent the metadata returned in a Hash named &lt;tt&gt;model&lt;/tt&gt;. &lt;tt&gt;model&lt;/tt&gt; contains the tables for the database as well as the name and columns for each table.&lt;/p&gt;&lt;pre&gt;
# controller.boo
import test from "test"

model = {
    "tables" : [
        {   "name": "user",
            "columns": ["user_id", "username", "password"]
        },
        {   "name": "item",
            "columns": ["item_id", "name", "description"]
        }
    ]
}

f = View(model)
print f.RunTemplate()
&lt;/pre&gt;&lt;p&gt;Don't let the Hash scare you. If you plan to do any AJAX, get used to the JSON format. I much prefer it over XML. You would probably build stongly typed classes for the metadata. JSON is just a quick way to represent objects. Back on topic, staying within the MVC pattern, create a view for &lt;tt&gt;model&lt;/tt&gt;.&lt;/p&gt;&lt;pre&gt;
# view.boo
import MGutz.CodeInjector from "MGutz.CodeInjector"

[InjectCode(TemplateCodeBuilder, "view.tpl")]
class View:
    [property(Model)]
    _model as Hash

    def constructor(model as Hash):
        _model = model
&lt;/pre&gt;&lt;p&gt;&lt;tt&gt;View&lt;/tt&gt; doesn't do much but accept a model. The magic happens in the compiler. &lt;tt&gt;InjectCode&lt;/tt&gt; is a special attribute instructing the Boo compiler, "invoke me when you compile this class." When the atribute is invoked, it instantiates &lt;tt&gt;TemplateCodeBuilder&lt;/tt&gt; to process the contents of the &lt;tt&gt;view.tpl&lt;/tt&gt; file. &lt;tt&gt;TemplateCodeBuilder&lt;/tt&gt; converts the file into Boo code and it becomes the body for a &lt;tt&gt;RunTemplate()&lt;/tt&gt; method. &lt;tt&gt;InjectCode&lt;/tt&gt; then injects &lt;tt&gt;RunTemplate()&lt;/tt&gt; into the class &lt;tt&gt;View&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;Look at the view's template using the model.&lt;/p&gt;&lt;pre&gt;
# view.tpl - template for the view
&amp;lt;% for table as Hash in Model['tables']: %&amp;gt;
class &amp;lt;%= table['name'] %&amp;gt;:

    &amp;lt;% for column in table['columns']: %&amp;gt;
    [property(&amp;lt;%=column%&amp;gt;)]
    _&amp;lt;%=column%&amp;gt; as string

    &amp;lt;% end %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;&lt;p&gt;It's ASP(.NET) syntax. Notice how &lt;tt&gt;Model&lt;/tt&gt; is accessible here. You could access the instance variable &lt;tt&gt;_model&lt;/tt&gt; just as well. Remember this template is injected as a function into &lt;tt&gt;View&lt;/tt&gt;, it has access to private methods, private fields, ... like any member of the &lt;tt&gt;View&lt;/tt&gt;. Also note the &lt;tt&gt;end&lt;/tt&gt; keyword. This is an alternate Boo syntax when using it in markup scripts. &lt;tt&gt;end&lt;/tt&gt; is a required keyword in your templates.&lt;/p&gt;&lt;p&gt;Compile this baby. &lt;tt&gt;view.boo&lt;/tt&gt; + &lt;tt&gt;view.tpl&lt;/tt&gt; merges into a single class into &lt;tt&gt;test.dll&lt;/tt&gt;.&lt;/p&gt;&lt;pre&gt;
&amp;gt; booc -t:library -out:test.dll view.boo
&lt;/pre&gt;&lt;p&gt;Run the controller.&lt;/p&gt;&lt;pre&gt;
&amp;gt; booi controller.boo

class user:
        [property(user_id)]
        _user_id as string

        [property(username)]
        _username as string

        [property(password)]
        _password as string

class item:
        [property(item_id)]
        _item_id as string

        [property(name)]
        _name as string

        [property(description)]
        _description as string

&lt;/pre&gt;&lt;p&gt;Voila! Instant classes for your database. Remember, the template is compiled. Think of a template as a function in an abstract format. You now have a compiled class that executes your template without any run-time parsing, merging, etc. This is ideal not only for code generation but also for views in a web framework.&lt;/p&gt;&lt;p&gt;I'll finish up by saying Boo is such a wonderful language. It's what VB.NET  should have been. Even down at the compiler pipeline level you just sense how solid Boo is.&lt;/p&gt; &lt;p&gt;If you're wondering what the generated code for &lt;tt&gt;View.RunTemplate()&lt;/tt&gt; looks like.&lt;/p&gt;&lt;pre&gt;
def RunTemplate() as string:
        out = System.Text.StringBuilder()
         for table as Hash in Model['tables']:
out.Append("class ")
out.Append( table['name'] )
out.Append(":\r\n")

 for column in table['columns']:
out.Append("\t")
out.Append("[property(")
out.Append(column)
out.Append(")]\r\n")
out.Append("\t")
out.Append("_")
out.Append(column)
out.Append(" as string\r\n\r\n")

 end
 end
out.Append("\r\n\r\n")

        return out.ToString()
end
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113040003697867613?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113040003697867613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113040003697867613' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113040003697867613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113040003697867613'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/10/boo-as-template-compiler.html' title='Boo as a template compiler'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18278253.post-113026082912568931</id><published>2005-10-25T10:18:00.000-07:00</published><updated>2005-10-25T13:49:36.623-07:00</updated><title type='text'>custom preprocessor idea for Boo</title><content type='html'>&lt;p&gt;I remember reading the possibility of adding language directives to &lt;a href="http://boo.codehaus.org"&gt;Boo&lt;/a&gt;.  If they do, then I propose a feature which I have not seen in other compilers---the ability to  invoke a custom preprocessor.&lt;/p&gt;&lt;p&gt;Imagine the possibilities. You could include an ORM XML mapping file, preprocess it to automatically generate accessors within the class. You could include a XAML file and bind events. There are so many more neat things you could do.&lt;/p&gt;&lt;p&gt;Here's an example applied to my yet to be released MVC framework. A view is comprised of a template and code-behind much like ASP.NET. What's the advantage? There is no run-time compilation, no parsing, no reflection, etc. The view and template merge and compile into a single type. I realize ASP.NET gets compiled as well but it's a separate framework, this becomes a first class feature of the language. &lt;/p&gt;&lt;pre&gt;
# MyTemplate.html - maintainted by a designer. Rows between &amp;lt;%=* %&amp;gt; and &amp;lt;%*%&amp;gt;
# are omitted when rendering. It's an aid for designers.
&amp;lt;html&amp;gt;
    &amp;lt;table&amp;gt;
        &amp;lt;%=* Cycle([EvenRow, OddRow], Model['Items']) %&amp;gt;
        &amp;lt;tr class='even'&amp;gt;&amp;lt;td&amp;gt;even row omitted when compiled&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
        &amp;lt;tr class='odd'&amp;gt;&amp;lt;td&amp;gt;odd row omitted when compiled&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt; 
        &amp;lt;tr class='even'&amp;gt;&amp;lt;td&amp;gt;even row omitted when compiled&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
        &amp;lt;%*%&amp;gt;
    &amp;lt;/table&amp;gt;
&amp;lt;/html&amp;gt;

# MyView.boo - code-upfront (code-behind)
class MyView(ViewBase):
    def OddRow(s as string) as string:
        return "&amp;lt;tr class='odd'&amp;gt;&amp;lt;td&amp;gt;${s}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;\n"

    def EvenRow(s as string) as string:
        return "&amp;lt;tr class='even'&amp;gt;&amp;lt;td&amp;gt;${s}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;\n"
        
    #include "MyTemplate.html", TemplateProcessor
&lt;/pre&gt;&lt;p&gt;The line above means preprocess &lt;tt&gt;MyTemplate.html&lt;/tt&gt; using a custom preprocessor &lt;tt&gt;TemplateProcessor&lt;/tt&gt;. Here's the pseudocode:&lt;/p&gt;&lt;pre&gt;
#converts an html template into a boo snippet
class TemplateProcessor(Boo.IPreProcessor):
    def Process(filename as string) as string:
        // read the contents of the file
        // convert html template into code
        // return BuildOutput() code
&lt;/pre&gt;&lt;p&gt;After preprocessing the class contains the generated &lt;tt&gt;BuildOutput()&lt;/tt&gt;&lt;/p&gt;&lt;pre&gt;
# class with generated function
class MyView(ViewBase):
    ... 
    
    // called by ViewBase.Render()
    def BuildOutput() as string:
        out = StringBuilder()
        out.Append("html\n\t&amp;lt;table&amp;gt;\n")
        Indent("\t\t")
        out.Append(Cycle([OddRow, EvenRow], Model['Items'])
        Dedent()
        out.Append("\t&amp;lt;/table&amp;gt;&amp;lt;/html&amp;gt;")
        return out.ToString()
&lt;/pre&gt;&lt;p&gt;The view simply cycles between &lt;tt&gt;OddRow()&lt;/tt&gt; and &lt;tt&gt;EvenRow()&lt;/tt&gt; applying values from &lt;tt&gt;Items&lt;/tt&gt; resulting in an HTML table with alternating row styles.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18278253-113026082912568931?l=codedojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codedojo.blogspot.com/feeds/113026082912568931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18278253&amp;postID=113026082912568931' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113026082912568931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18278253/posts/default/113026082912568931'/><link rel='alternate' type='text/html' href='http://codedojo.blogspot.com/2005/10/custom-preprocessor-idea-for-boo.html' title='custom preprocessor idea for Boo'/><author><name>Mario Gutierrez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
