<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://honestillusion.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Honest Illusion : monorail, C#</title><link>http://honestillusion.com/blogs/blog_0/archive/tags/monorail/C_2300_/default.aspx</link><description>Tags: monorail, C#</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Portable Areas for Castle Monorail, Part 2</title><link>http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx</link><pubDate>Thu, 01 Apr 2010 23:15:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7936</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><comments>http://honestillusion.com/blogs/blog_0/comments/7936.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7936</wfw:commentRss><description>
  &lt;P&gt;In our last episode, we discussed the PortableAreaController base class, which makes it simple to create a portable area using Monorail.  In this installment, we put that class to use.&lt;/P&gt;
&lt;P&gt;For the purposes of this example, the controller isn’t going to do anything useful – I’m not even going to bother with code in the actions.  The different actions will display different views so you can see the effect, and I’m hoping you’ll just trust that you can put real code in the action methods.&lt;/P&gt;&lt;PRE class="csharpcode"&gt;[Layout(&lt;SPAN class="str"&gt;"default"&lt;/SPAN&gt;,&lt;SPAN class="str"&gt;"patest"&lt;/SPAN&gt;)]
&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;class&lt;/SPAN&gt; PATest : PortableAreaController
{
    &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;void&lt;/SPAN&gt; Page1()
    {         }
    &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;void&lt;/SPAN&gt; Page2()
    {         }
    &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;void&lt;/SPAN&gt; Page3()
    {         }
}&lt;/PRE&gt;
&lt;P&gt; &lt;/P&gt;
&lt;P&gt;That’s our minimalistic example.  If it looks a lot like an ordinary Monorail controller, that’s the idea.    “PATest” is the name of the controller, which in the case of a Portable Area, is the name of the entire feature, so it’s be something like CoolWiki or MyForum.  &lt;/P&gt;
&lt;P&gt;The Action methods are identical to what you’d have in a normal controller.  In fact, everything in the portable controller is just like it would be if this were a intrinsic part of a website.  &lt;/P&gt;
&lt;P&gt;The rest is just about putting the pieces together in the assembly.   &lt;/P&gt;
&lt;P&gt;&lt;A href="http://honestillusion.com/blogs/blog_0/PortableAreaSolution_7652A1E6.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="PortableAreaSolution" border="0" alt="PortableAreaSolution" src="http://honestillusion.com/blogs/blog_0/PortableAreaSolution_thumb_6E5AFF84.png" width="244" height="226" /&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Individual files  (images, css files etc) should be placed in the root level of the project.  When referencing then in a view, just added “.rails” to the end ( &amp;lt;img src=”${siteRoot}/PATest/autolist.png.rails” /&amp;gt;)&lt;/P&gt;
&lt;P&gt;View templates should be in a folder named after the controller, and layouts in a “layouts” folder --- just as if the root level was the website’s “Views” folder.  You don;t have to do anything special to get Monorail to find them – that is handled for you by the base class.&lt;/P&gt;
&lt;P&gt;All those files (not the CS files obviously) should have their Build Action set to Embedded Resource.&lt;/P&gt;
&lt;P&gt;Note that when a view template is needed, Monorail will first look for a physical file in the website’s Views files, and failing there, search in the assembly.  This allows the end user to override the embedded view templates with their own.   In the example I’ve uploaded to the CastleContrib SVN repository, I’ve locally overridden Page2.&lt;/P&gt;
&lt;P&gt;The same holds for layouts, which I’ve put to use in the example.  I assumed that most sites will have a default layout for the site (which I further assumed is called “default”).  The controller uses that layout and adds it’s own child layout.  (The project should also define a simple default layout as just “${childContent}” just in case the website it’s being used in doesn’t define one.)&lt;/P&gt;
&lt;P&gt;The PortableAreaController base class has been added to the ViewComponent project in the CastleContrib SVN repository. (Yes, I know it’s not a ViewComponent, but I didn’t want to create a whole new branch -- particularly not for just one file-- and ViewComponents were the closest available existing project).  The PATest example shown here is a separate project under that branch, with the resulting Castle.MonoRail.PortableAreaExample.dll assembly added to the ViewComponent.TestSite project.  Note that that assembly is the &lt;EM&gt;only&lt;/EM&gt; file added to the website to enable this functionality, and the only other change was to add a reference to it into the web.config.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Portable+Areas+for+Castle+Monorail%2c+Part+2" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx&amp;subject=Portable+Areas+for+Castle+Monorail%2c+Part+2"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx&amp;title=Portable+Areas+for+Castle+Monorail%2c+Part+2" title="Submit Portable+Areas+for+Castle+Monorail%2c+Part+2 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx&amp;phase=2" title="Submit Portable+Areas+for+Castle+Monorail%2c+Part+2 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx&amp;title=Portable+Areas+for+Castle+Monorail%2c+Part+2" title="Submit Portable+Areas+for+Castle+Monorail%2c+Part+2 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7936" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item><item><title>Portable Areas for Castle Monorail</title><link>http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx</link><pubDate>Thu, 01 Apr 2010 23:09:59 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7935</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><comments>http://honestillusion.com/blogs/blog_0/comments/7935.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7935</wfw:commentRss><description>
  
