<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Jakob Andersen</title>
    <description />
    <link>http://intellect.dk/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.Net Syndication Generator 1.0.0.0 (http://dotnetblogengine.net/)</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://intellect.dk/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd?format=rss</blogChannel:blink>
    <dc:creator>Jakob Andersen</dc:creator>
    <dc:title>Jakob Andersen</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/intellectdk" /><feedburner:info uri="intellectdk" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Miracle Open World 2010 - Development track</title>
      <description>&lt;p&gt;
&lt;img style="float: left" src="http://intellect.dk/image.axd?picture=mowbanner135x200x.gif" alt="" /&gt;The company that I work for &lt;a href="http://miracleas.dk/"&gt;Miracle&lt;/a&gt; has a reputation. A reputation for throwing some exiting and very social konferences. Usually the themes have been either Oracle or SQL Server but this year this has changed. The Oracle and SQL Server folks will have to get a long and furthermore we have added a Microsoft development track and a workshop track, so&amp;nbsp;I bet the discussions over the drinks and dinner will be a little less onesided this year. 
&lt;/p&gt;
&lt;p&gt;
The venue is Lalandia/Legoland in Billund and everything is included in the conferencefee: food, drinks, accomedation and off course access to the galladinner and the legendary beachparty held in the venues waterpark (Don&amp;#39;t miss this, its a blast). 
&lt;/p&gt;
&lt;p&gt;
I have been involved in the planning of the development and workshop tracks and i thought it would fit me to write a little bit about the speakers i have invited to talk at the event and why i look forward to a couple of exiting days in April: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.rasmuskl.dk/"&gt;Rasmus Kromann-Larsen&lt;/a&gt; will demonstrate his mad ninjaskills with ReSharper and im pretty sure that when you leave the talk you will have a few extra tricks up your sleeve to improve your productivity when writing and navigating around code. Rasmus second session will discuss some practical experiences from an ASP.NET MVC implementation project, so if you still miss to see how ASP.NET MVC will work in the wild compared to webforms you should definitely go. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://madskristensen.net/"&gt;Mads Kristensen&lt;/a&gt; from Vodafone is a really weird guy compared to most of the .NET developers i know. Mads look on performance has a strong focus on things like renderingtime in the browser and how much data we send to the clients. This aspect of performanceoptimization is often missed and if you have struggled to reduce the waittime in your serverside code I bet you that Mads will show you some tricks that can improve the response time from the users point of view. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.improve.dk/"&gt;Mark S. Rasmussen&lt;/a&gt; from iPaper knows a lot about working with existing PDF documents. Mark has had the technical responsibility from building the iPaper solution from scratch. He will show you how to work efficiently with large PDF documents and what information you can extract from them. Furthermore Mark secretly wan&amp;#39;t to be sysadm so he loves monitoring performance of his systems, thats why his second talk will talk about end-to-end tracing of your applications across infrastructure points and including the database. 
&lt;/p&gt;
&lt;p&gt;
Have you ever heard of WinDBG? If you haven&amp;#39;t you missed out on of the most valuable tools for debugging the really tough problems like deadlocks or memoryleaks in both managed and unmanaged code. &lt;a href="http://kodehoved.dk/"&gt;Brian Rasmussen&lt;/a&gt; who works at SimCorp is an expert on WinDBG and a really good speaker. Brian will present a session about WinDBG and if you really want to get messy he will host a workshop where you can explore the wonders of WinDBG in more depth. On a personal note i can add that WinDBG has been one of the favorites in my toolbox since i first learned to use it. 
&lt;/p&gt;
&lt;p&gt;
Adding to the above speakers we have some very skilled Miracle employees that will present on the development track: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.lybecker.com/blog/"&gt;Anders Lybecker&lt;/a&gt; is going to talk about the full-text search framework Lucene.NET. Anders has reallife experience with Lucene.NET from several projects with large amounts of data and demands for fast searches with continious updating of the searchindex. 
&lt;/p&gt;
&lt;p&gt;
Simon Clemen Pedersen is going to take you on a guided tour in the jungle of javascript frameworks and show how you can keep a clean and maintainable codebase when working with the Dojo javascriptlibrary. 
&lt;/p&gt;
&lt;p&gt;
I am going to give a few talks aswell. First of i will introduce how we can measure an applications throughput to create a performancebasline for the application. This baseline can be used to find the knee in performancecourves aswell as monitoring performance across new releases. My second talk will discuss different caching strategies in applications. Lastly im going to give a talk on some of the more exotic features in nHiberante like Sharding, Validators and Caching. 
&lt;/p&gt;
&lt;p&gt;
Even though you might see yourselv as a developer type a lot of interesting topics is on the SQL Server and Oracle tracks aswell. Topics like: how to work with huge databases, SQL Server Integration Services,, how to write effective SQL, XML in the database. And of course a lot of topics on performance and scalability. One of my &amp;quot;odd&amp;quot; but must-see sessions is Toon Koppelaars &amp;quot;Applied Mathematics for database professionals&amp;quot;, i have heard the talk once before and its about how to use basic mathematics to formally describe difficult SQL Queries, and hence use mathematical rules to simplify or optimize the queries, that session is highly recommended! 
&lt;/p&gt;
&lt;p&gt;
We are still working on completing the speakerlineup, so if you have any suggestions please let me know, and i will see if we can make it happen. 
&lt;/p&gt;
&lt;p&gt;
Registration and more information is available on: &lt;a href="http://mow2010.dk/"&gt;mow2010.dk&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
If you have any questions about the programme or the konference in general feel free to contact me on &lt;a href="mailto:jta@miracleas.dk"&gt;jta@miracleas.dk&lt;/a&gt; 
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=zc31Cq1rKiU:e-j3QseU7og:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=zc31Cq1rKiU:e-j3QseU7og:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=zc31Cq1rKiU:e-j3QseU7og:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=zc31Cq1rKiU:e-j3QseU7og:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=zc31Cq1rKiU:e-j3QseU7og:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=zc31Cq1rKiU:e-j3QseU7og:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=zc31Cq1rKiU:e-j3QseU7og:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=zc31Cq1rKiU:e-j3QseU7og:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/zc31Cq1rKiU" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/zc31Cq1rKiU/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Miracle-Open-World-2010---Development-track.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=83855850-22f4-4891-bc1a-56bad8ca9fed</guid>
      <pubDate>Fri, 12 Feb 2010 01:31:00 +0200</pubDate>
      <category>Conference</category>
      <category>Miracle</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=83855850-22f4-4891-bc1a-56bad8ca9fed</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=83855850-22f4-4891-bc1a-56bad8ca9fed</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Miracle-Open-World-2010---Development-track.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=83855850-22f4-4891-bc1a-56bad8ca9fed</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=83855850-22f4-4891-bc1a-56bad8ca9fed</feedburner:origLink></item>
    <item>
      <title>Writing a calculator in C# using Irony</title>
      <description>&lt;p&gt;
My &lt;a href="http://improve.dk/"&gt;friend Mark&lt;/a&gt; wrote &lt;a href="http://improve.dk/blog/2009/09/30/writing-a-calculator-in-csharp-using-sablecc"&gt;a post last week about implementing a calculating compiler using SableCC&lt;/a&gt;. I have worked with &lt;a href="http://sablecc.org/"&gt;SableCC&lt;/a&gt; on a project where we needed to parse C# code and I have to admit I don&amp;#39;t recall SableCC as a friendly framework, and reading Mark&amp;#39;s post proves my memory right.
&lt;/p&gt;
&lt;p&gt;
First of Mark&amp;#39;s grammar is very specific to SableCC, a lot af tricks is made to make SableCC accept the grammar and furthermore the grammar is complicated further by handling operator precedence. If we disregard performance considerations and focus on an easily understandable and maintainable compiler structure our grammar for our parser generator ideally would look very much like the Extended Backus Naur Format (EBNF) of the language.
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
number = digit+ | digit+ &amp;#39;.&amp;#39; digit+
lparen = &amp;#39;(&amp;#39;
rparen = &amp;#39;)&amp;#39;
binop = &amp;#39;+&amp;#39; | &amp;#39;-&amp;#39; | &amp;#39;/&amp;#39; | &amp;#39;*&amp;#39; | &amp;#39;%&amp;#39;
funcname = letter+
expression := lparen expression rparen | expression operator expression | funcname lparen expression rparen | number
&lt;/pre&gt;
&lt;p&gt;
&lt;a href="http://irony.codeplex.com/"&gt;Irony&lt;/a&gt; is like SableCC a scanner/parser generator but it is implemented as an internal DSL in C# for specifying grammars on a format very close to EBNF. The code is specified in the constructor body of a class inherting from Irony&amp;#39;s Grammar class. The EBNF described above (slightly modified for readability) looks like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
public class SimpleCalcGrammar : Irony.Parsing.Grammar{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public SimpleCalcGrammar(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var number = TerminalFactory.CreateCSharpNumber(&amp;quot;number&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var identifier = TerminalFactory.CreateCSharpIdentifier(&amp;quot;identifier&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var expression = new NonTerminal(&amp;quot;expression&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var binexpr = new NonTerminal(&amp;quot;binexpr&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var parexpr = new NonTerminal(&amp;quot;parexpr&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var fncall = new NonTerminal(&amp;quot;fncall&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var binop = new NonTerminal(&amp;quot;binop&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expression.Rule =  parexpr | binexpr | number | fncall;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parexpr.Rule = &amp;quot;(&amp;quot; + expression + &amp;quot;)&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;binexpr.Rule = expression + binop + expression;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;binop.Rule = Symbol(&amp;quot;+&amp;quot;) | &amp;quot;-&amp;quot; | &amp;quot;/&amp;quot; | &amp;quot;*&amp;quot; | &amp;quot;%&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fncall.Rule = identifier + &amp;quot;(&amp;quot; + expression + &amp;quot;)&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.Root = expression;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
&lt;/pre&gt;
&lt;p&gt;
The first few lines are initialization of our Terminals and Productions, this is pretty trivial however a few things is worth noting. Irony is a very rich framework that provides a lot of prebaked functionality, one of these is the TerminalFactory for creating typically used terminals, in our case we use C#&amp;#39;s format for numbers and identifiers, that means we out of the bag get support in our language for suffix on numbers for specifying types etc.
&lt;/p&gt;
&lt;p&gt;
The interresting part is after initialization, here we set up rules for the productions. Irony relies heavily on operator overloading so using our productions and the operators from EBNF we can describe the language pretty straight forward. Lastly we specify what productions is the root of our program, that is the production that contains the entry point for the whole language.
&lt;/p&gt;
&lt;p&gt;
Next up we need to handle operator precedence, fortunately Irony knows that this is a common challenge when developing languages and hence it supports registering our operators and their precedence using the following code:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
RegisterOperators(1, &amp;quot;+&amp;quot;, &amp;quot;-&amp;quot;);
RegisterOperators(2, &amp;quot;*&amp;quot;, &amp;quot;/&amp;quot;, &amp;quot;%&amp;quot;);
&lt;/pre&gt;
&lt;p&gt;
Having specified this we have a working parser that can be used like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
SimpleCalcGrammar g = new SimpleCalcGrammar();
Parser p = new Parser(g);
ParseTree t = p.Parse(&amp;quot;25-37+2*(1.22+cos(5))*sin(5)*2+5%2*3*sqrt(5+2)&amp;quot;);
&lt;/pre&gt;
&lt;p&gt;
This gives us a parse tree that is pretty rough in the edges and hard to work with, what we want instead is a pretty Abstract Syntax Tree that contains exactly the information we need. On our NonTerminal instances we can specify which nodes they should be transformed into, fortunately Irony contains some of the basic nodes that are needed in many languages for instance the binary expression node, so we can specify the built-in BinExprNode on our binexpr NonTerminal like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
var binexpr = new NonTerminal(&amp;quot;binexpr&amp;quot;, typeof(BinExprNode));
&lt;/pre&gt;
&lt;p&gt;
For us to parse the language we need one aditional node in our AST, that is the FunctionCall node (the observant reader might have noticed i have choosen to implement an openended grammar that allows for extending with new built-in functions without modifying the grammar). Irony has a AST node for function calls built-in but for the sake of the example i will show a custom implementation here:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
public class FunctionCallNode : AstNode{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public string Name;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public AstNode Argument;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override void Init (Irony.Parsing.ParsingContext context, Irony.Parsing.ParseTreeNode treeNode)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.Init (context, treeNode);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Name = treeNode.ChildNodes[0].FindTokenAndGetText(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Argument = AddChild(&amp;quot;Arg&amp;quot;, treeNode.ChildNodes[1]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AsString = Name; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
//Adding the node to our function call node
var fncall = new NonTerminal(&amp;quot;fncall&amp;quot;, typeof(FunctionCallNode));
&lt;/pre&gt;
&lt;p&gt;
So implementing our own AST nodes is pretty simple, and Irony has a rich infrastructure for getting text of tokens and adding childnodes as you can see in the sample. Because our parse tree contains a lot of &amp;quot;garbage&amp;quot; that we don&amp;#39;t want transferred to our AST, so we need to inform Irony to import these, this is done by marking nonterminals as transient like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
MarkTransient(parexpr, expression);
&lt;/pre&gt;
&lt;p&gt;
And at last we need to set a flag so that the parser generates the Ast using the following line of code:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
LanguageFlags = LanguageFlags.CreateAst;
&lt;/pre&gt;
&lt;p&gt;
The next step is to actually work with the AST for sementic analysis, codegeneration or as in our case execution of the calculation. Mark did this using a visitor and Irony&amp;#39;s AST supports visitors aswell, so we can make the &amp;quot;PrintVisitor&amp;quot; mark used for debugging like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
public class PrintVisitor : IAstVisitor{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int indentation = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void BeginVisit (AstNode node)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (int i = 0;i&amp;lt;indentation ;i++ ) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.Write(&amp;quot;\t&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(node.ToString());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;indentation++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void EndVisit (AstNode node)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;indentation--;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/pre&gt;
&lt;p&gt;
Using a visitor looks like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
SimpleCalcGrammar g = new SimpleCalcGrammar();
Parser p = new Parser(g);
ParseTree t = p.Parse(&amp;quot;25-37+2*(1.22+cos(5))*sin(5)*2+5%2*3*sqrt(5+2)&amp;quot;);
var astnode = (AstNode)t.Root.AstNode
astnode.AcceptVisitor(new PrintVisitor());
&lt;/pre&gt;
&lt;p&gt;
And the result of this operation is:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
+(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: +(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: -(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:25
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:37
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: *(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: *(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: *(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: +(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:1.22
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: cos
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:5
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: sin
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:5
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: *(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: *(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: %(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:5
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:3
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: sqrt
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg: +(operator)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:5
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arg:2
&lt;/pre&gt;
&lt;p&gt;
However, there is no need for us to create a printvisitor, Irony comes with an UI that allows us to work with our grammar and can parse samples and show us AST, parsertrace with parserstatec and much more, this is very useful to see what the grammar actually does under the covers (shift/reduce). But basically we can go ahead and implement pretty much the same visitor as Mark have used for SableCC, but let&amp;#39;s do something different. Irony has support for a basic LanguageRuntime, and actually for a basic interpreter aswell. So if we tell our AST-nodes how they should evaluate themselves we get all the infrastructure given to us by Irony!
&lt;/p&gt;
&lt;p&gt;
So lets override the Evaluate method on our FunctionCallNode so it can be used in Irony&amp;#39;s interpreter infrastructure:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
public class FunctionCallNode : AstNode{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//....
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override void Evaluate (Irony.Interpreter.EvaluationContext context, Irony.Ast.AstMode mode)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Argument.Evaluate(context, AstMode.Read); //Evaluate the argument the result is saved in context.Data
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double input = Convert.ToDouble(context.Data[0]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double result;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(Name == &amp;quot;sqrt&amp;quot;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = Math.Sqrt(input);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else if(Name == &amp;quot;cos&amp;quot;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = Math.Cos(input);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else if(Name == &amp;quot;sin&amp;quot;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = Math.Sin(input);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw new NotSupportedException(&amp;quot;Method &amp;quot; + Name + &amp;quot; not supported&amp;quot;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;context.Data.Replace(1, result); //Replace the argument value on the stack with the result of the function call
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
&lt;/pre&gt;
&lt;p&gt;
Yes, in real life our methods would be in a method table and not hardcoded here, this is just to demonstrate the functionality of the interpreter in irony. To use the Interpreter we write code like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
var interpreter = new Irony.Interpreter.ScriptInterpreter(new LanguageData(new SimpleCalcGrammar()));
interpreter.Evaluate(&amp;quot;25-37+2*(1.22+cos(5))*sin(5)*2+5%2*3*sqrt(5+2)&amp;quot;);
Console.WriteLine(interpreter.EvaluationContext.LastResult);
&lt;/pre&gt;
&lt;p&gt;
Voila, done with the code that corresponds to Mark&amp;#39;s sample and the result of running the above is: -9.83033874894108 and the built-in Irony interpreter handle almost everything for us leaving me with only 57 lines of pure C# code:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
public class FunctionCallNode : AstNode{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public string Name;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public AstNode Argument;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override void Init (Irony.Parsing.ParsingContext context, Irony.Parsing.ParseTreeNode treeNode)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.Init (context, treeNode);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Name = treeNode.ChildNodes[0].FindTokenAndGetText();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Argument = AddChild(&amp;quot;Arg&amp;quot;, treeNode.ChildNodes[1]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AsString = Name;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override void Evaluate (Irony.Interpreter.EvaluationContext context, Irony.Ast.AstMode mode)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Argument.Evaluate(context, AstMode.Read);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double input = Convert.ToDouble(context.Data[0]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double result;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(Name == &amp;quot;sqrt&amp;quot;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = Math.Sqrt(input);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else if(Name == &amp;quot;cos&amp;quot;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = Math.Cos(input);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else if(Name == &amp;quot;sin&amp;quot;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = Math.Sin(input);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw new NotSupportedException(&amp;quot;Method &amp;quot; + Name + &amp;quot; not supported&amp;quot;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;context.Data.Replace(1, result);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
public class SimpleCalcGrammar : Irony.Parsing.Grammar{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public SimpleCalcGrammar(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var number = TerminalFactory.CreateCSharpNumber(&amp;quot;number&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var identifier = TerminalFactory.CreateCSharpIdentifier(&amp;quot;identifier&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var expression = new NonTerminal(&amp;quot;expression&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var binexpr = new NonTerminal(&amp;quot;binexpr&amp;quot;, typeof(BinExprNode));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var parexpr = new NonTerminal(&amp;quot;parexpr&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var fncall = new NonTerminal(&amp;quot;fncall&amp;quot;, typeof(FunctionCallNode));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var binop = new NonTerminal(&amp;quot;binop&amp;quot;, &amp;quot;operator&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expression.Rule =  parexpr | binexpr | number | fncall;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parexpr.Rule = &amp;quot;(&amp;quot; + expression + &amp;quot;)&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;binexpr.Rule = expression + binop + expression;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;binop.Rule = Symbol(&amp;quot;+&amp;quot;) | &amp;quot;-&amp;quot; | &amp;quot;/&amp;quot; | &amp;quot;*&amp;quot; | &amp;quot;%&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fncall.Rule = identifier + &amp;quot;(&amp;quot; + expression + &amp;quot;)&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RegisterPunctuation(&amp;quot;(&amp;quot;,&amp;quot;)&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RegisterOperators(1, &amp;quot;+&amp;quot;, &amp;quot;-&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RegisterOperators(2, &amp;quot;*&amp;quot;, &amp;quot;/&amp;quot;, &amp;quot;%&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MarkTransient(parexpr, expression);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.Root = expression;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.LanguageFlags = LanguageFlags.CreateAst;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tvSTLCxx3MI:-EBZyvCCcNQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tvSTLCxx3MI:-EBZyvCCcNQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tvSTLCxx3MI:-EBZyvCCcNQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tvSTLCxx3MI:-EBZyvCCcNQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=tvSTLCxx3MI:-EBZyvCCcNQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tvSTLCxx3MI:-EBZyvCCcNQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=tvSTLCxx3MI:-EBZyvCCcNQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tvSTLCxx3MI:-EBZyvCCcNQ:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/tvSTLCxx3MI" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/tvSTLCxx3MI/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Writing-a-calculator-in-C-using-Irony.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=731bda36-f73f-44ee-885b-3331cfbcbd4d</guid>
      <pubDate>Wed, 07 Oct 2009 14:42:00 +0200</pubDate>
      <category>.NET</category>
      <category>C#</category>
      <category>English</category>
      <category>Irony</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=731bda36-f73f-44ee-885b-3331cfbcbd4d</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=731bda36-f73f-44ee-885b-3331cfbcbd4d</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Writing-a-calculator-in-C-using-Irony.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=731bda36-f73f-44ee-885b-3331cfbcbd4d</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=731bda36-f73f-44ee-885b-3331cfbcbd4d</feedburner:origLink></item>
    <item>
      <title>Why I love extension points - nHibernate Driver</title>
      <description>&lt;p&gt;
I have used nHibernate on linux for some time now without any major problems. The issues I have encountered have infact not been with Mono but with the MySql dialect in nHibernate. One of these where a nasty issue where nHibernate closed the connection to the database before retrieving the newly generated identifier which (in this case) unfortunately is bound to the current database connection. However I made a fix for this in the MySqlDialect and now it should be committet to nHibernate repository be included in next release.
&lt;/p&gt;
&lt;p&gt;
Today I was starting a new project writing some tests and wanted to use SQLlite in memory for some pseudo integration testing, Mono has built-in support for SQLite in the Mono.Data.Sqlite assembly however nHibernate isn&amp;#39;t aware of this and hence espects that you have the SQLite.NET assembly and the SQLite binaries present either in your bin directory or in the GAC. To avoid having to deploy these on my linux box which already has a .NET implementation of SQLite&amp;#39;s IDbConnection and IDbCommand i turned to one of the extensions points in nHibernate and made my own Driver as follows:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
public class MonoSqliteDriver : NHibernate.Driver.ReflectionBasedDriver
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public MonoSqliteDriver() : 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base(&amp;quot;Mono.Data.Sqlite&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;Mono.Data.Sqlite.SqliteConnection&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;Mono.Data.Sqlite.SqliteCommand&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override bool UseNamedPrefixInParameter {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override bool UseNamedPrefixInSql {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override string NamedPrefix {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return &amp;quot;@&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override bool SupportsMultipleOpenReaders {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
&lt;/pre&gt;
&lt;p&gt;
Initially I wanted to derive from the existing SQLiteDriver in nHibernate, but unfortunately the important part is the call to the base constructor on ReflectionBasedDriver, and as SqlLiteDriver hides the constructor of this i can&amp;#39;t hook in and provide the three parameters that I need to change. The things changed is the three strings in the constructor call, &amp;quot;Mono.Data.Sqlite&amp;quot; is the assembly where the IDbConnection and IDbCommand implementations are located, and the other two are the names of the implementation. The overridden properties are taken from the existing SqliteDriver in the nHibernate source.
&lt;/p&gt;
&lt;p&gt;
Finally to use our driver we just specify it in our nHibernate configuration
&lt;/p&gt;
&lt;pre class="xml" name="code"&gt;
&amp;lt;add key=&amp;quot;connection.driver_class&amp;quot; value=&amp;quot;Name.Space.MonoSqliteDriver, AssemblyName&amp;quot; /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
Conclusion: Extension points are indeed nice, and the stack I use including nHibernate has a lot of them which makes my life a lot easier
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J1WC816viNM:MPXbk0UEETQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J1WC816viNM:MPXbk0UEETQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J1WC816viNM:MPXbk0UEETQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J1WC816viNM:MPXbk0UEETQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=J1WC816viNM:MPXbk0UEETQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J1WC816viNM:MPXbk0UEETQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=J1WC816viNM:MPXbk0UEETQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J1WC816viNM:MPXbk0UEETQ:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/J1WC816viNM" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/J1WC816viNM/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Why-I-love-frameworks-with-lots-of-extension-points.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=d5c4aee5-2308-43c1-9b38-8bbfc3d557fb</guid>
      <pubDate>Wed, 26 Aug 2009 01:01:00 +0200</pubDate>
      <category>.NET</category>
      <category>C#</category>
      <category>Mono</category>
      <category>nHibernate</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=d5c4aee5-2308-43c1-9b38-8bbfc3d557fb</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=d5c4aee5-2308-43c1-9b38-8bbfc3d557fb</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Why-I-love-frameworks-with-lots-of-extension-points.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=d5c4aee5-2308-43c1-9b38-8bbfc3d557fb</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=d5c4aee5-2308-43c1-9b38-8bbfc3d557fb</feedburner:origLink></item>
    <item>
      <title>OpenRasta talk in Denmark</title>
      <description>A few months ago i was in London attending the &lt;a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-exchange"&gt;Progressive .NET&lt;/a&gt; conference and listened to &lt;a href="http://serialseb.blogspot.com/"&gt;Sebastian Lambla&lt;/a&gt; present his &lt;a href="http://openrasta.com"&gt;OpenRasta framework&lt;/a&gt;. Not only is Sebastian a great speaker his framework looks really promising. Even though you might not think you are in need of an restful MVC framework there are some interresting opinions build into the framework. So i can only recommend that you attend the&lt;a href="http://www.anug.dk/post/2009/08/17/OpenRasta-MVC-with-strong-opinions.aspx"&gt; Aarhus .NET User Group meeting&lt;/a&gt; where Sebastian kindly have agreed to present OpenRasta.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tSdQMK8Qw6k:eSjTJdXZ63I:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tSdQMK8Qw6k:eSjTJdXZ63I:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tSdQMK8Qw6k:eSjTJdXZ63I:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tSdQMK8Qw6k:eSjTJdXZ63I:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=tSdQMK8Qw6k:eSjTJdXZ63I:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tSdQMK8Qw6k:eSjTJdXZ63I:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=tSdQMK8Qw6k:eSjTJdXZ63I:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=tSdQMK8Qw6k:eSjTJdXZ63I:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/tSdQMK8Qw6k" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/tSdQMK8Qw6k/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/OpenRasta-talk-in-Denmark.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=2a006fb0-7b9b-4f49-8f20-6465531b5198</guid>
      <pubDate>Mon, 17 Aug 2009 12:14:00 +0200</pubDate>
      <category>Events</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=2a006fb0-7b9b-4f49-8f20-6465531b5198</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=2a006fb0-7b9b-4f49-8f20-6465531b5198</trackback:ping>
      <wfw:comment>http://intellect.dk/post/OpenRasta-talk-in-Denmark.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=2a006fb0-7b9b-4f49-8f20-6465531b5198</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=2a006fb0-7b9b-4f49-8f20-6465531b5198</feedburner:origLink></item>
    <item>
      <title>Implementing Generate Constructor refactoring in MonoDevelop</title>
      <description>&lt;p&gt;
In this post I will cover how to implement a simple generate constructor refactoring in the Open Source .NET IDE MonoDevelop.  I have recently started using MonoDevelop because I run linux on my laptop for various reasons, most important one of them is that I miss the power of the commandline and all the small tools that is pretty standard on linux. But the IDE lacks some features and this weekend I decided to dig into the codebase to try to add a few refactorings, this post will cover the first one.
&lt;/p&gt;
&lt;p&gt;
MonoDevelop is build using .NET and the user interface is based on Gtk. So its a little different structure than WinForms but MonoDevelop comes with a nice designer and the application itself contains a lot of UI code you can be inspired by. Im not much of an UI guy myself so I started in the code. The refactorings in MonoDevelop are all registred in the class MonoDevelop.Ide.Commands.CurrentRefactoryOperationsHandler, in this class a methods exists that generate the commands to be available in the Context menu on the currently chosen type, variable, parameter etc:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
CommandInfo BuildRefactoryMenuForItem (ProjectDom ctx, ICompilationUnit pinfo, IType eclass, IDomVisitable item, bool includeModifyCommands)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Implementation
}
&lt;/pre&gt;
&lt;p&gt;
The &lt;strong&gt;CommandInfo&lt;/strong&gt; is in its default implementation a single Command but has a specialisation &lt;strong&gt;CommandInfoSet&lt;/strong&gt; that allows us to return multiple commands, so in the implementation of this method we can add several refactorings that is applicable based on the location in code. The parameters passed to the above method is for helping us determine which commands to add and to supply these commands with the information about the code they need to actually perform the refactoring. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;ProjectDom&lt;/strong&gt; contains information about the current project that is a collection of files containing classes etc. refactorings that modify the public interface of the current class needs this to ensure references to the public interface can be updated. A good example of this is the Rename refactoring, if you rename a public property on a class you need to update all references to this with the new name.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;ICompilationUnit&lt;/strong&gt; contains information of the current CompilationUnit which is typically corresponding to the current source file, it contains information about using directives, attributes and types present.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;IType&lt;/strong&gt; references the class if a interface is clicked so, is currently only there to support the &amp;quot;Implement interface&amp;quot; refactoring which needs to know about both the current class and the interface clicked.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;IDomVisitable&lt;/strong&gt; is the type that the user is currently on, that is a class, interface, member, enum etc. this is going to be the most important in our implementation because we only work on a single type and not modifying anything outside this.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;includeModifyCommands&lt;/strong&gt; is a flag that decides whether the CommandInfo&amp;#39;s should include refactorings modifying the type. This is useful for not popping up refactorings modifying types we have no control over.
&lt;/p&gt;
&lt;p&gt;
So we need to add logic to the BuildFactoryMenuForItem method to add our refactoring under certain circumstances, more specific when a we have a class marked in the UI, the code for this looks as this:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
//Make sure the current item is a type
if(item is IType){ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IType type = (IType)item;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Make sure that the type is a class and it belongs to a project
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(type.ClassType == ClassType.Class &amp;amp;&amp;amp; type.SourceProject != null){ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Add the command to our CommandInfoSet to be returned (ciset) with its name and a RefactoryOperation delegate
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ciset.CommandInfos.Add(&amp;quot;Generate Constructor&amp;quot;, new RefactoryOperation(refactorer.GenerateConstructor));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
&lt;/pre&gt;
&lt;p&gt;
As you can see existing code in the method already have initialized the &lt;strong&gt;ciset&lt;/strong&gt; and the &lt;strong&gt;refactorer&lt;/strong&gt; and for simplicity i left out localization of the name of the refactoring. The &lt;strong&gt;ciset&lt;/strong&gt; initialization is pretty straight forward, however the &lt;strong&gt;refactorer&lt;/strong&gt; is interesting: this class contains methods for actually doing the refactoring (or in most cases code that launches the UI that does the refactoring). The refactorer is initialized with pretty much the same parameters as passed to the BuildFactoryMenuForItem:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
Refactorer refactorer = new Refactorer (ctx, pinfo, eclass, realItem, null);
&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Only difference is that we pass &lt;strong&gt;realItem&lt;/strong&gt; instead of our raw &lt;strong&gt;IDomVisitable&lt;/strong&gt; this is because there is some handling of instantiated types and compound types, but that&amp;#39;s out of the scope of this post.
&lt;/p&gt;
&lt;p&gt;
The GenerateConstructor method on our refactorer class is pretty simple as all it does is fire up our UI Dialog (which we still need to make):
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
public void GenerateConstructor(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GenerateConstructorDialog dialog = new GenerateConstructorDialog(item);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dialog.Show();
}
&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Because we are only manipulating a single class and its contents, and we are only adding new code not modifying existing the only thing we need is the &lt;strong&gt;IDomVisitable&lt;/strong&gt; called &lt;strong&gt;item&lt;/strong&gt; which is the class we need to modify. With just a blank dialog put into this, we have now hooked into the structure of MonoDevelop and added our refactoring to the context menu:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div style="text-align: center"&gt;
&lt;img src="http://intellect.dk/image.axd?picture=RefactoringMenu.png" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Lets skip the UI part a little while and go to the actual codegeneration. We can utilize the built in code generation features of MonoDevelop namely the class &lt;strong&gt;MonoDevelop.Project.CodeGeneration.CodeRefactorer&lt;/strong&gt; which has a method &lt;strong&gt;AddMember(IType cls, System.CodeDom.CodeTypeMember)&lt;/strong&gt; we already have the IType that we are currently working on passed to our dialog so we need to construct a &lt;strong&gt;CodeTypeMember&lt;/strong&gt; using the &lt;strong&gt;System.CodeDom&lt;/strong&gt; classes. 
&lt;/p&gt;
&lt;p&gt;
Ideally we would like to decouple this generation of the &lt;strong&gt;CodeTypeMember&lt;/strong&gt; completely from our UI code, however to keep in line with the style that the rest of MonoDevelop is written we will keep this coupling. However this is definitively a refactoring candidate that should be done throughout MonoDevelop to decouple the actual refactoringcommands from the UI.
&lt;/p&gt;
&lt;p&gt;
I don&amp;#39;t wan&amp;#39;t to bore you with a lot of UI code so here as a screenshot instead:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://intellect.dk/image.axd?picture=GenerateConstructorDialog.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
We have some basic functionality a five column flat TreeView with the following columns:
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;a checkbox that decides if the field should be in the constructor&lt;/li&gt;
	&lt;li&gt;the name of the field&lt;/li&gt;
	&lt;li&gt;the name of the type&lt;/li&gt;
	&lt;li&gt;the name of the generated parameter that is editable&lt;/li&gt;
	&lt;li&gt;a checkbox that decides if an assignment should be generated in the body of the constructor&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Furthermore we can sort the order of the parameters and this will be reflected in the generated code. First thing we need to add the fields from the selected type to the TreeView, this is done with the following code:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
//Contains our column and the reference to the actual IField
ListStore store = new ListStore(typeof(bool), typeof(string), typeof(string), typeof(string), typeof(bool),typeof(IField)); 
//Add the store to the model of our TreeView
treeview.Model = store;
//Check if the IDomVisitable is actually a class
if(item is IType){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach(IField field in ((IType)item).Fields){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Generate a sensible parameter name from the name of the field
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;string paramName = GenerateParamName(field.Name);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Add the field to our storage with some default values
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;store.AppendValues(true, field.Name, field.DeclaringType.Name, paramName, true, field);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The code is pretty straight forward, however as mentioned it&amp;#39;s not exactly like Windows Forms, but notice the actual MVC approach with us binding the model to the TreeView, actually a very nice way to work with things compared to DataBinding in Windows Forms if you ask me. There is some UI code for generating the columns in the TreeView, handling edits and sorting that i won&amp;#39;t post because it is pretty trivial and because this post isn&amp;#39;t about programming Gtk. Lastly we should ideally retrieve fields from base types as well that could be initialized and provide them in the list if they are assignable from this type (i.e. protected or public). Lets move on to what happens when we click the OK button and we generate the &lt;strong&gt;CodeTypeMember&lt;/strong&gt; i mentioned before:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
//Get the CodeRefactorer from the IDE
CodeRefactorer refactorer = IdeApp.Workspace.GetCodeRefactorer (IdeApp.ProjectOperations.CurrentSelectedSolution);
//Get an iterator for our liststore that backs the TreeView
TreeIter iter;
if(!store.GetIterFirst(out iter))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return;
//Generate our CodeConstructor from System.CodeDom namespace
var constr = new CodeConstructor();
//Loop over the fields in the store
do {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Extract information from store
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bool selected = (bool) store.GetValue (iter, colCheckedIndex);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IField field = (IField) store.GetValue(iter, colFieldIndex);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bool genassignment = (bool) store.GetValue(iter, colGenAssignmentIndex);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;string paramName = (string) store.GetValue(iter, colParamNameIndex);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Check if the user asked us to include this field as parameter
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(selected){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Generate the parameter and add it to the constructor
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(field.ReturnType.DecoratedFullName, paramName);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constr.Parameters.Add(param);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Check if the user asked us to generate a default assignment
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(genassignment){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Generate assignment on the form &amp;quot;this.fieldname = paramname&amp;quot; and add to constructor body
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CodeAssignStatement expr = new CodeAssignStatement(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new CodeVariableReferenceExpression(paramName)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constr.Statements.Add(expr);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Generate a TODO comment if param not handled and add to and add to constructor body
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CodeCommentStatement comm = new CodeCommentStatement(string.Format(&amp;quot;TODO: Handle parameter {0}&amp;quot;, paramName));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constr.Statements.Add(comm);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
} while (store.IterNext (ref iter));
//Lastly use the refactorer to add the generated constructor to the type
refactorer.AddMember((IType)item, constr);
&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
This might seem a bit confusing but actually its not that complicated, a fluent interface around &lt;strong&gt;System.CodeDom&lt;/strong&gt; would certainly make it easier to read. That&amp;#39;s basically the code for this refactoring.
&lt;/p&gt;
&lt;p&gt;
There was one single change I had to make to the &lt;strong&gt;CodeRefactorer&lt;/strong&gt; implementation in MonoDevelop because the constructor gets its name from the class, and when using &lt;strong&gt;AddMember&lt;/strong&gt; the class name was hard-coded to be temp when generating the text from the &lt;strong&gt;CodeTypeMember&lt;/strong&gt;, so instead I changed it to take the name from the supplier IType. On a more general note I was very surprised about MonoDevelop, I had expected code of a higher quality and certainly more tests than it has, but that may be the cost of pushing out a pretty feauture complete IDE within a short timeframe.
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=dDrae_1jQGQ:4cMOg8prtn4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=dDrae_1jQGQ:4cMOg8prtn4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=dDrae_1jQGQ:4cMOg8prtn4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=dDrae_1jQGQ:4cMOg8prtn4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=dDrae_1jQGQ:4cMOg8prtn4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=dDrae_1jQGQ:4cMOg8prtn4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=dDrae_1jQGQ:4cMOg8prtn4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=dDrae_1jQGQ:4cMOg8prtn4:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/dDrae_1jQGQ" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/dDrae_1jQGQ/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Implementing-Generate-Constructor-refactoring-in-MonoDevelop.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=7760ea5b-b3bf-48a0-b7d5-1059a559156d</guid>
      <pubDate>Tue, 28 Apr 2009 22:28:00 +0200</pubDate>
      <category>Mono</category>
      <category>MonoDevelop</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=7760ea5b-b3bf-48a0-b7d5-1059a559156d</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=7760ea5b-b3bf-48a0-b7d5-1059a559156d</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Implementing-Generate-Constructor-refactoring-in-MonoDevelop.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=7760ea5b-b3bf-48a0-b7d5-1059a559156d</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=7760ea5b-b3bf-48a0-b7d5-1059a559156d</feedburner:origLink></item>
    <item>
      <title>Gendarme Rule based CIL validation - Building your own rules</title>
      <description>&lt;p&gt;&lt;a href="http://www.mono-project.com/Gendarme"&gt;Gendarme&lt;/a&gt; is a tool for analyzing and finding problems in code in &lt;a href="http://www.ecma-international.org/publications/standards/Ecma-335.htm"&gt;ECMA CIL format&lt;/a&gt; (For MS only people out there that is the specification of which &lt;a href="http://msdn.microsoft.com/en-us/library/c5tkafs1.aspx"&gt;MSIL&lt;/a&gt; is an implementation). The tool itself comes with a boatload of useful rules to find problems in your code, one example of a rule is ProvideCorrectArgumentsToFormattingMethodsRule this makes sure that every time you call String.Format the number of arguments specified will correspond to the number specified in the format string: &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;string.Format(&amp;quot;{0} would like a cup of {1}&amp;quot;, &amp;quot;Jakob&amp;quot;); &lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;So the rule would find the above and report it to us when we run our assemblies through Gendarme with that rule chosen.&amp;#160; There are a wide array of rules available already but if you feel something is missing either because it is not yet included in Gendarme or perhaps its a rule very specific to a project your working on, you can easily add rules to the framework, that was what it was build for!&lt;/p&gt;

&lt;p&gt;Gendarme uses &lt;a href="http://www.mono-project.com/Cecil"&gt;Mono.Cecil&lt;/a&gt; to inspect the CLI Image, basically the same as &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.aspx"&gt;Reflection&lt;/a&gt; in Microsoft’s BCL does, and furthermore supports modifying it as &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.aspx"&gt;Reflection.Emit&lt;/a&gt; does. However Reflection and Reflection.Emit only expose a subset of the features of CLI Images whereas Mono.Cecil gives you full access. So the code we are using to inspect and check for our rules is similar in functionality to Reflection code as you know it from MS, however there are some differences.&lt;/p&gt;

&lt;p&gt;The first thing to do is to write some tests for the rule we want to create. My idea for a rule is that I would like to avoid getters calling themselves which we all know often is a bad idea. So a simple test class to be used for testing this rule for both success and failures could look like this:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public class Item
{
    public bool UsesItSelf
    {
        get { return UsesItSelf; }
    }

    public bool DoesNotUseItSelf
    {
        get { return false; }
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Gendarme comes with a bunch of functionality for helping out testing rules in the form of some generic baseclass for our NUnit tests. In our case we want to create a MethodRule (as getters and setters are separate methods in CIL code). So we inherit from MethodRuleTestFixture&amp;lt;T&amp;gt; and get simple functionality to do Assertions on Success or Failure on applying our rule to specific methods. Confused, don't be the test cases are as simple as this:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[TestFixture]
public class UsePropertyGetterInPropertyGetterTest : MethodRuleTestFixture&amp;lt;UsePropertyGetterInPropertyGetterRule&amp;gt;
{
    [Test]
    public void TestUsesItSelf()
    {
        AssertRuleFailure&amp;lt;Item&amp;gt;(&amp;quot;get_UsesItSelf&amp;quot;);
    }

    [Test]
    public void TestDoesNotUseItSelf()
    {
        AssertRuleSuccess&amp;lt;Item&amp;gt;(&amp;quot;get_DoesNotUseItSelf&amp;quot;);
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The generic AssertRuleFailure and AssertRuleSucces takes a generic parameter that tells the type under test and the parameter tells which method should be called. When C# is compiled to CIL code the getters and setters are expanded to two methods with get_ and set_ prefixes in case you didn't know. &lt;/p&gt;

&lt;p&gt;Next up we need to implement the actual rule as currently our test cases can't even compile. Our rule needs to be a MethodRule so we need to implement the IMethodRule interface from Gendarme, fortunately a base class called Rule exists which does a lot of the hard work for us already so we inherit from that as well. 
  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[Problem(&amp;quot;This property getter calls itself&amp;quot;)]
[Solution(&amp;quot;It is probably not supposed to, if it is consider refactoring to make it more readable&amp;quot;)]
public class UsePropertyGetterInPropertyGetterRule : Rule, IMethodRule
{
    public RuleResult CheckMethod(MethodDefinition method)
    {
        if (!method.IsGetter)
            return RuleResult.DoesNotApply;

        if (!method.HasBody)
            return RuleResult.Success;
        foreach (Instruction instruction in method.Body.Instructions)
        {
            if (instruction.OpCode == OpCodes.Call)
            {
                if(instruction.Operand.ToString() == method.ToString())
                {
                    Runner.Report(method, Severity.High, Confidence.Total);
                    return RuleResult.Failure;
                }
                
            }
        }
        return RuleResult.Success;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The only method we implement is CheckMethod, this is called when Gendarme finds a Method and our rule is enabled, so we get the MethodDefinition and need to return a RuleResult. So we take these steps: &lt;/p&gt;

&lt;p&gt;1. We check if this is a Getter, if not our rule does not apply &lt;/p&gt;

&lt;p&gt;2. We determine the rule it successful if nobody is available (No body = it doesn't call itself) &lt;/p&gt;

&lt;p&gt;3. We loop through instructions in the method body and find out if a Call OpCode exists, if it does we compare the method being called with the method we are currently analyzing, if they are the same we return a failure and report this to the Gendarme Runner &lt;/p&gt;

&lt;p&gt;That’s it, we have all green lights from our simple test case. We can now use it in the Gendarme tool, either command line, GUI or in your favorite build system. In case of command line usage (and UI I guess) you can add you own assembly containing your own rules to the rules.xml file found in the location you installed Gendarme.&lt;/p&gt;

&lt;p&gt;As a last note I would really recommend that you look into the rules bundled with Gendarme, there are a lot of useful ones that could save you a lot of pain if you happen to not have perfect test coverage.&lt;/p&gt;

&lt;p&gt;(Be aware that this is meant as an example only of implementing a rule in Gendarme, the above test suite is slim and the code for the actual rule uses some shortcuts that should be eliminated)&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=R7qkRF_73gM:dP0qqxi1PcU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=R7qkRF_73gM:dP0qqxi1PcU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=R7qkRF_73gM:dP0qqxi1PcU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=R7qkRF_73gM:dP0qqxi1PcU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=R7qkRF_73gM:dP0qqxi1PcU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=R7qkRF_73gM:dP0qqxi1PcU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=R7qkRF_73gM:dP0qqxi1PcU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=R7qkRF_73gM:dP0qqxi1PcU:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/R7qkRF_73gM" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/R7qkRF_73gM/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Gendarme-Rule-based-CIL-validation-ndash3b-Building-your-own-rules.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=00242809-cd5e-4809-84db-db50e696b875</guid>
      <pubDate>Wed, 08 Apr 2009 04:04:44 +0200</pubDate>
      <category>C#</category>
      <category>.NET</category>
      <category>Tools</category>
      <category>Mono</category>
      <category>Gendarme</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=00242809-cd5e-4809-84db-db50e696b875</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=00242809-cd5e-4809-84db-db50e696b875</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Gendarme-Rule-based-CIL-validation-ndash3b-Building-your-own-rules.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=00242809-cd5e-4809-84db-db50e696b875</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=00242809-cd5e-4809-84db-db50e696b875</feedburner:origLink></item>
    <item>
      <title>Generic pipeline for business objects using Castle Windsor</title>
      <description>&lt;p&gt;Currently I'm working with a system handling different operations when receiving business documents in object form. Its quite obvious that the code for handling this has evolved to have a lot more responsibilities than it was intended to.&lt;/p&gt;  &lt;p&gt;So already having an Inversion of Control container in our stack I thought we could make the operations in the pipeline configurable using the container. To achieve this we need to specify an interface for the tasks in the pipeline, in our case its pretty simple:&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;public interface IPipelineTask&amp;lt;T&amp;gt;
{
    T Perform(T instance);
}&lt;/pre&gt;

&lt;p&gt;Secondly we need to define the pipeline itself, again using a generic interface:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public interface IPipeline&amp;lt;T&amp;gt;
{
    T Execute(T instance);
}&lt;/pre&gt;

&lt;p&gt;So basically what I want to accomplish is the ability to ask my Inversion of control container for a pipeline for a certain type and be able to call the Execute method on the instance and have all associated tasks performed on the instance I pass to the method. So the code for handling an incoming object of type Invoice would look like this:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;Invoice incomingInvoice = ....;
ProjectContainer container = new ProjectContainer();
IPipeline&amp;lt;Invoice&amp;gt; pipeline = container.Resolve&amp;lt;IPipeline&amp;lt;Invoice&amp;gt;&amp;gt;();
Invoice processedInvoice = pipeline.Execute(incomingInvoice);
container.Release(pipeline);&lt;/pre&gt;

&lt;p&gt;So lets look at the implementation of the generic pipeline that handles executing of each task:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public class Pipeline&amp;lt;T&amp;gt; : IPipeline&amp;lt;T&amp;gt;
{
    private IPipelineTask&amp;lt;T&amp;gt;[] tasks;
    public Pipeline(IPipelineTask&amp;lt;T&amp;gt;[] pipelinetasks)
    {
        tasks = pipelinetasks;
    }

    public T Execute(T instance)
    {
        T processedInstance = instance;
        foreach (var task in tasks)
        {
            processedInstance = task.Perform(processedInstance);
        }
        return processedInstance;
    }
}&lt;/pre&gt;

&lt;p&gt;Note the constructor takes an array of IPipelineTasks&amp;lt;T&amp;gt; this is here our Inversion of Control container comes to play and does this for us using constructor dependency injection. &lt;/p&gt;

&lt;p&gt;Each task needs to implement the IPipelineTask&amp;lt;T&amp;gt; with its specific business object type:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public class InvoiceNotifier : IPipelineTask&amp;lt;Invoice&amp;gt;
{
    private IUserNotifier usernotifier;
    public InvoiceNotifier(IUserNotifier notifier)
    {
        usernotifier = notifier;
    }

    public Invoice Perform(Invoice instance)
    {
        usernotifier.Notify(Notification.IncomingInvoice,
                            &amp;quot;The invoice with identifier &amp;quot; + instance.ID + &amp;quot; changed state to &amp;quot; + instance.State);
        return instance;
    }
}&lt;/pre&gt;

&lt;p&gt;Normally when working with arrays in Castle Windsor we have to specify each service to be part of the array in the configuration, however in our case we want all registered implementations of the specific interface to be passed to the pipeline. To do this we can add a custom sub dependency resolver to castle, in fact we can use &lt;a href="http://hammett.castleproject.org/?p=257"&gt;the ArraySubDependencyResolver&lt;/a&gt; already written by &lt;a href="http://hammett.castleproject.org/"&gt;Castle projects founder (and soon to be Microsoftee) Hammett&lt;/a&gt;. With this in place we can make the following configuration and our mission is accomplished and all tasks registered in the configuration will be injected when we request the generic Pipeline of this type. &lt;/p&gt;

&lt;pre class="xml" name="code"&gt;&amp;lt;components&amp;gt;
   &amp;lt;!--Register the generic pipeline--&amp;gt; 
  &amp;lt;component
    id=&amp;quot;bussiness.document.pipeline&amp;quot;
    service=&amp;quot;Services.IPipeline`1, Services&amp;quot;
    type=&amp;quot;Services.Pipeline`1, Services&amp;quot;
    lifetype=&amp;quot;Thread&amp;quot;
    /&amp;gt;
   &amp;lt;!--Register our pipeline tasks--&amp;gt;
  &amp;lt;component
    id=&amp;quot;invoice.notification&amp;quot;
    service=&amp;quot;Services.IPipelineTask`1[[Domain.Invoice, Domain]], Services&amp;quot;
    type=&amp;quot;Services.InvoiceNotifier, Services&amp;quot;
    lifetype=&amp;quot;Thread&amp;quot;
    /&amp;gt;
  &amp;lt;component
    id=&amp;quot;invoice.reciever&amp;quot;
    service=&amp;quot;Services.IPipelineTask`1[[Domain.Invoice, Domain]], Services&amp;quot;
    type=&amp;quot;Services.InvoiceReciever, Services&amp;quot;
    lifetype=&amp;quot;Thread&amp;quot;
    /&amp;gt;
  
   &amp;lt;!--Registration of services and repositories which our pipeline tasks uses--&amp;gt;
   ....
&amp;lt;/components&amp;gt;&lt;/pre&gt;

&lt;p&gt;Using this infrastructure custom tasks can be specified easily in the configuration even from other namespaces and assemblies. And the pipeline doesn't need to worry about the dependencies of each Pipeline task, the container handles this&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=IfpQmcNkPb4:EPlRBeSUZQo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=IfpQmcNkPb4:EPlRBeSUZQo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=IfpQmcNkPb4:EPlRBeSUZQo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=IfpQmcNkPb4:EPlRBeSUZQo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=IfpQmcNkPb4:EPlRBeSUZQo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=IfpQmcNkPb4:EPlRBeSUZQo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=IfpQmcNkPb4:EPlRBeSUZQo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=IfpQmcNkPb4:EPlRBeSUZQo:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/IfpQmcNkPb4" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/IfpQmcNkPb4/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Generic-pipeline-for-business-objects-using-Castle-Windsor.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=5b0e50cb-02c1-42bd-9279-36d949227cac</guid>
      <pubDate>Sun, 20 Jul 2008 22:01:09 +0200</pubDate>
      <category>.NET</category>
      <category>Castle</category>
      <category>Inversion of Control</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=5b0e50cb-02c1-42bd-9279-36d949227cac</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=5b0e50cb-02c1-42bd-9279-36d949227cac</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Generic-pipeline-for-business-objects-using-Castle-Windsor.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=5b0e50cb-02c1-42bd-9279-36d949227cac</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=5b0e50cb-02c1-42bd-9279-36d949227cac</feedburner:origLink></item>
    <item>
      <title>Generating DTO's from your fully populated domain classes</title>
      <description>&lt;p&gt;When working with object relational mapping(or even handrolled DAL's) you most often work on fully populated objects. When working in an environment utilizing Data Transfer Object either for transport over the wire or screen bound&amp;#160; DTO's you have to slice or merge your fully populated objects. With LINQ for nHibernate, LINQ for SQL the solution for this is pretty obvious you populate the object using its constructor or object initialisers&amp;#160; in a LINQ query either directly on your data source or on one or more already populated instances.&lt;/p&gt;  &lt;p&gt;A quick example using LINQ for nHibernate could be:&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;var result = from p in db.Products select new ProductDTO {p.ID, p.Name} ;&lt;/pre&gt;

&lt;p&gt;(Of course we need to make instances not anonymous types because we need to pass them out of the current scope)&lt;/p&gt;

&lt;p&gt;If we are stuck using traditional querying in nHibernate we can accomplish the same using HQL:&lt;/p&gt;

&lt;pre class="sql" name="code"&gt;select new ProductDTO(p.ID, p.Name) from Product p&lt;/pre&gt;

&lt;p&gt;When using this HQL query its important to remember to import your DTO class in the mapping or else you will end up with an error like: &lt;/p&gt;

&lt;pre name="code"&gt;NHibernate.QueryException : class not found: ProductDTO&lt;/pre&gt;

&lt;p&gt;To import it just add &amp;lt;import class=&amp;quot;Name.Space.ProductDTO, Assembly&amp;quot;&amp;gt; right after your hibernate-mapping element. Of course the generating of the DTO's can get much more complex than the samples i have shown. They could span multiple business object requiring complex queries but the concept remains the same.&lt;/p&gt;

&lt;p&gt;Okay, so these options are valid only for folks using an LINQ empowered ORM's or frameworks with equivalent functionality to the nHibernate sample above. One thing we could do is to create the DTO's from the fully populated objects. Of course this could be a dangerous decision if you don't already have the objects in the current context and the DTO's require a very little subset of the data, so that's definitely worth noting. That beeing said we could do this in a number of ways all which i can thing of writing myself involves plumbing code. So a couple of days ago I stumbled upon a project called &lt;a href="http://code.google.com/p/otis-lib/"&gt;otis&lt;/a&gt; a object transformer or Object-to-Object mapper if you prefer that term. &lt;/p&gt;

&lt;p&gt;The concept is pretty simple, we can define how one object map to another so if we take our very simple case we can specify a mapping on this form:&lt;/p&gt;

&lt;pre class="xml" name="code"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;
&amp;lt;otis-mapping xmlns=&amp;quot;urn:otis-mapping-1.0&amp;quot;&amp;gt;
  &amp;lt;class name=&amp;quot;Name.Space.ProductDTO, Assembly&amp;quot; source=&amp;quot;Name.Space.Product, Assembly&amp;quot; &amp;gt;
    &amp;lt;member name=&amp;quot;ID&amp;quot; /&amp;gt;
    &amp;lt;member name=&amp;quot;Name&amp;quot; /&amp;gt;
  &amp;lt;/class&amp;gt;
&amp;lt;/otis-mapping&amp;gt;&lt;/pre&gt;

&lt;p&gt;In the above case we have the same names on properties in both classes so its pretty simple, but the possibilities in the mapping is many. You can use expression to combine multiple values to one, projections, exchanging certain values etc. I will certainly have to look into the source code of otis and have a look of its capabilities as the documentation is a bit sparse.&lt;/p&gt;

&lt;p&gt;To utilize the above mapping we configure the framework and use a generic class to get Assembler classes that can convert our types, its pretty simple:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;Product product = ...; //Our fully populated product instance
Otis.Configuration conf = new Otis.Configuration();
//Looks for embedded ressource with *.otis.xml ending
conf.AddAssemblyResources(Assembly.GetExecutingAssembly(), &amp;quot;otis.xml&amp;quot;); 
//Declare our assembler
var asm = conf.GetAssembler&amp;lt;ProductDTO, Product&amp;gt;();
//Use the assembler to get the DTO
ProductDTO dto = asm.AssembleFrom(product);&lt;/pre&gt;

&lt;p&gt;As I said I will definitely dive into the source to explore which features are available and how the transformation is done and what the costs of it is. The main issue I have with the approach is that we could do the same using code and to make it more flexible lambda expressions and have it strongly typed and avoid the verbosity of XML, but lets see how feature rich Otis is before dismissing it.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J_DogcYXcGg:6Ki0Ca0gsFE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J_DogcYXcGg:6Ki0Ca0gsFE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J_DogcYXcGg:6Ki0Ca0gsFE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J_DogcYXcGg:6Ki0Ca0gsFE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=J_DogcYXcGg:6Ki0Ca0gsFE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J_DogcYXcGg:6Ki0Ca0gsFE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=J_DogcYXcGg:6Ki0Ca0gsFE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=J_DogcYXcGg:6Ki0Ca0gsFE:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/J_DogcYXcGg" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/J_DogcYXcGg/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Generating-DTOs-from-your-fully-populated-domain-classes.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=e0c70a3a-f49c-4695-9894-06d23a4dee05</guid>
      <pubDate>Thu, 19 Jun 2008 23:34:11 +0200</pubDate>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=e0c70a3a-f49c-4695-9894-06d23a4dee05</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=e0c70a3a-f49c-4695-9894-06d23a4dee05</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Generating-DTOs-from-your-fully-populated-domain-classes.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=e0c70a3a-f49c-4695-9894-06d23a4dee05</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=e0c70a3a-f49c-4695-9894-06d23a4dee05</feedburner:origLink></item>
    <item>
      <title>Copenhagen .NET User Group - Startup</title>
      <description>&lt;p&gt;A .NET User Group is starting up in Copenhagen for more information check &lt;a href="http://cnug.dk/"&gt;http://cnug.dk/&lt;/a&gt; (in Danish). I Hope to see many of the Danish developers on the 19th of June in Ballerup. Its gonna be a talk about expectations for the User Group and a presentation of some concepts from object relational mapping.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=Pj0TfN2UkJM:nRJRFdL5-Io:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=Pj0TfN2UkJM:nRJRFdL5-Io:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=Pj0TfN2UkJM:nRJRFdL5-Io:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=Pj0TfN2UkJM:nRJRFdL5-Io:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=Pj0TfN2UkJM:nRJRFdL5-Io:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=Pj0TfN2UkJM:nRJRFdL5-Io:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=Pj0TfN2UkJM:nRJRFdL5-Io:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=Pj0TfN2UkJM:nRJRFdL5-Io:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/Pj0TfN2UkJM" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/Pj0TfN2UkJM/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Copenhagen-NET-User-Group---Startup.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=2cf0c963-cde7-4a31-8fe1-243c1f465f34</guid>
      <pubDate>Fri, 13 Jun 2008 13:40:14 +0200</pubDate>
      <category>.NET</category>
      <category>English</category>
      <category>General</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=2cf0c963-cde7-4a31-8fe1-243c1f465f34</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=2cf0c963-cde7-4a31-8fe1-243c1f465f34</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Copenhagen-NET-User-Group---Startup.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=2cf0c963-cde7-4a31-8fe1-243c1f465f34</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=2cf0c963-cde7-4a31-8fe1-243c1f465f34</feedburner:origLink></item>
    <item>
      <title>Why the database should handle paging</title>
      <description>&lt;p&gt;Notice that the scrollbar isn't at the bottom. That's a lot of data to fetch if you only show a single page of them&lt;/p&gt;  &lt;p&gt;&lt;a href="http://intellect.dk/images/Whythedatabaseshouldhandlepaging_18A9/manypages_3.jpg"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="348" alt="manypages" src="http://intellect.dk/images/Whythedatabaseshouldhandlepaging_18A9/manypages_thumb.jpg" width="640" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;(click for larger image)&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=f1IzJP2Yz0A:_xZyqmQhg7c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=f1IzJP2Yz0A:_xZyqmQhg7c:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=f1IzJP2Yz0A:_xZyqmQhg7c:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=f1IzJP2Yz0A:_xZyqmQhg7c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=f1IzJP2Yz0A:_xZyqmQhg7c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=f1IzJP2Yz0A:_xZyqmQhg7c:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=f1IzJP2Yz0A:_xZyqmQhg7c:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=f1IzJP2Yz0A:_xZyqmQhg7c:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/f1IzJP2Yz0A" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/f1IzJP2Yz0A/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Why-the-database-should-handle-paging.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=deb42ce4-d15d-41dd-86e4-6060f3afa9d1</guid>
      <pubDate>Fri, 06 Jun 2008 01:45:26 +0200</pubDate>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=deb42ce4-d15d-41dd-86e4-6060f3afa9d1</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=deb42ce4-d15d-41dd-86e4-6060f3afa9d1</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Why-the-database-should-handle-paging.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=deb42ce4-d15d-41dd-86e4-6060f3afa9d1</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=deb42ce4-d15d-41dd-86e4-6060f3afa9d1</feedburner:origLink></item>
    <item>
      <title>Generating passwords</title>
      <description>&lt;p&gt;So if you need to generate passwords easy you don't have to reinvent the wheel, you can use functionality that the Mempership functionality from ASP.NET already has. On the Membership class in System.Web.Security namespace is a static method for generating passwords. You can specify a length and how many non alphanumeric characters it should contain.&lt;/p&gt;  &lt;p&gt;Of course its not exotic in anyway and you can not control the set of characters used (apart from how many should be non alphanumeric) and it does not generate pronounceable passwords. &lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;string password = Membership.GeneratePassword(7, 1);&lt;/pre&gt;

&lt;p&gt;The above code will generate a string with seven random characters. Its worth taking note of the second parameter. It specifies the minimum number of non-alphanumerical characters so the generated password can contain more than one in the above case.&lt;/p&gt;

&lt;p&gt;If you need to generate pronounceable passwords I would recommend you take a look at the C implementation available here: &lt;a title="http://www.multicians.org/thvv/tvvtools.html#gpw" href="http://www.multicians.org/thvv/tvvtools.html#gpw"&gt;http://www.multicians.org/thvv/tvvtools.html#gpw&lt;/a&gt; it covers the theory behind using trigraphs and furthermore shows implementation of how to extract trigraphs from a dictionary and how to use this to generate the actual passwords.&lt;/p&gt;

&lt;p&gt;But to keep it short, if you just need a random set of chars. Use the features already in the framework instead of rolling your own! The lines saved makes fewer lines that could contain that tricky bug you are hunting a few months from now.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=EMrYOICLgHI:0vlt5eGW-5M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=EMrYOICLgHI:0vlt5eGW-5M:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=EMrYOICLgHI:0vlt5eGW-5M:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=EMrYOICLgHI:0vlt5eGW-5M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=EMrYOICLgHI:0vlt5eGW-5M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=EMrYOICLgHI:0vlt5eGW-5M:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=EMrYOICLgHI:0vlt5eGW-5M:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=EMrYOICLgHI:0vlt5eGW-5M:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/EMrYOICLgHI" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/EMrYOICLgHI/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Generating-passwords.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=ccb6dc06-c837-4dbf-b768-22e0d9ee763c</guid>
      <pubDate>Tue, 03 Jun 2008 23:38:32 +0200</pubDate>
      <category>.NET</category>
      <category>C#</category>
      <category>Snippets</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=ccb6dc06-c837-4dbf-b768-22e0d9ee763c</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=ccb6dc06-c837-4dbf-b768-22e0d9ee763c</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Generating-passwords.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=ccb6dc06-c837-4dbf-b768-22e0d9ee763c</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=ccb6dc06-c837-4dbf-b768-22e0d9ee763c</feedburner:origLink></item>
    <item>
      <title>Common nHibernate exceptions and a question</title>
      <description>&lt;p&gt;I often get asked question about nHibernate issues the question discussed last in this post is often brought up. But lets start out with a few simple exceptions that can sometimes take up more of your time than you would like.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;quot;NHibernate.MappingException : Unknown entity class: MyNamespace.With.Persistent.Class&amp;quot;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You are trying to use a class as persistent that nHibernate wouldn't know how to handle. The number one reason for this error is that you have mapping files as embedded resources and that you forgot to actually embed the mapping file.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;quot;NHibernate.MappingException : persistent class ClassName not found&amp;quot; &lt;/strong&gt;&lt;strong&gt;or &amp;quot;&lt;/strong&gt;&lt;strong&gt;NHibernate.MappingException : associated class not found: ClassName&amp;quot;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is usually an error in your mapping, nHibernate can't find the class you reference in your mapping. This is often caused by typos or missing to specify in which assembly or namespace your persistent class is to be found. You can specify a default assembly and namespace in the &amp;lt;hibernate-mapping&amp;gt; element or you can write the name of your classes with the assembly and namespace specified on the form &amp;quot;Namespace.ClassName, Assembly&amp;quot;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;quot;NHibernate.InvalidProxyTypeException : The following types may not be used as proxies&amp;quot;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is a classic, if you want to use nHibernates lazyloading features you need to specify your classes properties as virtual so nHibernate can create proxies for you. If you don't need to use lazyloading on specific type mark these types with lazy=&amp;quot;false&amp;quot; in the class element, and you won't have to mark its properties as virtual.&lt;/p&gt;  &lt;p&gt;So that's a handful of the most common exceptions when starting out with nHibernate. Lets move on to a question I have answered quite a few times. People often want to minimize the number of roundtrip's to the database by joining and retrieving larger resultsets and have nHibernate transform this larger set of results into the correct object graph. Whether this is a good optimization depends heavily on the expected data since it could result in a huge amount of redundant data transferred between database and application. But nonetheless the thing that often tricks people is illustrated by the following test:&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;//Assumme we have 2 invoices with 3 invoicelines each
IList&amp;lt;Invoice&amp;gt; invoices = s.CreateCriteria(typeof (Invoice)).SetFetchMode(&amp;quot;InvoiceLines&amp;quot;, FetchMode.Join).List&amp;lt;Invoice&amp;gt;();
Assert.AreEqual(2, invoices.Count);&lt;/pre&gt;

&lt;p&gt;This test will fail, because you actually get 6 invoice entities back. That's because the resultset contains duplicate invoices (one for each InvoiceLine) and nHibernate transforms these into invoice instances. One way to fix this is to specify that you want distinct root entities back. This is done by specifying a result-transformer like this:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;IList&amp;lt;Invoice&amp;gt; invoices =
                s.CreateCriteria(typeof (Invoice)).
                SetFetchMode(&amp;quot;InvoiceLines&amp;quot;, FetchMode.Join).
                SetResultTransformer(CriteriaUtil.DistinctRootEntity).
                List&amp;lt;Invoice&amp;gt;();&lt;/pre&gt;

&lt;p&gt;So what if your data isn't suitable for joining, you might end up with the large resultset I mentioned earlier? And we don't want to hit the N+1 Select problem by selecting the InvoiceLines for each of the fetched Invoice's. That's were nHibernates batch fetching can be used. We have retrieved all the Invoices we want to use and afterwards we want to select the invoicelines for those. We can specify that our InvoiceLines should be retrieved in batches by specifying a batch-size on the collection in our mapping file.&lt;/p&gt;

&lt;pre class="xml" name="code"&gt;&amp;lt;set name=&amp;quot;InvoiceLines&amp;quot; batch-size=&amp;quot;20&amp;quot;&amp;gt;
	&amp;lt;key column=&amp;quot;InvoiceID&amp;quot; /&amp;gt;
	&amp;lt;one-to-many class=&amp;quot;InvoiceLine&amp;quot; /&amp;gt;
&amp;lt;/set&amp;gt;&lt;/pre&gt;

&lt;p&gt;I just used 20 as an example, this means that nHibernate will fetch the InvoiceLines for 20 Invoices at a time. So this will result in two roundtrip's(in our example case), and this without fetching duplicate data in the resultsets. You could optimize some scenarios like the one above using MultiQuery or MultiCriteria, that is sending multiple queries in one roundtrip, but that's another story.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=vGMy5LZWgLU:5asJel8X1VA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=vGMy5LZWgLU:5asJel8X1VA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=vGMy5LZWgLU:5asJel8X1VA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=vGMy5LZWgLU:5asJel8X1VA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=vGMy5LZWgLU:5asJel8X1VA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=vGMy5LZWgLU:5asJel8X1VA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=vGMy5LZWgLU:5asJel8X1VA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=vGMy5LZWgLU:5asJel8X1VA:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/vGMy5LZWgLU" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/vGMy5LZWgLU/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Common-nHibernate-exceptions-and-a-question.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=3a20585a-d4ba-4d49-a24b-0fcc3e96f5e9</guid>
      <pubDate>Tue, 13 May 2008 16:27:46 +0200</pubDate>
      <category>.NET</category>
      <category>English</category>
      <category>nHibernate</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=3a20585a-d4ba-4d49-a24b-0fcc3e96f5e9</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=3a20585a-d4ba-4d49-a24b-0fcc3e96f5e9</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Common-nHibernate-exceptions-and-a-question.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=3a20585a-d4ba-4d49-a24b-0fcc3e96f5e9</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=3a20585a-d4ba-4d49-a24b-0fcc3e96f5e9</feedburner:origLink></item>
    <item>
      <title>BlogEngine.NET - Urlrewriting</title>
      <description>&lt;p&gt;So the first thing I usually do when reviewing web projects is to find the default entry page that the user would see. When doing this with BlogEngine.NET you find the default.aspx (obviously in most cases). The first thing in the Page_Load of this is the following code:&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;if (Request.RawUrl.ToLowerInvariant().Contains(&amp;quot;/category/&amp;quot;)){...}
else if (Request.RawUrl.ToLowerInvariant().Contains(&amp;quot;/author/&amp;quot;)){...}
else if (Request.RawUrl.ToLowerInvariant().Contains(&amp;quot;?tag=&amp;quot;)){...}
//a couple of else if's more&lt;/pre&gt;

&lt;p&gt;So this makes it clear that the default.aspx page handles all listing of posts whether it is all in a category, all by an author or all having a specific tag. All these listings are requested using different URI's, to handle this an UrlRewrite HttpModule is implemented. If we look at some code in this UrlRewriter we will find:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;if (context.Request.Path.Contains(&amp;quot;/blog.aspx&amp;quot;)){...}
else if (url.Contains(&amp;quot;/POST/&amp;quot;)){...}
else if (url.Contains(&amp;quot;/CATEGORY/&amp;quot;)){...}
else if (url.Contains(&amp;quot;/AUTHOR/&amp;quot;)){...}
//a couple of else if's more&lt;/pre&gt;

&lt;p&gt;So what happens here is we delegate the responsibility for different URL's to be handled on different pages, the responsibilities redirected to the default page is afterwards on the default page once again delegated to different methods handling databinding because presentation is alike. This results in some parsing of the URL's is duplicated in the UrlRewriter and in the default.aspx.cs file. And furthermore the collection of all posts is iterated both in the UrlRewriter and on the pages, that seems silly. Why not let UrlRewriting do what its intended for: to forward information and then keep the processing on simple pages for specific requests to avoid the redundant parsing and iteration?&lt;/p&gt;

&lt;p&gt;I read an &lt;a href="http://www.infoq.com/news/2007/11/BlogEngine"&gt;interview with the BlogEngine.NET founder on InfoQ&lt;/a&gt; a while back, and it seems he has some issues with third party dependencies. I don't see the reason for this, if you can use a third party dependency too do a task it does well and have been doing in many projects already, why roll your own. So allow me to introduce &lt;a href="http://www.urlrewriting.net"&gt;UrlRewritingNet.UrlRewrite&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UrlRewritingNet basically consists of a generic HttpHandler that rewrites based on rules you set up in a configuration section in your web.config file, so instead of having to change code to change rewrites, we change simple regular expressions in our configuration of UrlRewritingNet. So lets see the rules I set up for BlogEngine.NET:&lt;/p&gt;

&lt;pre class="xml" name="code"&gt;&amp;lt;configSections&amp;gt;
	&amp;lt;section name=&amp;quot;urlrewritingnet&amp;quot;
		restartOnExternalChanges=&amp;quot;true&amp;quot;
		requirePermission=&amp;quot;false&amp;quot;
		type=&amp;quot;UrlRewritingNet.Configuration.UrlRewriteSection, UrlRewritingNet.UrlRewriter&amp;quot;
	/&amp;gt;
&amp;lt;/configSections&amp;gt;
&amp;lt;urlrewritingnet xmlns=&amp;quot;http://www.urlrewriting.net/schemas/config/2006/07&amp;quot;&amp;gt;
	&amp;lt;rewrites&amp;gt;
		&amp;lt;add name=&amp;quot;categoryRule&amp;quot; virtualUrl=&amp;quot;^~/category/(.*).aspx&amp;quot; destinationUrl=&amp;quot;~/category.aspx?name=$1&amp;quot;/&amp;gt;
		&amp;lt;add name=&amp;quot;blogRule&amp;quot; virtualUrl=&amp;quot;^~/blog.aspx&amp;quot; destinationUrl=&amp;quot;~/default.aspx?blog=true&amp;quot;/&amp;gt;
		&amp;lt;add name=&amp;quot;authorRule&amp;quot; virtualUrl=&amp;quot;^~/author/(.*).aspx&amp;quot; destinationUrl=&amp;quot;~/author.aspx?name?=$1&amp;quot;/&amp;gt;
		&amp;lt;add name=&amp;quot;postRuleDate&amp;quot; virtualUrl=&amp;quot;^~/post/(\d{4})/([0-1]?\d)/([0-3]?\d)/(.*).aspx&amp;quot;
			destinationUrl=&amp;quot;~/post.aspx?year=$1&amp;amp;amp;month=$2&amp;amp;amp;day=$3&amp;amp;amp;name=$4&amp;quot;/&amp;gt;
		&amp;lt;add name=&amp;quot;postRuleMonth&amp;quot; virtualUrl=&amp;quot;~/post/(\d{4})/([0-1]?\d)/(.*).aspx&amp;quot;
			destinationUrl=&amp;quot;~/post.aspx?year=$1&amp;amp;amp;month=$2&amp;amp;amp;name=$3&amp;quot;/&amp;gt;
		&amp;lt;add name=&amp;quot;postRuleTitle&amp;quot; virtualUrl=&amp;quot;~/post/(.*).aspx&amp;quot; destinationUrl=&amp;quot;~/post.aspx?name=$1&amp;quot;/&amp;gt;
		&amp;lt;add name=&amp;quot;pageRule&amp;quot; virtualUrl=&amp;quot;~/page/(.*).aspx&amp;quot; destinationUrl=&amp;quot;~/page.aspx?name=$1&amp;quot;/&amp;gt;
		&amp;lt;add name=&amp;quot;calendarRule&amp;quot; virtualUrl=&amp;quot;~/calendar/.*&amp;quot; destinationUrl=&amp;quot;~/calendar.aspx&amp;quot;/&amp;gt;
	&amp;lt;/rewrites&amp;gt;
&amp;lt;/urlrewritingnet&amp;gt;
&amp;lt;system.web&amp;gt;
	&amp;lt;httpModules&amp;gt;
		&amp;lt;add name=&amp;quot;UrlRewriteModule&amp;quot; type=&amp;quot;UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter&amp;quot;/&amp;gt;
	&amp;lt;/httpModules&amp;gt;
&amp;lt;/system.web&amp;gt;&lt;/pre&gt;

&lt;p&gt;The above handles rewriting of Url's nothing more, nothing less. The existing BlogEngine.NET UrlRewrite have some business logic built in, for instance to retrieve the identifier of posts and sending them to the page that shows the post. I feel this doesn't belong in an UrlRewriter so I will implement this logic on the pages that actually handles the requests instead of on the UrlRewriter.&lt;/p&gt;

&lt;p&gt;So this was the first step, now we can move the if statement out of our default.aspx and let it concentrate on showing the default content which is the frontpage of the blog and the other pages concentrate on their tasks. How to implement the pages referred to in the mapping above will follow in the next post.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=CfcYaI3dKb0:ZSW8compMMs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=CfcYaI3dKb0:ZSW8compMMs:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=CfcYaI3dKb0:ZSW8compMMs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=CfcYaI3dKb0:ZSW8compMMs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=CfcYaI3dKb0:ZSW8compMMs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=CfcYaI3dKb0:ZSW8compMMs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=CfcYaI3dKb0:ZSW8compMMs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=CfcYaI3dKb0:ZSW8compMMs:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/CfcYaI3dKb0" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/CfcYaI3dKb0/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/BlogEngineNET---Urlrewriting.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=79f12de2-aae9-4ad4-b7d8-dc512badbd8a</guid>
      <pubDate>Thu, 08 May 2008 13:40:59 +0200</pubDate>
      <category>Blogengine.NET</category>
      <category>Tools</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=79f12de2-aae9-4ad4-b7d8-dc512badbd8a</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=79f12de2-aae9-4ad4-b7d8-dc512badbd8a</trackback:ping>
      <wfw:comment>http://intellect.dk/post/BlogEngineNET---Urlrewriting.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=79f12de2-aae9-4ad4-b7d8-dc512badbd8a</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=79f12de2-aae9-4ad4-b7d8-dc512badbd8a</feedburner:origLink></item>
    <item>
      <title>Small challenge: call method on null</title>
      <description>&lt;p&gt;Inspired by some talk I &amp;quot;overheard&amp;quot; on twitter I thought it would be interesting to post a small challenge. Is it possible to implement the missing parts of the following code so it compiles and runs without exceptions, if yes how would you do it? You are not allowed to modify the body of the Main method but the rest is up to you.&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;static void Main(string[] args)
{
    Foo f = null;
    f.Bar();
}&lt;/pre&gt;

&lt;p&gt;And yes its a pretty useless exercise :-)&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=ZE81SRMnf1Y:wD1k0a3NkzY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=ZE81SRMnf1Y:wD1k0a3NkzY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=ZE81SRMnf1Y:wD1k0a3NkzY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=ZE81SRMnf1Y:wD1k0a3NkzY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=ZE81SRMnf1Y:wD1k0a3NkzY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=ZE81SRMnf1Y:wD1k0a3NkzY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=ZE81SRMnf1Y:wD1k0a3NkzY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=ZE81SRMnf1Y:wD1k0a3NkzY:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/ZE81SRMnf1Y" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/ZE81SRMnf1Y/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/Small-challenge-call-method-on-null.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=661dd0c9-470b-418d-8e25-c1c92fd59549</guid>
      <pubDate>Fri, 25 Apr 2008 00:31:34 +0200</pubDate>
      <category>.NET</category>
      <category>C#</category>
      <category>Challenge</category>
      <category>English</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=661dd0c9-470b-418d-8e25-c1c92fd59549</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=661dd0c9-470b-418d-8e25-c1c92fd59549</trackback:ping>
      <wfw:comment>http://intellect.dk/post/Small-challenge-call-method-on-null.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=661dd0c9-470b-418d-8e25-c1c92fd59549</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=661dd0c9-470b-418d-8e25-c1c92fd59549</feedburner:origLink></item>
    <item>
      <title>BlogEngine.NET - DAL Architecture</title>
      <description>&lt;p&gt;So as I wrote a few days ago I have been looking at BlogEngine.NET and considered how I would have designed its lower layers. So lets kick off with the provider that's currently used in BlogEngine.NET for accessing the various storages (XML and RDBMS). The provider is responsible for accessing all data, that is Pages, Categories, Posts etc. Furthermore for each of these types of data it is responsible for the structure of the storage location, transforming the data from storage to objects including loading of related data. In my book this isn't good for extensibility, and as BlogEngine.NET provides multiple point for extending its functionality I would argue that it should be possible to extend its storage mechanism to handle new types of data just as easily. Currently extending the data access would involve adding new members to the provider and its implementations.&lt;/p&gt;  &lt;p&gt;So to solve this problem (and a few others I will address shortly) my suggestion would be to make data access classes responsible for a single type only, these can share some common functionality that deals with the structure of the storage when we talk about the XML provider. So basically we want to specify how these classes should look, the most generic approach is represented by this interface.&lt;/p&gt;   &lt;pre class="c-sharp" name="code"&gt;public interface IRepository&amp;lt;T&amp;gt;
{
    //Retrieval
    T Load(Guid identifier);
    IList&amp;lt;T&amp;gt; LoadAll();

    //Modification
    void Save(T instance);
    void Delete(T instance);
    void Delete(Guid identifier);
}&lt;/pre&gt;


&lt;p&gt;I have made the assumption here that all data has a Guid identifier, of course this could be handled so that we are free to choose the type of our identifier. But for know im satisfied with the Guid-identifier&lt;/p&gt;

&lt;p&gt;Instead of implementing our repositories right away we can abstract common details for storage types away in abstract classes. This way the implementation of our actual repositories are as slim as possible. I have (based on the way XML is stored in BlogEngine.NET) chosen two different storage types for XML and implemented the abstract classes SingleFileRepository&amp;lt;T&amp;gt; and SingleFolderRepository&amp;lt;T&amp;gt;. The first one handles storage of data types where all instances are in a single XML file, the second one handles storage of data types where each instance has its own XML file all contained in a folder. So the basic responsibility of these two classes is to handle details of the storage, that is the structure on disk and the structure in the files. Let me remind you that these abstract classes are only for simplifying the implementation of the actual repositories, if development later requires changing minor details we can override or even change the implementations on these, and if we want to start from scratch without the assumptions build into these abstract classes we can implement IRepository&amp;lt;T&amp;gt; any way we would like. This gives great flexibility in how different data is stored and the opportunity for code reusability is very much still there.&lt;/p&gt;

&lt;p&gt;Lets take a look at the code for SingleFolderRepository: &lt;/p&gt;


&lt;pre class="c-sharp" name="code"&gt;public abstract class SingleFolderRepository&amp;lt;T&amp;gt; : IRepository&amp;lt;T&amp;gt; where T : class, IEntity
{
    protected readonly IBlogSettings settings;
    protected readonly IObjectXmlConverter&amp;lt;T&amp;gt; converter;
    protected readonly string storagelocation;

    public SingleFolderRepository(IBlogSettings settings, IObjectXmlConverter&amp;lt;T&amp;gt; converter)
    {
        this.settings = settings;
        this.converter = converter;
        this.storagelocation = settings.StorageLocationFor(typeof (T));
    }

    public T Load(Guid identifier)
    {
        string path = Path.Combine(storagelocation, identifier + &amp;quot;.xml&amp;quot;);
        FileInfo datafile = new FileInfo(path);
        if (datafile.Exists)
        {
            return converter.Build(GetXml(datafile));
        }
        return null;
    }

    private string GetXml(FileInfo datafile)
    {
        string xml = string.Empty;
        using (StreamReader sr = new StreamReader(datafile.Open(FileMode.Open, FileAccess.Read, FileShare.Read)))
        {
            xml = sr.ReadToEnd();
        }
        return xml;
    }

    public IList&amp;lt;T&amp;gt; LoadAll()
    {
        List&amp;lt;T&amp;gt; instances = new List&amp;lt;T&amp;gt;();
        DirectoryInfo datadirectory = new DirectoryInfo(storagelocation);
        if (datadirectory.Exists)
        {
            foreach (FileInfo datafile in datadirectory.GetFiles(&amp;quot;*.xml&amp;quot;))
            {
                instances.Add(converter.Build(GetXml(datafile)));
            }
        }
        return instances;
    }

    public void Save(T instance)
    {
        if (converter.IsNew(instance))
        {
            instance.Identifier = Guid.NewGuid();
        }

        string path = Path.Combine(storagelocation, instance.Identifier + &amp;quot;.xml&amp;quot;);
        using (FileStream fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            using (StreamWriter writer = new StreamWriter(fs))
            {
                writer.Write(converter.Flatten(instance));
                writer.Flush();
            }
        }
    }

    public void Delete(T instance)
    {
        Delete(instance.Identifier);
    }

    public void Delete(Guid identifier)
    {
        string path = Path.Combine(storagelocation, identifier + &amp;quot;.xml&amp;quot;);
        File.Delete(path);
    }
}&lt;/pre&gt;


&lt;p&gt;So notice the constructor. The dependencies that this class has is passed into the contructor so before we can use the repository we need settings for the blog and an IObjectXmlConverter for the type that the repository handles. The IObjectXmlConverter handles flattening of objects to XML and building objects from XML. Below is an example an implementation of this.&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public class CategoryConverter : IObjectXmlConverter&amp;lt;Category&amp;gt;
{
    public Category Build(string xml)
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);
        Category c = new Category();
        c.Identifier = new Guid(doc.SelectSingleNode(&amp;quot;/category/&amp;quot;).Attributes[&amp;quot;id&amp;quot;].InnerText);
        c.Name = doc.SelectSingleNode(&amp;quot;/category/&amp;quot;).InnerText;
        return c;
    }

    public string Flatten(Category instance)
    {
        return
            XmlOutput.Create().XmlDeclaration()
                .Node(&amp;quot;category&amp;quot;)
                .Attribute(&amp;quot;id&amp;quot;, instance.Identifier.ToString())
                .InnerText(instance.Name).GetOuterXml();
    }
}&lt;/pre&gt;

&lt;p&gt;So this is where the mapping between the datastore and the objects happen, of course error handling should be in place here if we expect missing values in the data we load.&lt;/p&gt;

&lt;p&gt;With this change in structure presented above we have seperated concerns of the data access into smaller reusable components, furthermore in my book this makes the code easier to extend and understand but thats a subjective matter.&lt;/p&gt;

&lt;p&gt;So now its time to specify the actual repositories, we could settle for the functionality present on our generic IRepository but often we want more specific functionality for each datatype for instance fetching all posts in a specific category, paging of posts and so forth. So for each data type we define an interface with its actions. Currently in BlogEngine.NET much of this functionality is done in various places for instance sorting, filtering and paging. I would like to have our repositories responsible for this because the most efficient way to do these things depends on the type of storage. That is paging would for instance be done different for XML storage and RDBMS storage.&lt;/p&gt;

&lt;p&gt;So as an example we could make our repository for posts have an interface like this:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public interface IPostRepository : IRepository&amp;lt;Post&amp;gt;
{
    PageableList&amp;lt;Post&amp;gt; GetPage(int pagesize, int pagenum);
    PageableList&amp;lt;Post&amp;gt; GetPageInCategory(int category, int pagesize, int pagenum);
    PageableList&amp;lt;Post&amp;gt; GetPageWithTag(int tag, int pagesize, int pagenum);
    PageableList&amp;lt;Post&amp;gt; GetPageFromMonth(int month, int year, int pagesize, int pagenum);
}&lt;/pre&gt;

&lt;p&gt;Notice that we might need more methods, but this illustrates some examples on how we let the repository handle paging so it can optimize it based on the data storage.&lt;/p&gt;

&lt;p&gt;The actual implementation in the XML storage can be optimized but for now we load all data and do it in memory like BlogEngine.NET currently does. (I will discuss caching in a later post)&lt;/p&gt;

&lt;p&gt;The form and responsibility of our repositories is now pretty clear. You might have noticed that I have passed classes dependencies through their constructor. To avoid having to construct these dependencies myself I will use an Inversion of Control container that manages these dependencies for me. Furthermore configuration of the IoC container is what helps use interchange the repositiores for XML and RDBMS.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=n7SSwMdyuWk:EHPjos8NsDc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=n7SSwMdyuWk:EHPjos8NsDc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=n7SSwMdyuWk:EHPjos8NsDc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=n7SSwMdyuWk:EHPjos8NsDc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=n7SSwMdyuWk:EHPjos8NsDc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=n7SSwMdyuWk:EHPjos8NsDc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?i=n7SSwMdyuWk:EHPjos8NsDc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/intellectdk?a=n7SSwMdyuWk:EHPjos8NsDc:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/intellectdk?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/intellectdk/~4/n7SSwMdyuWk" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/intellectdk/~3/n7SSwMdyuWk/post.aspx</link>
      <author>Jakob Andersen</author>
      <comments>http://intellect.dk/post/BlogEngineNET---DAL-Architecture.aspx#comment</comments>
      <guid isPermaLink="false">http://intellect.dk/post.aspx?id=fc952b09-bb94-4260-8f37-fa97cf9e4b4c</guid>
      <pubDate>Thu, 24 Apr 2008 23:45:35 +0200</pubDate>
      <category>.NET</category>
      <category>Blogengine.NET</category>
      <category>C#</category>
      <category>English</category>
      <category>OOP</category>
      <dc:publisher>Jakob Andersen</dc:publisher>
      <pingback:server>http://intellect.dk/pingback.axd</pingback:server>
      <pingback:target>http://intellect.dk/post.aspx?id=fc952b09-bb94-4260-8f37-fa97cf9e4b4c</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://intellect.dk/trackback.axd?id=fc952b09-bb94-4260-8f37-fa97cf9e4b4c</trackback:ping>
      <wfw:comment>http://intellect.dk/post/BlogEngineNET---DAL-Architecture.aspx#comment</wfw:comment>
      <wfw:commentRss>http://intellect.dk/syndication.axd?post=fc952b09-bb94-4260-8f37-fa97cf9e4b4c</wfw:commentRss>
    <feedburner:origLink>http://intellect.dk/post.aspx?id=fc952b09-bb94-4260-8f37-fa97cf9e4b4c</feedburner:origLink></item>
  </channel>
</rss>
