<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gojko Adzic &#187; activerecord</title>
	<atom:link href="http://gojko.net/tag/activerecord/feed/" rel="self" type="application/rss+xml" />
	<link>http://gojko.net</link>
	<description>Building software that matters</description>
	<lastBuildDate>Wed, 04 Aug 2010 11:38:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Castle Demo App #3: Saving time and effort with advanced Monorail features</title>
		<link>http://gojko.net/2008/05/26/castle-demo-app-3-saving-time-and-effort-with-advanced-monorail-features/</link>
		<comments>http://gojko.net/2008/05/26/castle-demo-app-3-saving-time-and-effort-with-advanced-monorail-features/#comments</comments>
		<pubDate>Mon, 26 May 2008 17:36:40 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[monorail]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=131</guid>
		<description><![CDATA[In the third part of the Castle tutorial, we look into the features of Monorail that allow us to save a lot of time and effort when developing web applications. We explore advanced Monorail concepts that help us delegate error processing and authentication to the framework and reuse templates. We also look into how Monorail [...]]]></description>
			<content:encoded><![CDATA[<p>In the third part of the Castle tutorial, we look into the features of Monorail that allow us to save a lot of time and effort when developing web applications. We explore advanced Monorail concepts that help us delegate error processing and authentication to the framework and reuse templates. We also look into how Monorail integrates nicely with ActiveRecord to automatically load and modify database objects based on HTML forms.<span id="more-131"></span></p>
<p>For those of you that have just joined this tutorial, this is the third iteration of the EvilLink web application. <a href='http://gojko.net/2008/05/07/castle-demo-app-activerecord-basics-and-unit-testing/'>In the first iteration</a>, we used basic features of ActiveRecord to set up a domain model and back it with a database. <a href='http://gojko.net/2008/05/13/castle-demo-app-2-monorail-basics/'>In the second iteration</a>, we created a basic web site using Monorail that allowed users to register and log in. If you have not worked with Monorail or ActiveRecord before, read those two articles before continuing with this one. </p>
<p>A quick note before we begin. Hammett from the Castle project was kind enough to correct me about ActiveRecord and mixing domain logic with storage. It turns out that there is a nice way to implement the repository pattern with ActiveRecord directly. Read about the ActiveRecord Mediator that allows that in <a href='http://hammett.castleproject.org/?p=287' target='_blank'>this post</a> (including the comments). </p>
<p>Unlike the previous two tutorials, this one will not list all the source code for all project classes and web files. We’ll just focus on the most important stuff. You can download the full source code for this iteration from <a href='/resources/EvilLink_i3.zip'>here</a>.</p>
<p>Let’s continue with the remaining user stories:</p>
<ul>
<li>As a user, I want to record my web links online, so that I can access them from anywhere.</li>
<li>As a user, I want to review the links that I previously recorded so that I can visit the interesting sites. </li>
<li>As a user, I want to edit details and descriptions of the links that I previously recorded, so that I can keep them up to date.</li>
</ul>
<p>To implement these stories, we will create a new controller to manage links. We will prevent anonymous users from accessing this controller by checking whether the user is logged in, and if not, redirecting them to the login page.</p>
<h2>Modifying the model</h2>
<p>To implement these stories, we will need to create the Link record type and describe the relationship between users and links. We add a Links collection to User class to record links that the user has registered. It’s best to have the type as a IList interface rather than a particular list to avoid data mapping problems. Instead of [Property], we mark this as [HasMany] to signal that it is a one-to-many mapping.</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>private</span><span> <span style='color:teal'>IList</span>&lt;<span style='color:teal'>Link</span>&gt; links = <span style='color:blue'>new</span> <span style='color:teal'>List</span>&lt;<span style='color:teal'>Link</span>&gt;();</span>
<span>[<span style='color:teal'>HasMany</span>]</span>
<span style='color:blue'>public</span><span> <span style='color:teal'>IList</span>&lt;<span style='color:teal'>Link</span>&gt; Links</span>
<span>{</span>
<span>    <span style='color:blue'>get</span> { <span style='color:blue'>return</span> links; }</span>
<span>    <span style='color:blue'>set</span> { links=<span style='color:blue'>value</span>; }</span>
<span>}</span>
</pre>
</div>
<p>The Link class is fairly straight-forward. The only interesting part is the other end of the one-to-many relationship. We mark it as [BelongsTo] and also specify that the Link collection should get saved and updated automatically when the User is saved.</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
[BelongsTo(Cascade = CascadeEnum.SaveUpdate)]
public User Owner
{
    get { return owner; }
    set { owner= value; }
}
</pre>
</div>
<h2>Dynamic binding, AR style</h2>
<p>One of the best things about the Castle project is how we can learn and use various components in isolation, but they also have added value when used together. Monorail and ActiveRecord together allow us to write web applications with very little boiler-plate code, focusing just on the business problem at hand. In the second part of this tutorial I explained how to use data binding to automatically populate domain objects from HTTP requests. When ActiveRecord comes into the play, this data binding becomes even more powerful. We can tell Monorail to automatically fetch a record object from the database by ID and have it ready for us to either pass to the view or modify. This is very convenient for actions that should display an object or present a HTML form to edit the object. This is done using the ARFetch attribute instead of DataBind and passing the request field that represents the ID of the related record object. For example, this method signature will automatically fetch a link by id from the database and make it available to us for display:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>public</span><span> <span style='color:blue'>void</span> Edit([<span style='color:teal'>ARFetch</span>(<span style='color:maroon'>&quot;id&quot;</span>)] <span style='color:teal'>Link</span> link)</span>
</pre>
</div>
<p>On the way back, we typically want to merge the database object with the request values. There is a shortcut for this as well:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>public</span><span> <span style='color:blue'>void</span> Submit([<span style='color:teal'>ARDataBind</span>(<span style='color:maroon'>&quot;link&quot;</span>,
AutoLoad = <span style='color:teal'>AutoLoadBehavior</span>.NewInstanceIfInvalidKey)] <span style='color:teal'>Link</span> link)</span>
</pre>
</div>
<p>ARDataBind will first find the object in the database, then populate it with changes from the HTTP request. The only thing left to do is to verify that the link is valid and save it. AutoLoadBehavior specifies what to do if the object is not found &mdash; in this case ARDataBind will create a new object, effectively enabling us to use the same method for creating and updating links.</p>
<p>To use these two attributes, our controller has to extend ARSmartDispatcherController, not SmartDispatcherController. The new controller base class and the data load attributes are in the Castle.MonoRail.ActiveRecordSupport.dll library, so add a reference to that DLL as well in your controllers project.</p>
<h2>Advanced Monorail concepts</h2>
<p>Instead of wrapping up here, let’s see what else we can delegate to Monorail and write less code. Monorail has several more tricks to save time and effort while creating web applications. </p>
<h3>Filters</h3>
<p>Filters, in Monorail jargon, are methods that are executed before or after controller actions. They allow us to declaratively add infrastructural functionality to the controller code, similar to Aspect Oriented Programming (Windsor provides better support for AOP in general and we’ll discuss this in one of the following articles in this series. Monorail filters are just simple additions to controller code). For example, we can use a filter to instantly prevent anonymous users from calling any action on the Link controller. A filter is specified on the whole controller class with a FilterAttribute. This one will execute the AuthenticatedUserFilter before each action:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span>[<span style='color:teal'>FilterAttribute</span>(<span style='color:teal'>ExecuteEnum</span>.BeforeAction, <span style='color:blue'>typeof</span>(<span style='color:teal'>AuthenticatedUserFilter</span>))]</span>
</pre>
</div>
<p>The filter class (in this case AuthenticatedUserFilter) has to implement the IFilter interface from Castle.Monorail.Framework. The interface has only one method: Perform. If it returns false, the HTTP request processing will stop at that point and will not proceed to the controller. So let’s check if a user is logged in, and if not then redirect the browser to the login page:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> System.Collections.Generic;</span>
<span style='color:blue'>using</span><span> System.Text;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span>&nbsp;</span>
<span style='color:blue'>namespace</span><span> EvilLink.Controllers</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>AuthenticatedUserFilter</span>: <span style='color:teal'>IFilter</span></span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>UserContext</span> userContext=<span style='color:blue'>new</span> <span style='color:teal'>UserContext</span>();</span>
<span>&nbsp;</span>
<span>&nbsp;</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>bool</span> Perform(<span style='color:teal'>ExecuteEnum</span> exec, </span>
<span>          <span style='color:teal'>IRailsEngineContext</span> context, <span style='color:teal'>Controller</span> controller)</span>
<span>        {</span>
<span>            <span style='color:blue'>if</span> (userContext.CurrentUserId == <span style='color:blue'>null</span>)</span>
<span>            {              </span>
<span>                context.Response.Redirect(<span style='color:maroon'>&quot;UserOps&quot;</span>,
<span style='color:maroon'>     &quot;index.ashx?goBackUrl=&quot;</span>+context.Request.Uri);</span>
<span>                <span style='color:blue'>return</span> <span style='color:blue'>false</span>;</span>
<span>            }</span>
<span>            <span style='color:blue'>else</span> <span style='color:blue'>return</span> <span style='color:blue'>true</span>;</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>We can now use this filter to quickly mark all controllers that require the customer to be logged in, just by putting an attribute on the class. </p>
<h3>Partial templates</h3>
<p>NVelocity allows us to reuse view code in different templates by just including the file, using #parse(file) command. This is what Rails calls partial templates. For example, we’ll need to display link details after a user registers that link, but we also need to display the same details when the user browses his links. Instead of copying the same content all over the templates, we can extract that into a common view file and just include it. The important thing to remember is that the path of the included file is relative to the views folder, not the current folder. This is an example of the view that prints links using a partial template:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
&lt;h1&gt;My Links&lt;/h1&gt;
#if ($links.Count&gt;0)
&lt;ul&gt;
	#foreach( $link in $links)
	&lt;li&gt;
		#parse ("Link/viewLink.vm")
	&lt;/li&gt;
	#end
&lt;/ul&gt;
#else
You have no saved links.
#end
#parse("Link/newLink.vm")
</pre>
</div>
<h3>Helpers</h3>
<p>NVelocity language intentionally does not allow you to perform complex scripting, to avoid mixing domain and UI code. But sometimes we want to automate generating HTML code in a more complex language. Monorail allows that with Helpers. Helpers allow us to script the UI formatting in C#. We used a forms helper in the second article of this tutorial, to build a HTML form and pre-populate it with values. There are some other interesting helpers included in the Castle distribution, for example Ajax helpers that generate Scriptaculous effects or help with Prototype communication. You can also write your own helpers and add them to the controllers using the Helper attribute.</p>
<h3>View components</h3>
<p>View components are a way to re-use parts of the UI dynamically in various pages. This is typically used to manage common parts of the web pages like menus. </p>
<p>I personally don’t use view components that much, because there are different alternatives that can provide the same functionality with just controllers. For view formatting (without any business functionality), it is often better to use Helpers. To loop through a list of objects and reuse the display functionality, I use partial templates (with NVelocity, you can use #parse to include a template file). Parts that reuse business functionality can be implemented using AJAX DIVs as well. So components are really used only when you need to re-use parts of UI that include some business functionality and layout, but you want to process that on the server as part of the same request (so no AJAX). </p>
<p>We use a component in this case to build the top menu bar, that will display links to log in and register if the user is not yet logged in, and display options to add and review stored links and to log out when a user is logged in. The component class is just like a mini-controller with a single action. To implement the component, we need to extend ViewComponent and override the Render method. PropertyBag is available for the component as well (it is actually shared with the controller). Because there is only one method, the component needs to explicitly specify which view gets rendered.</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span style='color:blue'>namespace</span><span> EvilLink.Controllers</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>MenuBarComponent</span>:<span style='color:teal'>ViewComponent</span></span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>UserContext</span> context=<span style='color:blue'>new</span> <span style='color:teal'>UserContext</span>();</span>
<span>&nbsp;</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>override</span> <span style='color:blue'>void</span> Render()</span>
<span>        {</span>
<span>            <span style='color:blue'>if</span> (context.CurrentUserId != <span style='color:blue'>null</span>)</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;appuser&quot;</span>] = context.CurrentUser;</span>
<span>            RenderView(<span style='color:maroon'>&quot;default&quot;</span>);</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>The view file for the component is similar to the controller view files, but it needs to be in the views\components\MenuBarComponent folder in the web site. To include this component somewhere in the view code, use #component NVelocity extension (this was added for the Castle project and it is not available in the basic NVelocity release). As components are re-usable across pages, they are typically included into the generic layout files, not into individual template views. So here is the changed default layout:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>&lt;</span><span style='color:maroon'>html</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>head</span><span style='color:blue'>&gt;&lt;</span><span style=';color:maroon'>title</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>&gt;</span><span style='font-size:10.0pt;font-family:"Courier New"'>Evil Link v 1.0<span style='color:blue'>&lt;/</span><span style='color:maroon'>title</span><span style='color:blue'>&gt;&lt;/</span><span style='color:maroon'>head</span><span style='color:blue'>&gt;</span></span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>link</span><span style='color:blue'> </span><span style='color:red'>rel</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>stylesheet</span>&quot;<span style='color:blue'> </span><span style='color:red'>href</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>$siteRoot/views/layouts/default.css</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>body</span><span style='color:blue'>&gt;</span>
<span>      #component(MenuBarComponent)</span>
<span style='color:blue'>      &lt;</span><span style=';color:maroon'>hr</span><span style=';color:blue'>/&gt;</span>
<span>      #if($message)</span>
<span style='color:blue'>      &lt;</span><span style=';color:maroon'>div</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'> </span><span style='font-size:10.0pt;font-family:"Courier New";color:red'>class</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>=</span><span style='font-size:10.0pt;font-family:"Courier New"'>&quot;<span style='color:blue'>message</span>&quot;<span style='color:blue'>&gt;</span></span>
<span>            $message</span>
<span style='color:blue'>      &lt;/</span><span style=';color:maroon'>div</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>&gt;</span>
<span>      #end</span>
<span>&nbsp;</span>
<span>      #if($error)</span>
<span style='color:blue'>      &lt;</span><span style=';color:maroon'>div</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'> </span><span style='font-size:10.0pt;font-family:"Courier New";color:red'>class</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>=</span><span style='font-size:10.0pt;font-family:"Courier New"'>&quot;<span style='color:blue'>error</span>&quot;<span style='color:blue'>&gt;</span></span>
<span>            $error</span>
<span style='color:blue'>      &lt;/</span><span style=';color:maroon'>div</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>&gt;</span>
<span>      #end</span>
<span>&nbsp;</span>
<span>      $childContent</span>
<span>&nbsp;</span>
<span style='color:blue'>&lt;/</span><span style='color:maroon'>body</span><span style='color:blue'>&gt;</span>
<span style='font-size:10.0pt;font-family:"Courier New"; color:blue'>&lt;/</span><span style='font-size:10.0pt;font-family:"Courier New"; color:maroon'>html</span><span style='font-size:10.0pt;font-family:"Courier New"; color:blue'>&gt;</span>
</pre>
</div>
<h3>Rescues</h3>
<p>Monorail Rescues allow us to delegate most common error handling cases, when we just display an error message to the user, to the framework. A rescue is just an alternative view that will be displayed in case of an exception, and passing the responsibility for that to the framework allow us to write less code &mdash; instead of try/catch and display error blocks in every action, we just specify an attribute. Rescues can be specified for the whole class or for individual methods, and can be called for a particular exception type or for any exception. For example, to just display an error view in case of any exceptions during processing, we can add a Rescue(&#8220;error&#8221;) attribute to the controller class. The actual view should be stored in the views\rescues folder of the web site. In the view, we can use $context to reference the rails context. See <a target='_blank' href='http://api.castleproject.org/html/AllMembers_T_Castle_MonoRail_Framework_IRailsEngineContext.htm'>IRailsEngineContext API docs</a> for more details on that. Most important is the fact that $context.LastException.Message will give us the exception message. So here is a simple rescue velocity file:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>&lt;</span><span style='color:maroon'>div</span><span style='color:blue'> </span><span style='color:red'>class</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>error</span>&quot;<span style='color:blue'>&gt;</span></span>
<span>$context.LastException.Message</span>
<span style='color:blue'>&lt;/</span><span style='color:maroon'>div</span><span style='color:blue'>&gt;</span>
</pre>
</div>
<h2>Implementing the Link Controller</h2>
<p>Armed with all this knowledge, we can now easily implement the link controller. We’ll add a filter to prevent people from using any of the link controller actions if they are not logged in, and we will also not write any error handling code &#038;mdash instead it will be delegated to a rescue. We need to implement actions to register a new link and edit an existing link. After the user submits link details, we store them to the database and display new link information. We also want to enable users to view registered links. For that, we’ll create the following actions:</p>
<ul>
<li>NewLink &mdash; display a form for a new link</li>
<li>Edit &mdash; display a form to edit an existing link</li>
<li>MyLinks &mdash; view registered links</li>
<li>Submit &mdash; process a form containing link details, either to create or edit a link</li>
<li>View &mdash; view details of a particular link</li>
</ul>
<p>Edit and View perform the same action essentially, they just load the link details from the database and pass it on to the view to display (but they use different views). We’ll use ARFetch for Edit and View, and we use ARDataBind for Submit. NewLink and Edit should use the same visual template, and MyLinks should use that same template to display links from a collection. For that, we can use the #parse trick. </p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> System.Collections.Generic;</span>
<span style='color:blue'>using</span><span> System.Text;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.ActiveRecordSupport;</span>
<span style='color:blue'>using</span><span> EvilLink.Database;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span style='color:blue'>namespace</span><span> EvilLink.Controllers</span>
<span>{</span>
<span>    [<span style='color:teal'>FilterAttribute</span>(<span style='color:teal'>ExecuteEnum</span>.BeforeAction, <span style='color:blue'>typeof</span>(<span style='color:teal'>AuthenticatedUserFilter</span>))]</span>
<span>    [<span style='color:teal'>Rescue</span>(<span style='color:maroon'>&quot;error&quot;</span>), <span style='color:teal'>Layout</span>(<span style='color:maroon'>&quot;default&quot;</span>)]</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>LinkController</span> : <span style='color:teal'>ARSmartDispatcherController</span> </span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>UserContext</span> context=<span style='color:blue'>new</span> <span style='color:teal'>UserContext</span>();</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> NewLink()</span>
<span>        {</span>
<span>            <span style='color:green'>// just display the form</span></span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Submit([<span style='color:teal'>ARDataBind</span>(<span style='color:maroon'>&quot;link&quot;</span>,</span>
<span>         AutoLoad = <span style='color:teal'>AutoLoadBehavior</span>.NewInstanceIfInvalidKey)] <span style='color:teal'>Link</span> link)</span>
<span>        {</span>
<span>            <span style='color:blue'>if</span> (!link.IsValid())</span>
<span>            {</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;link&quot;</span>] = link;</span>
<span>                Flash[<span style='color:maroon'>&quot;error&quot;</span>] = link.ValidationErrorMessages;</span>
<span>                RenderView(<span style='color:maroon'>&quot;edit&quot;</span>);</span>
<span>                <span style='color:blue'>return</span>;</span>
<span>            }</span>
<span>            link.Owner = context.CurrentUser;</span>
<span>            link.SaveAndFlush();</span>
<span>            Flash[<span style='color:maroon'>&quot;message&quot;</span>] = <span style='color:maroon'>&quot;Link saved&quot;</span>;</span>
<span>            <span style='color:green'>//redirect after post</span></span>
<span>            Redirect(<span style='color:maroon'>&quot;view.ashx?id=&quot;</span>+link.Id);</span>
<span>        }</span>
<span>        <span style='color:green'>// shortcut for loading the object, don't update it with request values</span></span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> View([<span style='color:teal'>ARFetch</span>(<span style='color:maroon'>&quot;id&quot;</span>)] <span style='color:teal'>Link</span> link)</span>
<span>        {</span>
<span>            PropertyBag[<span style='color:maroon'>&quot;link&quot;</span>] = link;</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Edit([<span style='color:teal'>ARFetch</span>(<span style='color:maroon'>&quot;id&quot;</span>)] <span style='color:teal'>Link</span> link)</span>
<span>        {</span>
<span>            View(link); <span style='color:green'></span></span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> MyLinks()</span>
<span>        {</span>
<span>            PropertyBag[<span style='color:maroon'>&quot;links&quot;</span>] = context.CurrentUser.Links;</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<h2>Key stuff to remember</h2>
<ul>
<li>Mark one-to-many relationships with [HasMany] and [BelongsTo]</li>
<li>Reuse parts of templates with #parse </li>
<li>Use helpers to perform more complex UI scripting with C#, but avoid putting any business functionality into helper classes</li>
<li>Share business functionality and UI between pages using view components</li>
<li>Delegate error handling to rescues</li>
<li>Use Filters for simple aspect-style programming with Controllers to perform authentication, logging and similar actions</li>
<li>Use ActiveRecord data binding attributes and ARSmartDispatcherController to automatically load objects from the database and merge changes from HTML forms</li>
</ul>
<h2>Next exercise</h2>
<p>In the next part of this tutorial, we look into unit testing Monorail controllers. That tutorial should be online early next week. You can download the full source code for this iteration from <a href='/resources/EvilLink_i3.zip'>here</a>.</p>
<p>Meanwhile, you might be interested in coming to the &#8220;Developing Ajax Web applications with Castle Monorail&#8221; presentation that I will be doing on the 12th of June in London. It&#8217;s free, but you have to register up-front. See <a href='http://skillsmatter.com/event/open-source-dot-net/developing-ajax-web-applications-with-castle-monorail'>Skills Matter site</a> for more information.   </p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/05/26/castle-demo-app-3-saving-time-and-effort-with-advanced-monorail-features/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Castle demo App #2: Monorail basics</title>
		<link>http://gojko.net/2008/05/13/castle-demo-app-2-monorail-basics/</link>
		<comments>http://gojko.net/2008/05/13/castle-demo-app-2-monorail-basics/#comments</comments>
		<pubDate>Tue, 13 May 2008 21:25:33 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[alt.net]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[monorail]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=125</guid>
		<description><![CDATA[In the second part of the Castle demo application tutorial, we look into the basic features of Castle’s powerful Model-View-Controller system, called Monorail. Monorail is based on Ruby on Rails, and brings two very important features to .NET web development: 1. Good separation of concerns between the domain model, workflow logic and the user interface: [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/images/103301_monorail_train_2.jpg" style="border:1px solid black; margin:5px 5px 5px 5px" align="left" />In the second part of the Castle demo application tutorial, we look into the basic features of Castle’s powerful Model-View-Controller system, called Monorail. Monorail is based on Ruby on Rails, and brings two very important features to .NET web development: </p>
<p>1.	Good separation of concerns between the domain model, workflow logic and the user interface: this allows us to unit test larger portions of web applications, makes the code more reusable and gives us flexibility for the user interface.</p>
<p>2.	HTTP request/response plumbing, allowing us to be much more productive when developing web pages: Monorail will automatically convert HTTP request data into strongly typed function parameters, even domain objects; it provides an infrastructure for aspect-oriented request handling and reacting to errors. That allows us to focus on the business logic of the web application and skip writing boilerplate web code.<span id="more-125"></span></p>
<p>The <a href="http://en.wikipedia.org/wiki/Model-view-controller" target="_blank">Model-View-Controller </a> (MVC) pattern has stood the test of time as the best way to implement user interfaces for business applications. It asks for a clear separation of responsibilities between the domain business logic (model), workflow (controller) and the actual user interface (view). MVC has been around since the eighties, and although there are arguably more productive ways to develop user interfaces, MVC is important because it makes sure that applications will be easy to maintain. First of all, the clear separation of concerns is there to ensure that the user interface layout, typically the most frequently changed part of the system, can be updated and modified without affecting the business logic. User interface code and business code are never mixed, so we can re-use the model for several views and we can change or add views easily. Also, this separation allows us to cover a huge part of the application with automated unit tests. Automated testing through the user interface is hard to implement properly, and such tests are <a href="http://gojko.net/2007/09/25/effective-user-interface-testing/" target="_blank">very brittle and generally a pain to maintain</a>. Since MVC requires that the user interface code contains no business logic, all business code can be properly tested without even touching the UI. Monorail, in addition, allows us to unit-test the controller code easy as well (this will be explained in one of the next articles in this series). Separating workflow logic from the actual user interface display makes the code more reusable. For example, let&#8217;s say that we are working on a reporting application that allows users to view their account statements over the Web. Once the model and controllers are implemented for statements as HTML tables, changing the application to export those reports as PDFs or Excel sheets is very easy &mdash; we just need to implement another set of views. The logic behind how those views are created, authentications, data collection and filters can all be reused. </p>
<p>MVC is traditionally not the easiest way to create user-facing applications, but it makes sure that the applications can evolve easily and that the cost of maintenance and enhancements is low. Monorail goes one step further, and takes away all the plumbing code for web pages and makes the MVC model much more productive. We’ll come to that later, but now we need to take a step back. </p>
<p>A quick note before we move on: You can download the source code for this example from <a href="http://gojko.net/resources/EvilLink_i2.zip">http://gojko.net/resources/EvilLink_i2.zip</a> </p>
<h2>User Registration, continued</h2>
<p>In the previous article of this series, <a href='http://gojko.net/2008/05/07/castle-demo-app-activerecord-basics-and-unit-testing/'>ActiveRecord basics and unit testing</a>, I introduced the basic features of Castle’s database interface toolkit, ActiveRecord. We started implementing the User Registration story, and now we are going to complete it by building a set of web pages to allow users to register. In addition, to be able to check whether the users have successfully registered, we will allow them log in. In the MVC pattern, we have to separate business logic, workflow and user interface into distinct layers. For the business logic, the first story requires us to allow users to register and verify the login details. Workflow and session logic for now deal with the fact that the users should be able to register if they are not logged in, and that they will be able to log out after logging in. The user interface part will deal with how to display the forms for registration and login. Within Castle’s MVC stack, ActiveRecord typically represents the model, Monorail controllers deal with the workflow (and controll the session), and View engines such as NVelocity deal with the user interface.</p>
<p>ActiveRecord is probably not the best choice for the model in complex applications, because it effectively has two very distinct responsibilities: domain logic and storage. When building more complex systems, it makes a lot of sense to use a different pattern for storage, such as the <a href="http://martinfowler.com/eaaCatalog/repository.html" target="_blank">Repository pattern</a>, and have a separate layer of domain logic built around plain CLR objects. Castle also integrates nicely with NHibernate directly (and with iBatis ORM framework, if you do not want to use NHibernate), which allows us to implement a different storage pattern. However,  that requires somewhat more configuration and code, and we’ll leave that for later articles in this series. For now, let’s keep it simple. </p>
<h3>Completing the domain for User Registration</h3>
<p>Our User record class already provides a way for new users to register, simply by creating and saving a new user object. But we have to add the logic for verifying login details. Such domain logic methods that do not operate on a particular User object, but relate to the whole concept of Users, are typically implemented as static methods in the record class. We can use FindAllByProperty (provided by the ActiveRecordValidationBase which the User class extends) to get a list of User objects matching a particular property &mdash; in this case we can look for a matching username. Then we verify that the password is correct and return the appropriate user object. If the passwords do not match, or there is no user with requested username, we return null. In a real system, passwords should be kept encrypted and we would probably have to verify a password hash against the stored value, but let’s keep it simple in this tutorial. Here is the method to add to the User class: </p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>public</span><span> <span style='color:blue'>static</span> <span style='color:teal'>User</span> Login(<span style='color:blue'>string</span> username, <span style='color:blue'>string</span> password)</span>
<span>{</span>
<span>    <span style='color:teal'>User</span>[] user = <span style='color:teal'>User</span>.FindAllByProperty(<span style='color:maroon'>&quot;Username&quot;</span>, username);</span>
<span>    <span style='color:blue'>if</span> (user.Length == 0) <span style='color:blue'>return</span> <span style='color:blue'>null</span>;</span>
<span>    <span style='color:blue'>if</span> (user[0].password.Equals(password)) <span style='color:blue'>return</span> user[0];</span>
<span>    <span style='color:blue'>return</span> <span style='color:blue'>null</span>;</span>
<span>}</span>
</pre>
</div>
<p>Let’s add a few unit tests to verify that this method works correctly to the UserTests class:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span>[Test]</span>
<span style='color:blue'>public</span><span> <span style='color:blue'>void</span> TestLoginCorrect()</span>
<span>{</span>
<span>    <span style='color:teal'>User</span> mike = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;Mike Smith&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass123&quot;</span>, <span style='color: maroon'>&quot;mike@mike.com&quot;</span>);</span>
<span>    mike.Save();</span>
<span>    <span style='color:teal'>User</span> tom = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;Tom Smith&quot;</span>, <span style='color:maroon'>&quot;tom&quot;</span>, <span style='color:maroon'>&quot;tom123&quot;</span>, <span style='color:maroon'>&quot;tom@tom.com&quot;</span>);</span>
<span>    tom.Save();</span>
<span>    Flush();</span>
<span>    <span style='color:teal'>User</span> loggedIn = <span style='color:teal'>User</span>.Login(<span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass123&quot;</span>);</span>
<span>    <span style='color:teal'>Assert</span>.AreEqual(mike, loggedIn);</span>
<span>&nbsp;</span>
<span>}</span>
<span>[Test]</span>
<span style='color:blue'>public</span><span> <span style='color:blue'>void</span> TestLoginWrongPw()</span>
<span>{</span>
<span>    <span style='color:teal'>User</span> mike = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;Mike Smith&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass123&quot;</span>, <span style='color: maroon'>&quot;mike@mike.com&quot;</span>);</span>
<span>    mike.Save();</span>
<span>    Flush();</span>
<span>    <span style='color:teal'>User</span> loggedIn = <span style='color:teal'>User</span>.Login(<span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass12&quot;</span>);</span>
<span>    <span style='color:teal'>Assert</span>.IsNull(loggedIn);</span>
<span>}</span>
<span>[Test]</span>
<span style='color:blue'>public</span><span> <span style='color:blue'>void</span> TestLoginWrongUsername()</span>
<span>{</span>
<span>    <span style='color:teal'>User</span> mike = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;Mike Smith&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass123&quot;</span>, <span style='color: maroon'>&quot;mike@mike.com&quot;</span>);</span>
<span>    mike.Save();</span>
<span>    Flush();</span>
<span>    <span style='color:teal'>User</span> loggedIn = <span style='color:teal'>User</span>.Login(<span style='color:maroon'>&quot;ke&quot;</span>, <span style='color:maroon'>&quot;mpass12&quot;</span>);</span>
<span>    <span style='color:teal'>Assert</span>.IsNull(loggedIn);</span>
<span>}</span>
</pre>
</div>
<h2>Setting up the projects</h2>
<p>To start building our web site, we now add two new projects to the solution. One project is a plain C# class library that will contain our controllers and other web application code &mdash; let’s call it EvilLink.Controllers. The second project is the actual web site: configuration and layout files &mdash; effectively the View part of the MVC stack. Let’s call the second project EvilLink.WebSite. If you are working with the commercial version of Visual Studio, you can use the Web application template to build the second project. If you are working with the Express version, create it as a Class Library project, then go to project build properties (right-click on the project, select properties, then click on the Build tab) and change the output path to bin\  (it’s probably bin\Release or bin\Debug by default). The reason for this is that IIS automatically loads DLLs from the bin folder of Web applications, so we want Visual Studio to put all dependencies there. Add the following references to the controllers project: Castle.ActiveRecord.dll, Castle.Core.dll, Castle.Monorail.Framework.dll, System.Web from GAC and EvilLink.Database project. Add the following references to the web site project: Castle.ActiveRecord.dll, Castle.Components.Validator.dll, Castle.Core.dll, Castle.DynamicProxy.dll, Castle.Monorail.Framework.dll, Castle.Monorail.Framework.Views.Nvelocity.dll, log4net.dll, NHibernate.dll, NVelocity.dll (the last three are in the dependencies zip file of the Castle distribution), EvilLink.Controllers and EvilLink.Database projects. If you are using the Express version of Visual Studio, configure a Web site in IIS to point to the root of the EvilLink.WebSite project.</p>
<h2>Creating the web application</h2>
<p>We need to initialise ActiveRecord properly when the Web application starts. To do that, we’ll replace the default Web application with our own. Instead of loading ActiveRecord configuration from a separate file, let’s keep it in web.config with all the other web application parameters. Instead of using the XmlConfigurationSource, like in the unit tests, we can specify that ActiveRecord should load the configuration from the main configuration section with ActiveRecordSectionHandler.Instance. So add this class to the Controllers project:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System.Reflection;</span>
<span style='color:blue'>using</span><span> Castle.ActiveRecord.Framework.Config;</span>
<span style='color:blue'>using</span><span> Castle.ActiveRecord;</span>
<span>&nbsp;</span>
<span style='color:blue'>namespace</span><span style='font-size: 10.0pt;font-family:"Courier New"'> EvilLink.Controllers</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>EvilLinkWebApp</span> : System.Web.<span style='color:teal'>HttpApplication</span></span>
<span>    {</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Application_OnStart()</span>
<span>        {</span>
<span>                <span style='color:teal'>ActiveRecordStarter</span>.Initialize(</span>
<span>                    <span style='color:teal'>Assembly</span>.GetAssembly(<span style='color:blue'>typeof</span>(EvilLink.Database.<span style='color:teal'>User</span>)),</span>
<span>                <span style='color:teal'>ActiveRecordSectionHandler</span>.Instance);</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>Create a file called global.asax in the EvilLink.WebSite project root, and set the Web application class:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
&lt; %@ Application Inherits="EvilLink.Controllers.EvilLinkWebApp,
EvilLink.Controllers" %&gt;
</pre>
</div>
<p>Now let’s create the web.config file in the EvilLink.WebSite project root. To configure Monorail, we add a MonoRailSectionHandler section, specify the assembly that contains controller classes (in this case EvilLink.Controllers) and define the view engine (for this example we use NVelocity). The controller code is decoupled from the view code &mdash; controllers are not concerned with the actual display of results. NVelocity view engine uses templates written in the <a href=’ http://velocity.apache.org/engine/devel/vtl-reference-guide.html’>Velocity language</a>. There are other view engines that you can use, including the WebForms view engine (although I honestly don’t know anyone who uses that). To make Monorail work, we also need to load the Monorail HTTP module and then route some requests to Monorail. People often use .rails as the extension for Monorail, but I like to use one of the standard .NET extensions to keep things consistent with the .NET environment and make the Web server configuration simple &mdash; in this example we map all requests for .ashx pages to Monorail. If you want to use a non-standard extension (like .rails), don’t forget to to assign that content type to ASP.NET in IIS configuration (remember to uncheck the Verify that file exists option for that extension). To configure ActiveRecord, we just copy the configuration from unit tests into an ActiveRecordSectionHandler section. The only thing that should be changed is the isWeb attribute &mdash; in this case, set it to true. Here is the full configuration file:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>&lt;?</span><span style='color:maroon'>xml</span><span style='color:blue'> </span><span style='color:red'>version</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>1.0</span>&quot;<span style='color:blue'> </span><span style='color:red'>encoding</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>utf-8</span>&quot;<span style='color:blue'> ?&gt;</span></span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>configuration</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>  &lt;</span><span style='color:maroon'>configSections</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>    &lt;</span><span style='color:maroon'>section</span><span style='color:blue'> </span><span style='color:red'>name</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>monorail</span>&quot;<span style='color:blue'> </span></span>
<span style='color:blue'>      </span><span style='color:red'>type</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>Castle.MonoRail.Framework.Configuration.MonoRailSectionHandler, </span></span>
<span style='color:blue'>            Castle.MonoRail.Framework</span><span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>     &lt;</span><span style='color:maroon'>section</span><span style='color:blue'> </span><span style='color:red'>name</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>activerecord</span>&quot;</span>
<span style='color:blue'>      </span><span style='color:red'>type</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, </span></span>
<span style='color:blue'>            Castle.ActiveRecord</span><span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>   &lt;/</span><span style='color:maroon'>configSections</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>   &lt;</span><span style='color:maroon'>monorail</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>controllers</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>        &lt;</span><span style='color:maroon'>assembly</span><span style='color:blue'>&gt;</span><span>EvilLink.Controllers<span style='color:blue'>&lt;/</span><span style='color:maroon'>assembly</span><span style='color:blue'>&gt;</span></span>
<span style='color:blue'>      &lt;/</span><span style='color:maroon'>controllers</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>viewEngines</span><span style='color:blue'> </span><span style='color:red'>viewPathRoot</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>Views</span>&quot;<span style='color:blue'>&gt;</span></span>
<span style='color:blue'>        &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>type</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>Castle.MonoRail.Framework.Views.NVelocity.NVelocityViewEngine, </span></span>
<span style='color:blue'>                   Castle.MonoRail.Framework.Views.NVelocity</span><span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>      &lt;/</span><span style='color:maroon'>viewEngines</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>    &lt;/</span><span style='color:maroon'>monorail</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>    &lt;</span><span style='color:maroon'>activerecord</span><span style='color:blue'> </span><span style='color:red'>isWeb</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>true</span>&quot;<span style='color:blue'> </span><span style='color:red'>pluralizeTableNames</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>true</span>&quot;<span style='color:blue'>&gt;</span></span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>config</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>        &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>key</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>hibernate.connection.driver_class</span>&quot;<span style='color:blue'> </span></span>
<span style='color:red'>             value</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>NHibernate.Driver.SqlClientDriver</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>        &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>key</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>hibernate.dialect</span>&quot;<span style='color:blue'>                 </span></span>
<span style='color:blue'>             </span><span style='color:red'>value</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>NHibernate.Dialect.MsSql2005Dialect</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>        &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>key</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>hibernate.connection.provider</span>&quot;<span style='color:blue'>     </span></span>
<span style='color:red'>             value</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>NHibernate.Connection.DriverConnectionProvider</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>        &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>key</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>hibernate.connection.connection_string</span>&quot;<span style='color:blue'> </span></span>
<span style='color:red'>             value</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>Data Source=MALI\SQLEXPRESS;Initial Catalog=castletest;</span></span>
<span style='color:blue'>                    user id=castletest;password=castletest</span><span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>     &lt;/</span><span style='color:maroon'>activerecord</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>  &lt;</span><span style='color:maroon'>system.web</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>    &lt;</span><span style='color:maroon'>httpHandlers</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>verb</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>*</span>&quot;<span style='color:blue'> </span><span style='color:red'>path</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>*.ashx</span>&quot;<span style='color:blue'> </span></span>
<span style='color:blue'>       </span><span style='color:red'>type</span><span style='color:blue'>=</span><span style='font-size: 10.0pt;font-family:"Courier New"'>&quot;<span style='color:blue'>Castle.MonoRail.Framework.MonoRailHttpHandlerFactory, </span></span>
<span style='color:blue'>             Castle.MonoRail.Framework</span><span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>     &lt;/</span><span style='color:maroon'>httpHandlers</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>   &lt;</span><span style='color:maroon'>httpModules</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>name</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>monorail</span>&quot;<span style='color:blue'> </span></span>
<span style='color:blue'>        </span><span style='color:red'>type</span><span style='color:blue'>=</span><span style='font-size: 10.0pt;font-family:"Courier New"'>&quot;<span style='color:blue'>Castle.MonoRail.Framework.EngineContextModule, </span></span>
<span style='color:blue'>              Castle.MonoRail.Framework</span><span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>    &lt;/</span><span style='color:maroon'>httpModules</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>  &lt;/</span><span style='color:maroon'>system.web</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>&lt;/</span><span style=' color:maroon'>configuration</span><span style='color:blue'>&gt;</span>
</pre>
</div>
<h2>Hello World from Monorail</h2>
<p>Let’s start with a really simple example, just to verify that everything is properly set up. Three basic Monorail concepts that we’ll use in this exercise are:</p>
<ul>
<li>View: a particular visual display of some data. It does not contain any workflow or business logic &mdash; it is only concerned with how to render HTML from the provided information.</li>
<li>Controller: a .NET class handling the UI workflow for a set of related operations. This class handles all web requests and instructs Monorail which view to use to display the results, but not how to display them. This loosely corresponds to a web folder in a non-MVC environment.</li>
<li>Action: a method of the controller used to coordinate a single operation. This loosely corresponds to a single web page in a non-MVC environment.</li>
</ul>
<p>Now we create a controller that will display a form for entering a message, and after you type in something, print that message. Add this class to the EvilLink.Controllers project:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span>&nbsp;</span>
<span style='color:blue'>namespace</span><span> EvilLink.Controllers</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>HelloWorldController</span>:<span style='color:teal'>SmartDispatcherController</span></span>
<span>    {</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Index()</span>
<span>        {</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> ShowMessage(<span style='color:teal'>String</span> message)</span>
<span>        {</span>
<span>            PropertyBag[<span style='color:maroon'>&quot;message&quot;</span>] = message;</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>This controller extends the SmartDispatcherController. Most of your controllers will do the same. SmartDispatcherController will append the word Controller to the request folder name and look for the class, then find a method based on the file path of the URL, without the file extension.  In this case, if your local web site is running on http://localhost, then the request for http://localhost/helloworld/index.ashx would call the Index method of the HelloWorldController class. The request for http://localhost/helloworld/showmessage.ashx would call the ShowMessage method. GET/POST request parameters are automatically mapped to method parameters, based on name matching. SmartDispatcherController promotes the use of convention over configuration, so its programming model is very light-weight. Notice that there is no HTTP processing code in this class &mdash; Monorail takes care of all the plumbing. This is a simple optimization of work required to process a web request, but it makes the code much more clear. Considering that an average web site can have anywhere from a few dozen to a few hundred similar actions, this optimisation saves a lot of time and effort. It takes less code to build the web site, and less code means easier maintenance and less chance for errors.</p>
<p>The job of a controller in Monorail is to coordinate requests to the model classes to complete the workflow, and then prepare information that a view will use to render HTML. The data that should be available to the view is just stored in the PropertyBag dictionary. In this example, we use the message key in the PropertyBag dictionary to pass on the message that a user typed in. </p>
<p>Now, go to the EvilLink.WebSite project, and create a views folder. Then create a HelloWorld subfolder within that folder. This is where Monorail will look for the view files for the HelloWorld controller. In this exercise, we use the NVelocity template engine for views, and NVelocity files typically have the .vm extension. So create a text file called index.vm inside the HelloWorld folder and paste this content:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
Hello world from Monorail! Type in a message:
&lt;form method="post" action="showmessage.ashx"&gt;
&lt;input type="text" name="message" /&gt;
&lt;input type="submit" value="Show" /&gt;
&lt;/form&gt;
</pre>
</div>
<p>This is just a plain HTML file, with a form that will call our ShowMessage action. Notice that the form has a text field called message &mdash; this field will be mapped to the ShowMessage method argument of the same name. Now create showmessage.vm in the same folder, with the following content:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
You typed in: ${message}
</pre>
</div>
<p>Velocity uses a simple template language to access objects from the PropertyBag dictionary. In this case, we just enclose the object name into ${} and it gets printed out. You can use this syntax to access object properties or call object methods as well.</p>
<p>Rebuild the solution (so that Visual Studio copies all required DLLs to the WebSite bin folder), and open your browser. Navigate to http://localhost/helloworld/index.ashx and you should see the web form:</p>
<p><img src='/images/castle-mr-hw.png' style="border:1px solid black" /></p>
<p>Type in something, then click on Show. You should see the confirmation page.</p>
<p><img src='/images/castle-mr-hw2.png' style="border:1px solid black"/></p>
<p>That’s it! Monorail works. Take a breath and let’s move on to more complex stuff.</p>
<h2>Layouts</h2>
<p>In the HelloWorld example, our view specified the entire HTML response contents. In most web applications, such an approach would not be practical. Common content such as menus, headers and footers should be maintained at a single place. Common CSS styles and JavaScript files need to be included in every page. This functionality is provided in Monorail with Layouts. A Monorail Layout is a skeleton of a set of related web pages, similar to ASP.NET master pages. So, let’s create a layout for our web site. Add a layouts folder under the views folder (that’s where Monorail looks for layouts), and then create a file called default.vm with this content:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>&lt;</span><span style='color:maroon'>html</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>head</span><span style='color:blue'>&gt;&lt;</span><span style='color:maroon'>title</span><span style='color:blue'>&gt;</span><span style='font-size:10.0pt;font-family:"Courier New"'>Evil Link v 1.0<span style='color:blue'>&lt;/</span><span style='color:maroon'>title</span><span style='color:blue'>&gt;&lt;/</span><span style='color:maroon'>head</span><span style='color:blue'>&gt;</span></span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>link</span><span style='color:blue'> </span><span style='color:red'>rel</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>stylesheet</span>&quot;<span style='color:blue'> </span><span style='color:red'>href</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>$siteRoot/views/layouts/default.css</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>body</span><span style='color:blue'>&gt;</span>
<span>      #if($message)</span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>div</span><span style='color:blue'> </span><span style='color:red'>class</span><span style='color:blue'>=</span><span style='font-size:10.0pt;font-family:"Courier New"'>&quot;<span style='color:blue'>message</span>&quot;<span style='color:blue'>&gt;</span></span>
<span>            $message</span>
<span style='color:blue'>      &lt;/</span><span style='color:maroon'>div</span><span style='color:blue'>&gt;</span>
<span>      #end</span>
<span>      #if($error)</span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>div</span><span style='color:blue'> </span><span style='color:red'>class</span><span style='color:blue'>=</span><span style='font-size:10.0pt;font-family:"Courier New"'>&quot;<span style='color:blue'>error</span>&quot;<span style='color:blue'>&gt;</span></span>
<span>            $error</span>
<span style='color:blue'>      &lt;/</span><span style='color:maroon'>div</span><span style='color:blue'>&gt;</span>
<span>      #end</span>
<span>      $childContent</span>
<span style='color:blue'>&lt;/</span><span style='color:maroon'>body</span><span style='color:blue'>&gt;</span>
<span style=' color:blue'>&lt;/</span><span style=' color:maroon'>html</span><span style=' color:blue'>&gt;</span>
</pre>
</div>
<p>There are several things to notice in this example:</p>
<ul>
<li>we can use a shorter notation for accessing PropertyBag contents if they are just a single word &mdash; just prefix the word with a dollar sign. </li>
<li>$siteRoot is a global template variable that allows us to load resources using relative paths. </li>
<li>we can use #if  #end blocks to check whether a PropertyBag message is defined.</li>
<li>$childContent is a special variable for layouts that defines where the actual view content will go</li>
</ul>
<p>This particular layout will display errors or messages passed by the controller for all actions, and it will also load the CSS rules specified in default.css in the same folder. Here is what I’ve used for the CSS rules (feel free to add your own):</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
table { border:1px solid black;}
.error { border:1px solid red; width:300px;
  padding:5px 5px 5px 5px; text-align:center;}
.message { border:1px solid black; width:300px;
  padding:5px 5px 5px 5px; text-align:center;}
</pre>
</div>
<p>To apply a layout to a controller, just add a Layout attribute to the class. For example, add [Layout("default")] to the HelloWorldController to use the “default” layout.</p>
<h2>Working with session objects</h2>
<p>We need to know whether a user is logged in or not logged in in our application. For that, I typically use the HTTP session object (Yes, .NET also has the Principal object that might be better for this purpose, but we’ll use the session to show how to work with some other integrations later as well). In the controller class, you can use the Session property to access the HTTP session, but I do not like such uncontrolled global access to session variables (<a href="http://gojko.net/2008/05/05/put-the-web-server-on-a-diet-and-increase-scalability/">I wrote about that last week</a>). So instead of having controllers manipulate the session directly, let’s encapsulate session access into a class and then have controllers use that instead. Because we do not have access to the Monorail context in a standalone class, we can use System.Web.HttpContext.Current to get to the current HTTP request context. Here is the session context wrapper class:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> System.Web;</span>
<span style='color:blue'>using</span><span> EvilLink.Database;</span>
<span>&nbsp;</span>
<span style='color:blue'>namespace</span><span style=''> EvilLink.Controllers</span>
<span>{  </span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>UserContext</span></span>
<span>    {</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>int</span>? CurrentUserId</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> System.Web.<span style='color:teal'>HttpContext</span>.</span>
<span>                    Current.Session[<span style='color:maroon'>&quot;currentUserId&quot;</span>] <span style='color:blue'>as</span> <span style='color:blue'>int</span>?; }</span>
<span>            <span style='color:blue'>set</span> { System.Web.<span style='color:teal'>HttpContext</span>.</span>
<span>                Current.Session[<span style='color:maroon'>&quot;currentUserId&quot;</span>] = <span style='color:blue'>value</span>; }</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:teal'>User</span> CurrentUser</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> <span style='color:teal'>User</span>.Find(CurrentUserId); }</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<h2>The User Operation Controller</h2>
<p>For this example, we want to display the login form with a link for registration to users that are not yet logged in. They can then log in (let’s just display a confirmation message after they log in for now) or follow the registration link to get to the registration form, where they will be able to fill in their details and register. After the registration, let’s also just display a confirmation message for now. On the end, let’s also allow people to log out. So we have five actions for our controller (and five corresponding methods):</p>
<ul>
<li>Displaying login form (let’s call this Index)</li>
<li>Processing login details (let’s call this Login)</li>
<li>Logging out (let’s call this Logout)</li>
<li>Displaying the registration form (let’s call this Register)</li>
<li>Processing registration details (let’s call this SubmitRegistration)</li>
</ul>
<h2>Chaining actions and the Flash</h2>
<p><img src="/images/flash50.jpg" style="margin:5px 5px 5px 5px" align="right" />In the HelloWorld example, the view template file name was taken from the method name. This is one more example of promoting convention over configuration. However, that is not always practical. Some actions will have to display the same view. For example, if a user tries to register with invalid details or the requested username is already taken, we should display the registration form again. That form is already displayed by the Register view, and there is no need to duplicate the code.</p>
<p>Monorail controller does not need to execute the same view every time. By default, the view name is taken from the action name. The view name can also be explicitly set using the RenderView method. You can also call one action method from another, but the default view will still be the same as the first method called. A controller action can also issue a redirect command, that sends the user to another action (or another controller). The redirect will be executed using the HTTP redirection method. So, for example, if the SubmitRegistration method calls the Register method directly, than those two would be executed as part of the same HTTP request (and the SubmitRegistration view would be rendered on the end, unless explicitly specified otherwise). If the SubmitRegistration method calls RedirectToAction (“register”) then the client would get a HTTP redirect message, the browser would make another request for the Register action, and the Register method would be called (rendering the Register view unless specified differently). Here is a short summary of what happens in several different cases when we chain parts of the Redirect and Index actions:</p>
<table style='border:1px solid black;' valign="top">
<tr>
<td style='border-bottom:1px solid black;' valign="top">Call within the SubmitRegistration method</td>
<td style='border-bottom:1px solid black;' valign="top">Number of Http requests</td>
<td style='border-bottom:1px solid black;' valign="top">	Register() body executed</td>
<td style='border-bottom:1px solid black;' valign="top">Rendered view</td>
</tr>
<tr>
<td>Register()</td>
<td>One</td>
<td>Yes</td>
<td>SubmitRegistration</td>
</tr>
<tr>
<td>RenderView(“register”)</td>
<td>One</td>
<td>No</td>
<td>Register</td>
</tr>
<tr>
<td>RedirectToAction(“register”)</td>
<td>two</td>
<td>Yes</td>
<td>Register</td>
</tr>
</table>
<p>If the Register method is called directly, or if the register view is rendered in the SubmitRegistration method, the PropertyBag context set by the SubmitRegistration method would available to the final view as well. In the third case, where we have two HTTP requests, it would be lost. If we wanted to make some data available to the view for the next request, we could use the HTTP session. There is also a much simpler way to do it if we only want to keep it for the next request, not for any subsequents requests after that. The Monorail Flash object is used to store information between requests in a sequence. For example, we can set an error message and redirect to a different action like this:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span>Flash[<span style='color:maroon'>&quot;error&quot;</span>] = <span style='color:maroon'>&quot;Username or password incorrect, please try again&quot;</span>;</span>
<span>RedirectToAction(<span style='color:maroon'>&quot;index&quot;</span>);</span>
</pre>
</div>
<p>When the Index method gets called in the subsequent request, &#8220;Username or password incorrect, please try again&#8221; will be available directly to the view under the name &#8220;error&#8221;. The index page could display the error message and then the login form. This is a good way to provide feedback to users without introducing additional workflow. We can also access the Flash contents using a standard $Flash variable (eg $Flash.message would print out the &#8220;message&#8221; key from the Flash). </p>
<p>Armed with all this knowledge, we can now write the user operation controller. Add this class to the EvilLink.Controllers project:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span style='color:blue'>using</span><span> EvilLink.Database;</span>
<span>&nbsp;</span>
<span style='color:blue'>namespace</span><span> EvilLink.Controllers</span>
<span>{</span>
<span>    [<span style='color:teal'>Layout</span>(<span style='color:maroon'>&quot;default&quot;</span>)]</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>UserOpsController</span> : <span style='color:teal'>SmartDispatcherController</span></span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>UserContext</span> context=<span style='color:blue'>new</span> <span style='color:teal'>UserContext</span>(); </span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Index()</span>
<span>        {</span>
<span>            <span style='color:blue'>if</span> (context.CurrentUserId != <span style='color:blue'>null</span>)</span>
<span>            {</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;error&quot;</span>] </span>
<span>                 = <span style='color:maroon'>&quot;You are already logged in. Please log out&quot;</span>;</span>
<span>            }</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Login(<span style='color:teal'>String</span> username, <span style='color:teal'>String</span> password)</span>
<span>        {</span>
<span>            <span style='color:teal'>User</span> u = <span style='color:teal'>User</span>.Login(username, password);</span>
<span>            <span style='color:blue'>if</span> (u != <span style='color:blue'>null</span>)</span>
<span>            {</span>
<span>                context.CurrentUserId = u.Id;</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;user&quot;</span>] = context.CurrentUser;</span>
<span>                RenderView(<span style='color:maroon'>&quot;postlogin&quot;</span>);</span>
<span>            }</span>
<span>            <span style='color:blue'>else</span></span>
<span>            {</span>
<span>                Flash[<span style='color:maroon'>&quot;error&quot;</span>] = <span style='color:maroon'>&quot;Username or password incorrect,&quot;+</span>
<span>                 &quot; please try again&quot;</span>;</span>
<span>                RedirectToAction(<span style='color:maroon'>&quot;index&quot;</span>);</span>
<span>            }</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Logout()</span>
<span>        {</span>
<span>            context.CurrentUserId = <span style='color:blue'>null</span>;</span>
<span>            RenderView(<span style='color:maroon'>&quot;index&quot;</span>);</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Register()</span>
<span>        {</span>
<span>            PropertyBag[<span style='color:maroon'>&quot;user&quot;</span>] = <span style='color:blue'>new</span> <span style='color:teal'>User</span>();</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> SubmitRegistration([<span style='color:teal'>DataBind</span>(<span style='color:maroon'>&quot;user&quot;</span>)] <span style='color:teal'>User</span> user)</span>
<span>        {</span>
<span>            <span style='color:blue'>if</span> (!user.IsValid())</span>
<span>            {</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;error&quot;</span>] = <span style='color:teal'>String</span>.Join(<span style='color:maroon'>&quot;, &quot;</span>,</span>
<span>                    user.ValidationErrorMessages);</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;user&quot;</span>] = user;</span>
<span>                RenderView(<span style='color:maroon'>&quot;register&quot;</span>);</span>
<span>                <span style='color:blue'>return</span>;</span>
<span>            }</span>
<span>            <span style='color:blue'>try</span></span>
<span>            {</span>
<span>                user.CreateAndFlush();</span>
<span>                Flash[<span style='color:maroon'>&quot;message&quot;</span>] = <span style='color:maroon'>&quot;You have registered successfully. &quot;+</span>
<span>                 &quot;You can now log in.&quot;</span>;</span>
<span>                RedirectToAction(<span style='color:maroon'>&quot;index&quot;</span>);</span>
<span>            }</span>
<span>            <span style='color:blue'>catch</span> (<span style='color:teal'>Exception</span> e)</span>
<span>            {</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;error&quot;</span>] = e.Message;</span>
<span>                Logger.Error(<span style='color: maroon'>&quot;error during registration&quot;</span>, e);</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;user&quot;</span>] = user;</span>
<span>                RenderView(<span style='color:maroon'>&quot;register&quot;</span>);</span>
<span>            }</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>Before we continue with the views, notice that we are using the Flash to pass error messages or notifications before redirecting to other actions, and that we are directly setting the PropertyBag error and message keys when the view is getting rendered in the same request. Also, notice how we use the logging facility: the Logger property is available to you if you extend SmartDispatcherController, and it will use Monorail’s logging (you can set this up to be either Log4Net or NLog), but the code stays the same. </p>
<p>A very important line to look at is the SubmitRegistration method header. Monorail can load complete objects for you, not just simple properties. To do that, you have to add the DataBind attribute to the argument. Unfortunately, in this case Monorail does not use convention over configuration, so you will have to specify the parameter name as well. The value from the DataBind attribute is used like a prefix to map request parameters to object properties. In this case, the request parameter user_username would be mapped to the Username property of the method argument. Because we map the request arguments directly to a Monorail class, we can check whether the user details are valid and try to create a new user in only a few lines of code. </p>
<h2>User operation views</h2>
<p>The UserOpsController uses three views. Index is used to display the login form. Postlogin is used to greet the user after logging in, and register displays the registration form. Notice that there is no Postlogin method, and that the SubmitRegistration method does not have a view named after it. </p>
<p>The index view is the simplest. It should just display the login form and a link for registration. Remember that any errors or notification messages will be handled by the layout directly. Here is the index.vm file:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
Please log in
&lt;br/&gt;
&lt;table&gt;
&lt;form method=&quot;post&quot; action=&quot;login.ashx&quot;&gt;
&lt;tr&gt;&lt;td&gt;Username&lt;/td&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;username&quot;/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Password&lt;/td&gt;&lt;td&gt;&lt;input type=&quot;password&quot; name=&quot;password&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;input type=&quot;submit&quot; value=&quot;Log In&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/form&gt;
&lt;/table&gt;
&lt;br/&gt;
if you do not have an account, &lt;a href="register.ashx"&gt;register&lt;/a&gt; now
</pre>
</div>
<p>As mentioned before, you can use more complex objects directly in the PropertyBag. After a user successfully logs in, we store the whole user object in the PropertyBag to give our view the choice to display anything it sees fit. Remember, the controller should only coordinate actions and make the appropriate data available to the view, not decide what gets displayed or how. Here is postlogin.vm, that in this case greets the user by his name:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
You are logged in as ${user.Name}. &lt;a href="logout.ashx"&gt;Log out&lt;/a&gt;.
</pre>
</div>
<p>The register.vm view introduces a new concept. We want to reduce code duplication, and we want to display the same form to the user when they first try to register, but also when they tried to register with invalid data. Monorail uses something similar to Rails helpers here, and allows us to quickly build such forms. Here is what register.vm looks like:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
&lt;h1&gt;Register as a new user&lt;/h1&gt;
&lt;form method=&quot;post&quot; action=&quot;submitregistration.ashx&quot;&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;Username&lt;/td&gt;&lt;td&gt;$FormHelper.TextField(&quot;user.username&quot;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Password&lt;/td&gt;&lt;td&gt;$FormHelper.PasswordField(&quot;user.password&quot;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;E-mail&lt;/td&gt;&lt;td&gt;$FormHelper.TextField(&quot;user.email&quot;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Name&lt;/td&gt;&lt;td&gt;$FormHelper.TextField(&quot;user.name&quot;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;input type=&quot;submit&quot; name=&quot;Register&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;/form&gt;
</pre>
</div>
<p>Instead of typing in field names directly and checking whether the $user object has appropriate fields, we can use the $FormHelper variable to quickly script the user form. See <a href="http://www.castleproject.org/monorail/documentation/trunk/helpers/form/index.html" target="_blank">the FormHelper page</a> in Castle documentation for more information on this tool.</p>
<h2>The finishing touch</h2>
<p>We are almost done. Let’s make the browsing experience a bit better by presenting the users with a login form when they browse to the web site homepage. There are two ways to do this: either map all IIS requests to .NET and then set up Monorail to handle requests without an extension. Another, that is in my mind simpler, is to create an ASP.NET default page that redirects to the appropriate controller action. So let’s add this as the Default.aspx page to the web site:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
&lt;%@ Page Language="C#" %&gt;
&lt;%
	Response.Redirect("/userops/index.ashx");
%&gt;
</pre>
</div>
<p>You can now recompile the project, browse to the homepage of your localhost site, and you should see the login form. Try to register, log in and out. Note that you can change the layout and view files without recompiling or restarting the web site. You only need to recompile the projects after modifying the controller code. </p>
<p>You can download the source code for this example from <a href="http://gojko.net/resources/EvilLink_i2.zip">http://gojko.net/resources/EvilLink_i2.zip</a> </p>
<h2>Key stuff to remember</h2>
<ul>
<li>The Model-View-Controller pattern requires a clear separation of responsibilities between the domain business logic (model), workflow (controller) and the actual user interface (view).</li>
<li>ActiveRecord must be properly initialised in the Application OnLoad event. The easiest way to do that is to extend the HTTPApplication object and just load ActiveRecord configuration from web.config. </li>
<li>SmartDispatcherController maps web folders to class names, web file names to methods and web parameters to request arguments. It works with both simple and complex objects, but complex objects require the DataBind attribute as well.</li>
<li>PropertyBag contents are passed to the view, and the view should decide what to actually display.</li>
<li>Monorail layouts are templates that specify common parts of a set of pages. Use the Layout attribute on the controller to specify which layout template should be used.</li>
<li>Use the Flash object to transfer messages when redirecting to a different action.</li>
<li>$FormHelper allows us to quickly script HTML forms.</li>
<li>ActiveRecord is probably not the best choice for the model for complex applications, because it is a mix of domain logic and storage. Monorail integration features, however, make it an interesting choice for simpler applications. </li>
</ul>
<h2>Next exercise</h2>
<p>In the next part of this tutorial, we build web pages to manage links, which allows us to see how ActiveRecord and Monorail work together effectively. We also introduce Monorail rescues and page components. I will post the next part on this web site early next week. You can subscribe to <a href="http://gojko.net/feed">RSS</a> updates to get a notification when the next part is online. I will be discussing this demo application and several upcoming articles of this series this week in London on a workshop on <a target="_blank" href="http://www.skillsmatter.com/event/open-source-dot-net/agile-web-development-with-the-castle-framework">Agile Web development with Castle</a>. After the talk, we will meet up with the ALT.NET enthusiasts for <a href="http://gojko.net/2008/05/03/altnet-beers-after-the-castle-session/">beers</a>. </p>
<p>Image Credits: <a href="http://www.sxc.hu/profile/kasko" target="_blank">Igor Kasalovic</a></p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/05/13/castle-demo-app-2-monorail-basics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Castle demo app: ActiveRecord basics and unit testing</title>
		<link>http://gojko.net/2008/05/07/castle-demo-app-activerecord-basics-and-unit-testing/</link>
		<comments>http://gojko.net/2008/05/07/castle-demo-app-activerecord-basics-and-unit-testing/#comments</comments>
		<pubDate>Wed, 07 May 2008 14:57:18 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[alt.net]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=124</guid>
		<description><![CDATA[Castle project is a great .NET enterprise application framework. It helps us develop .NET applications and web sites by providing the plumbing and making it easy to test the most important parts of the system. I’ve decided to build a demo application with the Castle project for an internal training session, to show how easy [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.castleproject.org" target="_blank">Castle project</a> is a great .NET enterprise application framework. It helps us develop .NET applications and web sites by providing the plumbing and making it easy to test the most important parts of the system. I’ve decided to build a demo application with the Castle project for an internal training session, to show how easy it is to work with this framework and to demonstrate the best practices. I will post the  tutorial in parts on this web site as I develop it. In the first post, we work on the object-relational mapping with ActiveRecord and write unit tests for the database mapping layer.<span id="more-124"></span></p>
<p>Here is the stuff that you’ll need to run these examples:</p>
<ul>
<li><a href="http://www.microsoft.com/sql/editions/express/default.mspx<br />
" target="_blank">SQL Server Express 2005</a> or some other database</li>
<li><a href="http://msdn.microsoft.com/netframework/" target="_blank">.NET framework 2 or later</a></li>
<li>Visual Studio 2005 or later – you can get <a href="http://www.microsoft.com/express/vcsharp/">download the Express version</a> free</li>
<li>The latest binary release of the <a href="http://www.castleproject.org/castle/download.html">Castle Project</a> libraries</li>
<li><a href="http://nunit.org/index.php">NUnit</a> unit testing framework for .NET</li>
<li><a href="/resources/EvilLink_i1.zip">source code</a> for this example</li>
</ul>
<h2>Introducing EvilLink</h2>
<p>We&#8217;ll build an online bookmarking application, called it EvilLink. Here are the user stories that we will develop:</p>
<ol>
<li>As a site owner, I want users to register and leave their e-mail address so that I can spam them later (hence the app name).</li>
<li>As a user, I want to record my web links online, so that I can access them from anywhere.</li>
<li>As a user, I want to review the links that I previously recorded so that I can visit the interesting sites.</li>
<li>As a user, I want to edit details and descriptions of the links that I previously recorded, so that I can keep them up to date.</li>
</ol>
<p><br clear="all"/></p>
<p>This will be a rather simplistic web application, but it will allow us to try out the most important features of all three main components of the Castle project: the ActiveRecord object-relational mapping tool, the Monorail web model-view-controller framework and the Windsor dependency injection container. We will develop this application with full test support, meaning that our goal is to cover everything below the UI surface with unit tests.</p>
<h2>Story 1: User registration</h2>
<p>To implement this story, we’ll create a User object, connect it to the database, make sure that the ORM system works, and then build a simple Web site on top of that. During this exercise, we show how straightforward it is to use ActiveRecord. In the next one, we work on the basic layout of a Monorail web site and show the way that controllers handle incoming requests to complete the first user story.</p>
<h3>The User object</h3>
<p>Let’s first create the User class and related database mappings. Create a new solution for this project  in Visual Studio, and open a new project called EvilLink.Database. We’ll put database-related objects there. </p>
<p>ActiveRecord is a software architectural pattern that maps objects directly to table rows, and object properties to table columns. This pattern combines domain logic and data, providing easy persistence but not a very nice separation of responsibilities. For more information on this pattern, see Martin Fowler’s <a href='http://www.martinfowler.com/eaaCatalog/activeRecord.html' target='_blank'> Patterns of Enterprise Application Architecture</a> page.</p>
<p>Under the hood, Castle’s ActiveRecord uses NHibernate, but with almost no configuration. In general, preferring convention over configuration is one of the best things about the Castle framework. Instead of an external mapping file, ActiveRecord requires that we put a few attributes on the class. For start, the entire class should be marked with <code>[ActiveRecord]</code>. Persistent properties should be marked as [Property], and the class must have a numeric primary identifier, marked as <code>[PrimaryKey]</code>. Although it can work on plain CLR classes (the only requirement is a default public constructor without arguments), ActiveRecord also has a few utility base classes that you can extend. ActiveRecordBase supplies a bunch of useful finders and actions. ActiveRecordValidationBase integrates with the Castle component validator framework, and provides instant validation features. That means that you can annotate your properties with validation rules, and the object itself will refuse to save or update the database if it is invalid. It also gives you nice validation error messages if the object is not valid, ready to be displayed to the end users. Standard validators include checking whether an attribute is unique, not empty, formatted like an e-mail and a number of other similar actions. For a full list, see the <a target="_blank" href='http://api.castleproject.org/html/N_Castle_Components_Validator.htm'>Castle Components Validator</a> documentation. If you make a mistake in the attribute annotations, you will not get a compilation error. Problems like that don’t even pop up when the classes are loaded, but come up when you try to use the class with a misleading message like “ActiveRecordStarter.initialise call was not executed with the type”. Remember to double-check the public constructor and class and property annotations if you get that exception.</p>
<p>We’ll use this to validate that the username is unique, that the e-mail is in the correct format and that the user’s name is not empty.</p>
<p>All ActiveRecord attributes are in the Castle.ActiveRecord namespace. Validation attributes are in the Castle.Components.Validator namespace. Add references to Castle.Core.dll, Castle.ActiveRecord.dll and Castle.Components.Validator.dll and create the User class:</p>
<div style='margin-bottom:10pt'>
<pre style='font-size:10.0pt;font-family:Courier New;'>
<span style='color:blue'>using</span> <span>System;</span>
<span style='color:blue'>using</span> <span>Castle.ActiveRecord;</span>
<span style='color:blue'>using</span> <span>Castle.Components.Validator;</span>
<span style='color:blue'>namespace</span> <span>EvilLink.Database</span>
<span>{</span>
<span>    [<span style='color:teal'>ActiveRecord</span>]</span>
<span>    <span style='color:blue'>public</span><span style='color:blue'>class</span> <span style='color:teal'>User</span> : <span style='color:teal'>ActiveRecordValidationBase</span>&lt;<span style='color:teal'>User</span>&gt;</span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:blue'>int</span> id;</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>String</span> username;</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>String</span> password;</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>String</span> email;</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>String</span> name;</span>
<span>&nbsp;</span>
<span>        <span style='color:blue'>public</span> User()</span>
<span>        {</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> User(<span style='color:blue'>string</span> name, <span style='color:blue'>string</span> username, <span style='color:blue'>string</span> password, <span style='color:blue'>string</span> email)</span>
<span>        {</span>
<span>            <span style='color:blue'>this</span>.username = username;</span>
<span>            <span style='color:blue'>this</span>.password = password;</span>
<span>            <span style='color:blue'>this</span>.email = email;</span>
<span>            <span style='color:blue'>this</span>.name = name;</span>
<span>        }</span>
<span>&nbsp;</span>
<span>        [<span style='color:teal'>PrimaryKey</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>int</span> Id</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> id; }</span>
<span>            <span style='color:blue'>set</span> { id = <span style='color:blue'>value</span>; }</span>
<span>        }</span>
<span>        [<span style='color:teal'>Property</span>]</span>
<span>        [<span style='color:teal'>ValidateIsUnique</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>string</span> Username</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> username; }</span>
<span>            <span style='color:blue'>set</span> { username = <span style='color:blue'>value</span>; }</span>
<span>        }</span>
<span>        [<span style='color:teal'>Property</span>]</span>
<span>        [<span style='color:teal'>ValidateNonEmpty</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>string</span> Name</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> name; }</span>
<span>            <span style='color:blue'>set</span> { name= <span style='color:blue'>value</span>; }</span>
<span>        }</span>
<span>        [<span style='color:teal'>Property</span>]</span>
<span>        [<span style='color:teal'>ValidateNonEmpty</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>string</span> Password</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> password; }</span>
<span>            <span style='color:blue'>set</span> { password = <span style='color:blue'>value</span>; }</span>
<span>        }</span>
<span>        [<span style='color:teal'>Property</span>]</span>
<span>        [<span style='color:teal'>ValidateEmail</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>string</span> Email</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> email; }</span>
<span>            <span style='color:blue'>set</span> { email = <span style='color:blue'>value</span>; }</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>override</span> <span style='color:blue'>bool</span> Equals(<span style='color:blue'>object</span> obj)</span>
<span>        {</span>
<span>            <span style='color:teal'>User</span> us=obj <span style='color:blue'>as</span> <span style='color:teal'>User</span>;</span>
<span>            <span style='color:blue'>if</span> (us == <span style='color:blue'>null</span>) <span style='color:blue'>return</span> <span style='color:blue'>false</span>;</span>
<span>            <span style='color:blue'>return</span> us.id == <span style='color:blue'>this</span>.id;</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>override</span> <span style='color:blue'>int</span> GetHashCode()</span>
<span>        {</span>
<span>            <span style='color:blue'>return</span> id.GetHashCode();</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>override</span> <span style='color:blue'>string</span> ToString()</span>
<span>        {</span>
<span>            <span style='color:blue'>return</span> <span style='color:maroon'>&quot;Userid=&quot;</span> + id;</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>And that’s more or less everything about the database mapping. ActiveRecord will create all the SQL commands automatically. It can even create the database schema. The only thing left is to point it to the correct database.</p>
<h3>Step 2: Verifying that the model works</h3>
<p>To verify that our new User object works correctly, let’s write a unit test (of course, some purists will now note that I should be writing unit tests before the production code, but it’s a bit hard to explain things in that order. In any case, the User class is fairly simple and contains no business logic, so it is not such a sin to write the unit test after the class. When we build in more business logic later, we’ll do it properly). </p>
<p>Let’s create a new project for database tests, and call it EvilLink.Database.Test. Add references to the three Castle libraries as in the Database project, then also add a reference to the EvilLink.Database project and to NUnit.Framework.dll and NHibernate.dll (you’ll find them in the dependencies zip file in the Castle release). </p>
<p>To connect the User class to the database, we need to initialise ActiveRecord framework by telling it the database configuration. Castle.ActiveRecord.ActiveRecordStarter class is used for that. We need to call the Initialise method and pass the configuration file and list of record classes. We can load the configuration from an Application.Config file or from an external file. Because we want to run this inside the NUnit test runner, let’s use an external file. Theoretically, we can send a list of record classes to the ActiveRecordStarter, but we can also supply the whole assembly and let it find all relevant classes itself. Here are the two lines that prepare our ORM layer:</p>
<div style='margin-bottom:10pt'>
<pre style='font-size:10.0pt; font-family:Courier New;'>
<span style='color:teal'>IConfigurationSource</span>source = <span style='color:blue'>new</span> <span style='color:teal'>XmlConfigurationSource</span>(
  <span style='color:maroon'>&quot;ActiveRecordConfig.xml&quot;</span>);
<span style='color:teal'>ActiveRecordStarter</span>.Initialize(<span style='color:teal'>Assembly</span>.GetAssembly(
  <span style='color:blue'>typeof</span>(EvilLink.Database.<span style='color:teal'>User</span>)), source);
</pre>
</div>
<p>Having a dedicated assembly for record classes will make it easier to load and initialise the records appropriately. Avoid putting a lot of non-record classes in such assemblies, because ActiveRecordStarter will have to analyse all the classes in the assembly.</p>
<p>ActiveRecordStarter contains a bunch of other useful methods, most importantly CreateSchema and DropSchema that will <i>try</i> to create or delete the relevant database objects. I emphasised <i>try</i> because there are some interesting bugs in this that prevent correct initialisation of many-to-many mappings in SQL Server. For now, we’ll use this functionality. Later on, if you find that it starts causing you problems, create the schema yourself. ActiveRecordStarter normally allows you to initialise it only once during an application. For unit tests, we want to drop and recreate the schema before every test to avoid dependencies, so we’ll need to tell it to ignore this security check by calling ResetInitializationFlag.</p>
<p>As most ORM tools, ActiveRecord uses the concept of session scopes to reduce database communication and ensure data consistency. All operations on record objects should be performed within a session scope, and the changes are persisted in the database when the session is flushed or the scope ends. In the context of unit tests, it makes sense to automatically create a scope before tests and discard the scope after tests. To verify persistence functionality, we can flush the session and try to load the objects from the database. </p>
<p>To make testing easier, let’s create a utility class that will take care of all ActiveRecord initialisation and session control. It will also provide a method to flush the session so that we can test persistence. Add this class to the EvilLink.Database.Test project:</p>
<div style='margin-bottom:10pt'>
<pre style='font-size:10.0pt;font-family:Courier New;'>
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> NUnit.Framework;</span>
<span style='color:blue'>using</span><span> Castle.ActiveRecord;</span>
<span style='color:blue'>using</span><span> Castle.ActiveRecord.Framework;</span>
<span style='color:blue'>using</span><span> Castle.ActiveRecord.Framework.Config;</span>
<span style='color:blue'>using</span><span> System.Reflection;</span>
<span style='color:blue'>namespace</span><span style='font-size:10.0pt;'> EvilLink.Database.Test</span>
<span>{</span>
<span>    <span style='color:green'>// not a test fixture, it should not be invoked directly</span></span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>abstract</span> <span style='color:blue'>class</span> <span style='color:teal'>ARTestBase</span></span>
<span>    {</span>
<span>        <span style='color:blue'>protected</span> <span style='color:teal'>SessionScope</span> scope;</span>
<span>&nbsp;</span>
<span>        [<span style='color:teal'>TestFixtureSetUp</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> InitialiseAR()</span>
<span>        {</span>
<span>            <span style='color:teal'>ActiveRecordStarter</span>.ResetInitializationFlag();</span>
<span>            <span style='color:teal'>IConfigurationSource</span> source = <span style='color:blue'>new</span> </span>
<span>              <span style='color:teal'>XmlConfigurationSource</span>(<span style='color:maroon'>&quot;ActiveRecordConfig.xml&quot;</span>);</span>
<span>            <span style='color:teal'>ActiveRecordStarter</span><span>.Initialize(</span>
<span>              <span style='color:teal'> Assembly</span><span>.GetAssembly(<span style='color:blue'>typeof</span>(EvilLink.Database.<span style='color:teal'>User</span>)),</span>
<span>              <span>source);</span>
<span>        }</span>
<span>        [<span style='color:teal'>SetUp</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>virtual</span> <span style='color:blue'>void</span> SetUp()</span>
<span>        {</span>
<span>            <span style='color:teal'>ActiveRecordStarter</span>.DropSchema();</span>
<span>            <span style='color:teal'>ActiveRecordStarter</span>.CreateSchema();</span>
<span>            scope = <span style='color:blue'>new</span> <span style='color:teal'>SessionScope</span>();</span>
<span>        }</span>
<span>        [<span style='color:teal'>TearDown</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>virtual</span> <span style='color:blue'>void</span> TearDown()</span>
<span>        {</span>
<span>            scope.Dispose();</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Flush()</span>
<span>        {</span>
<span>            scope.Flush();</span>
<span>            scope.Dispose();</span>
<span>            scope = <span style='color:blue'>new</span> <span style='color:teal'>SessionScope</span>();</span>
<span>        }</span>
<span>       </span>
<span>    }</span>
<span>}</span>
</span></span></span>
</pre>
</div>
<p>We now need to supply the database configuration to ActiveRecord. Create a file called ActiveRecordConfig.xml in the project, and use this as a template:</p>
<div style='margin-bottom:10pt'>
<pre style='font-size:10.0pt;font-family:Courier New;'>
<span style='color:blue'>&lt;?</span><span style='color:maroon'>xml</span><span style='color:blue'> </span><span style='color:red'>version</span><span style='color:blue'>=</span><span style=''>&quot;<span style='color:blue'>1.0</span>&quot;<span style='color:blue'> </span><span style='color:red'>encoding</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>utf-8</span>&quot;<span style='color:blue'> ?&gt;</span></span>
<span style=' color:blue'>&lt;</span><span style='color:maroon'>activerecord</span><span style='color:blue'> </span><span style='color:red'>isWeb</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>false</span>&quot;<span style='color:blue'> </span><span style='color:red'>pluralizeTableNames</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>true</span>&quot;<span style='color:blue'>&gt;</span></span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>config</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>key</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>hibernate.connection.driver_class</span>&quot;
<span style='color:red'>              value</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>NHibernate.Driver.SqlClientDriver</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>key</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>hibernate.dialect</span>&quot;
<span style='color:red'>              value</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>NHibernate.Dialect.MsSql2005Dialect</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>key</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>hibernate.connection.provider</span>&quot;
<span style='color:red'>              value</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>NHibernate.Connection.DriverConnectionProvider</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>      &lt;</span><span style='color:maroon'>add</span><span style='color:blue'> </span><span style='color:red'>key</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>hibernate.connection.connection_string</span>&quot;
<span style='color:red'>              value</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>Data Source=.\SQLEXPRESS;Initial Catalog=castletest;
user id=castletest;password=castletest</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>&lt;/</span><span style='color:maroon'>config</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>&lt;/</span><span style='color:maroon'>activerecord</span><span style='color:blue'>&gt;</span>
</pre>
</div>
<p>This example connects to a SQLExpress database on the local machine (.\SQLEXPRESS) under the credentials of user castletest with the password castletest, and selects castletest as the starting database. So either create that on your local instance, or enter different connection details in the connection_string property. To use a different type of database, see the ActiveRecord <a href=’ http://www.castleproject.org/activerecord/documentation/trunk/manual/xmlconfigref.html’>configuration reference</a>. Just remember to keep <i>isWeb=&#8221;false&#8221; pluralizeTableNames=&#8221;true&#8221;</i> in the activerecord element. The first attribute tells ActiveRecord not to use automatic thread/transaction management and the other makes sure that the User objects are saved in the <code>users</code> table (otherwise you will get an error because User is a keyword in SQL Server). Right click on the file, select properties, and then choose “Copy always” as the “Copy to Output Directory” option to make sure that this configuration file is available at runtime when we need it.</p>
<p>Now, let’s write the unit test. Create a UserTests class and check whether we can register a user and whether the validations work correctly:</p>
<div style='margin-bottom:10pt'>
<pre style='font-size:10.0pt;font-family:Courier New;'>
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> NUnit.Framework;</span>
<span style='color:blue'>using</span><span> Castle.ActiveRecord;</span>
<span style='color:blue'>using</span><span> Castle.ActiveRecord.Framework;</span>
<span style='color:blue'>using</span><span> Castle.ActiveRecord.Framework.Config;</span>
<span>&nbsp;</span>
<span style='color:blue'>namespace</span><span style='font-size: 10.0pt;font-family:"Courier New"'> EvilLink.Database.Test</span>
<span>{</span>
<span>    [<span style='color:teal'>TestFixture</span>]</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>UserTests</span> : <span style='color:teal'>ARTestBase</span></span>
<span>    {</span>
<span>        [Test]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> TestInvalidFormatEmail()</span>
<span>        {</span>
<span>            <span style='color:teal'>User</span> u = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;Mike Smith&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass123&quot;</span>, <span style='color: maroon'>&quot;mike-mike.com&quot;</span>);</span>
<span>            <span style='color:teal'>Assert</span>.IsFalse(u.IsValid());</span>
<span>            <span style='color:blue'>try</span></span>
<span>            {</span>
<span>                u.Save();</span>
<span>                <span style='color:teal'>Assert</span>.IsFalse(<span style='color:blue'>true</span>, <span style='color:maroon'>&quot;invalid password object saved&quot;</span>);</span>
<span>            }</span>
<span>            <span style='color:blue'>catch</span> (<span style='color:teal'>Exception</span>)</span>
<span>            {</span>
<span>            }</span>
<span>        }</span>
<span>        [Test]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> TestNonUniqueUsername()</span>
<span>        {</span>
<span>            <span style='color:teal'>User</span> u = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;Mike Smith&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass123&quot;</span>, <span style='color: maroon'>&quot;mike@mike.com&quot;</span>);</span>
<span>            u.Save();</span>
<span>            Flush();</span>
<span>            u = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;Tom Smith&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;tpass123&quot;</span>, <span style='color:maroon'>&quot;tom@mike.com&quot;</span>);</span>
<span>            <span style='color:teal'>Assert</span>.IsFalse(u.IsValid());</span>
<span>            <span style='color:blue'>try</span></span>
<span>            {</span>
<span>                u.Save();</span>
<span>                <span style='color:teal'>Assert</span>.IsFalse(<span style='color:blue'>true</span>, <span style='color:maroon'>&quot;duplicate username object saved&quot;</span>);</span>
<span>            }</span>
<span>            <span style='color:blue'>catch</span> (<span style='color:teal'>Exception</span>)</span>
<span>            {</span>
<span>            }</span>
<span>        }</span>
<span>        [Test]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> TestAddingUsers()</span>
<span>        {</span>
<span>            <span style='color:teal'>User</span> u = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;Mike Smith&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass123&quot;</span>, <span style='color: maroon'>&quot;mike@mike.com&quot;</span>);</span>
<span>            u.Save();</span>
<span>            Flush();</span>
<span>            <span style='color:teal'>User</span>[] fromDb = <span style='color:teal'>User</span>.FindAllByProperty(<span style='color:maroon'>&quot;Username&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>);</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(1, fromDb.Length);</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(<span style='color:maroon'>&quot;mike@mike.com&quot;</span>, fromDb[0].Email);</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>Compile the solution, and run the test with NUnit. It should confirm that the database mapping works correctly.</p>
<p><img src='/images/castle-nunit-db-small.png' style='border:1px solid black' /></p>
<p>You can also check the database directly, Mike should be there:</p>
<p><img src='/images/castle-sql-1.png' style='border:1px solid black' /></p>
<p>You can download the source code for this example from <a href="/resources/EvilLink_i1.zip">http://gojko.net/resources/EvilLink_i1.zip</a> </p>
<h2>Key stuff to remember:</h2>
<ul>
<li>the record class needs to be annotated with the [ActiveRecord] attribute, be public, have a no-parameter public constructor. Otherwise loading fails, but you don&#8217;t get an error at that point &mdash; you will get an error later mentioning how ActiveRecordStarter.initialise call was not executed with the type. This can be a bit misleading.
</li>
<li>you need to initialise ActiveRecord and load types or whole assemblies. The best practice is to create an assembly especially for ActiveRecord types and then load that.</li>
<li>beware of using DB table/field names that are keywords (for example User in SQL Server 2005); converting table names to plurals helps to avoid some problems, but still beware that such problems can happen.</li>
<li>make sure you use ActiveRecordValidationBase if you want validations to work. Having only validation attributes on the properties is not enough.</li>
<li>Kill the initialisation flag in unit tests to allow re-initialisation</li>
<li>ActiveRecord can generate the schema for you &mdash; this is very helpful during initial stages of the project but it may not always work as expected.</li>
</ul>
<h2>Next exercise</h2>
<p>In the next part of this tutorial, we complete the first user story by developing a web page that allows people to register. I will post the next part on this web site shortly. You can subscribe to <a href="http://gojko.net/feed">RSS</a> updates to get a notification when the next part is online. If you are in UK, and want to learn more about the Castle project, drop by Skills Matter on the 15th of May for a two-hour workshop on <a target="_blank" href="http://www.skillsmatter.com/event/open-source-dot-net/agile-web-development-with-the-castle-framework">Agile Web development with Castle</a>. We are going for <a href="http://gojko.net/2008/05/03/altnet-beers-after-the-castle-session/">beers</a> after the talk.<!--more--></p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/05/07/castle-demo-app-activerecord-basics-and-unit-testing/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss>