&lt;p&gt;Recently I had read a blogger comparing Castle Monorail with ASP.NET MVC.  He chose ASP.NET mainly because it supported Portable Areas while Monorail did not.  As a supporter of Monorail, I was very offended by this, and decided to correct the problem.  The first step… finding out exactly what a “portable area” was.&lt;/p&gt;
&lt;p&gt;A Portable Area is a piece of functionality, with all pieces bundled up into a single assembly, which can be just “dropped into” an existing website.  Think of a forum or a wiki.  The idea is basically, I could just add wiki.dll to my site, and suddenly &lt;a href="http://www.mysite.com/wiki"&gt;www.mysite.com/wiki&lt;/a&gt; just works.&lt;/p&gt;
&lt;p&gt;Now, having a controller and its actions together in a single assembly is a basic design principle of Monorail (and essentially all of MVC design), so that part was done before I even began.  The rest was a bit trickier.&lt;/p&gt;
&lt;p&gt;I would have to store – and retrieve at the right times, the view template files, and all other associated files – images, style sheets, script files, etc.&lt;/p&gt;
&lt;p&gt;Storing the files was in itself trivial -- .NET has a means built right it. The file just need to be added to the project as embedded resources.  In Visual Studio, on the file’s property panel, set the “Build  Action” to “Embedded Resource”.&lt;/p&gt;
&lt;p&gt;Now that the files were in the assembly, we had to get them out of it. For views, which I had assumed were going to be the most trouble, this turned out to be simple, with the plumbing for it was already built into the Monorail framework.  Apparently, someone had planned for portable areas, but never followed through.  View templates are loaded by a class aptly called the FileAssemblyViewSourceLoader.  It looks in the “Views” folder for the template, and failing there, looks among the embedded resources of the assemblies in its collection.  However, nothing in the framework ever added an assembly to that collection, so this feature has always laid fallow.&lt;/p&gt;
&lt;p&gt;The final feature was getting it to load a random file from the resources.  Whenever I need to do something with a name not known in advance, a DefaultAction seems like the way to go.&lt;/p&gt;
&lt;p&gt;With that, all the pieces were in place, I just had a wee bit of code to tie them all together.  Defining a base class which a portable area could be derived from seemed the best approach.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PortableAreaController : SmartDispatcherController&lt;/pre&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;The first step was to override the Initialize() method, so that I could add this assembly to the list searched by FileAssemblyViewSourceLoader.  The only trick here is we must make sure that the assembly is only added once, regardless of how many times the controller is initialized.    And, while we are at it, we’ll also get the assembly name and a list of the resources and save them for later.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] resourceNames;
&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; asmName;

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize()
{
    &lt;span class="kwrd"&gt;base&lt;/span&gt;.Initialize();
    var asm = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetType().Assembly;
    resourceNames = asm.GetManifestResourceNames();
    asmName = asm.GetName().Name;
    var asminfo = &lt;span class="kwrd"&gt;new&lt;/span&gt; AssemblySourceInfo(asm, asmName.ToLower());
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.ViewSourceLoader.AssemblySources.Cast&amp;lt;AssemblySourceInfo&amp;gt;()&lt;br /&gt;                            .Any(asi=&amp;gt;asi.AssemblyName==asminfo.AssemblyName))
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.ViewSourceLoader.AddAssemblySource(asminfo);
}&lt;/pre&gt;
&lt;p&gt;Next is the DefaultAction.  The idea here is that you request somefile.jpg.rails, and we pull somefile.jpg out of the resources, and stream it to the browser.  In Monorail, a DefaultAction is a method which is called when no other method in the controller matches the action.  In our DefaultAction, we’ll generate a resource name from the assembly name and the Action name.  The Action is basically, the name of the “file” requested without the “.rails” extension, so if we ask for file “http://mysite.com/portable/myimage.gif.rails”, then the pseudo-file we are requesting is “myimage.gif.rails” which makes the Action “myimage.gif” which just happens to be the file we really want.  The only tricky part here is the GetContentTypeFromExt() function.  The problem is that there is a very simple way to do this --- which only works under Windows.  Now, while the vast majority of web servers running Monorail are Windows based, Monorail is designed to also run under Mono (Linux).   I couldn’t find a good portable way to handle this, so I just punted (check the source for dirty secrets).&lt;/p&gt;
&lt;p&gt;[DefaultAction] 
  &lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DefaultAction() 

  &lt;br /&gt;{ 

  &lt;br /&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; filename = asmName + &lt;span class="str"&gt;"."&lt;/span&gt; + Action; 

  &lt;br /&gt;    var resourceName = resourceNames.FirstOrDefault(rn=&amp;gt; rn.Equals(filename,StringComparison.InvariantCultureIgnoreCase)); 

  &lt;br /&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (resourceName!= &lt;span class="kwrd"&gt;null&lt;/span&gt;) 

  &lt;br /&gt;    { 

  &lt;br /&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; ext = Path.GetExtension(filename); 

  &lt;br /&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Response.ContentType = GetContentTypeFromExt(ext); 

  &lt;br /&gt;

  &lt;br /&gt;        Stream contents = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetType().Assembly.GetManifestResourceStream(resourceName); 

  &lt;br /&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Response.BinaryWrite(contents); 

  &lt;br /&gt;        CancelView(); 

  &lt;br /&gt;    } 

  &lt;br /&gt;} 

  &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;This method is the controller’s Default action by virtue of the [DefaultAction] attribute.  The name is arbitrary – DefaultAction just kept things simple.&lt;/p&gt;
&lt;p&gt;And with that, everything you need to write a portable area in Monorail is neatly contained in a simple base class.  Everything we’ve just gone over, you can now completely ignore.   &lt;/p&gt;
&lt;p&gt;Next, we discuss how you use this base class to write your own portable area.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Portable+Areas+for+Castle+Monorail" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx&amp;subject=Portable+Areas+for+Castle+Monorail"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx&amp;title=Portable+Areas+for+Castle+Monorail" title="Submit Portable+Areas+for+Castle+Monorail to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx&amp;phase=2" title="Submit Portable+Areas+for+Castle+Monorail to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx&amp;title=Portable+Areas+for+Castle+Monorail" title="Submit Portable+Areas+for+Castle+Monorail to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7935" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item><item><title>A ViewComponent extension for Castle MonoRail, Part II</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx</link><pubDate>Tue, 25 Aug 2009 00:44:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7882</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><comments>http://honestillusion.com/blogs/blog_0/comments/7882.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7882</wfw:commentRss><description>
  &lt;P&gt;This was intended to be a two-part article.  It was just after I published &lt;A href="http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx" target="_blank"&gt;the original article,&lt;/A&gt; I noticed that I’d left out a large part of ViewComponentEx. We continue…..&lt;/P&gt;
&lt;HR /&gt;
&lt;PRE class="c#"&gt;&lt;FONT size="4"&gt;        protected bool RenderOptionalSection(string section) 
        protected bool RenderOptionalSection(string section, string defaultText)&lt;/FONT&gt; &lt;/PRE&gt;
&lt;P&gt;Renders the named section of a block component – if the section is present.  If not, it just silently returns.   The second overload lets you provide some text to be rendered, if that section isn’t given:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size="3"&gt;RenderOptionalSection("tablestart", “&amp;lt;table&amp;gt;”)&lt;/FONT&gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Returns true if this section was rendered; false, if the section was present.  This seems like a very simple method (and it is), but if your component has a number of different sections for styling (such as the SmartGridViewComponent, which has 18!), this can do wonders to streamline your code.&lt;/P&gt;
&lt;HR /&gt;
&lt;PRE class="c#"&gt;&lt;FONT size="4"&gt;        void RenderComponent&amp;lt;VC&amp;gt;(params string[] componentParams) where VC : ViewComponentEx, new();
        void RenderComponent&amp;lt;VC&amp;gt;(IDictionary componentParams) where VC : ViewComponentEx, new();
        void RenderComponent(ViewComponentEx component, params string[] componentParams); 
        void RenderComponent(ViewComponentEx component, IDictionary componentParams); &lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;This implement, with a slightly different syntax, a technique originally devised by Joey Beninghove.  The idea is to make a ViewComponent which is composite of several other VCs.  The basic syntax is &lt;/P&gt;&lt;PRE class="c#"&gt;&lt;FONT size="4"&gt; RenderComponent&amp;lt;LinkSubmitButtonComponent&amp;gt;("linkText=Search",
             string.Format("formToSubmit={0}", searchFormName));&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;However, the various overloads allow using an already exist component object, and/or an already built dictionary of options.&lt;/P&gt;
&lt;HR /&gt;

&lt;P&gt;Also include in the source file is the class ViewComponentUsingSiteMap which, like ViewComponentEx, is an abstract base use for creating ViewComponents, but I’ll hold off discussing that until I ready to talk about the VCs the derive from it.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx&amp;subject=A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx&amp;title=A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II" title="Submit A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx&amp;phase=2" title="Submit A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx&amp;title=A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II" title="Submit A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7882" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item><item><title>A ViewComponent extension for Castle MonoRail</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx</link><pubDate>Mon, 24 Aug 2009 11:21:08 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7881</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><comments>http://honestillusion.com/blogs/blog_0/comments/7881.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7881</wfw:commentRss><description>
  &lt;p&gt;I’ve been rewriting my website, njtheater.com, (very slowly) as a Castle MonoRail application.  Along the way, I’ve written a number of ViewComponent and other elements.  Many of these were of general use, so I’ve added them to the CastleContib project, and documented them in the using.castleproject.org wiki.&lt;/p&gt;  &lt;p&gt;Two problem there: First, some of the items I wrote don’t fit into an exist category in CastleContrib (There’s one for ViewComponents, which I’ve stick a filter into, but putting a Controller base class there seemed wrong).  Second, CastleContrib &amp;amp; using.castleproject.org seem to be somewhat of a black hole.  No one seems to look there for information about the Castle Project (which is kind of a shame, since that’s exactly it’s purpose).  &lt;/p&gt;  &lt;p&gt;On the other hand, blogs posts about Castle are turning up everywhere.  We’ve even now got an &lt;a href="http://pipes.yahoo.com/pipes/pipe.run?_id=bGjr2c1s3hGi5qx20EypaA&amp;amp;_render=rss&amp;amp;limit=200" target="_blank"&gt;aggregated blog feed specific to Castle&lt;/a&gt;.  So, I figured, I start using my blog to talk about what I’ve written.&lt;/p&gt;  &lt;p&gt;In fact, one article I discovered on that aggregator was Andy Pike’s “Integrating Gravatar with Castle MonoRail” inwhich he discusses a Helper object for Monorail which creates Gravatars for use’s email addresses.  It was written last January.  The only thing is, I’ve written (and added to CastleContrib) a Gravatar component three months earlier.  That was going to be the topic of my first MonoRail blog post (and I will be my second), but first, I figure I should talk about the base class I once for all my ViewComponents, which I’ve given the rather imaginative name of ViewComponentEx.&lt;/p&gt;  &lt;p&gt;ViewComponentEx derives from ViewComponent, and can be used as a “drop-in” replacement for it, as the base class for your ViewComponents.  It provides a number of simple methods to help building ViewComponents.&lt;/p&gt;  &lt;pre class="c#"&gt;&lt;font size="4"&gt;void ConfirmSectionPresent(string section);&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Throws an exception if the given section is not present. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;string GetSectionText(string section);&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Get the text of a section as a string.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;string GetBodyText();&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Get the text of the body of a block component (without section)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;void RenderTextFormat(string format, params object[] args);&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Renders the text, formatted. Just like String.Format() &lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;string GetParamValue(string key, string defaultValue);&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;bool GetParamValue(string key, bool defaultValue);&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;E GetParamValue(string key, E defaultValue) where E : struct;&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Gets a parameter value, with a default. Overloaded to handle string, boolean, or Enum value. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;Castle.Core.Logging.ILogger Logger { get; set; }&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;A property for the system Logger. Automatically wired by Windsor, if active and a Logger is defined in the container. Default to NullLogger, otherwise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;string MakeUniqueId(string prefix);&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Makes an unique id. The given prefix is prepended to the generated number. The ID isn't actually guaranteed to be unique (which would require using all 32 digits of the guid). But this produce ids sufficiently distinctive to generate multiple controls on a page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Code available here: &lt;a href="http://honestillusion.com/files/folders/castle/entry7880.aspx" target="_blank"&gt;ViewComponentex.cs&lt;/a&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email A+ViewComponent+extension+for+Castle+MonoRail" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx&amp;subject=A+ViewComponent+extension+for+Castle+MonoRail"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx&amp;title=A+ViewComponent+extension+for+Castle+MonoRail" title="Submit A+ViewComponent+extension+for+Castle+MonoRail to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx&amp;phase=2" title="Submit A+ViewComponent+extension+for+Castle+MonoRail to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx&amp;title=A+ViewComponent+extension+for+Castle+MonoRail" title="Submit A+ViewComponent+extension+for+Castle+MonoRail to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7881" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item></channel></rss>