Tigraine

Daniel Hoelbling talks about programming

RSS Feed

Archives for Castle

FileUpload in MonoRail

0 Comments

After a stressful week of non-computer related stuff eating up my time today I finally got around to continue some work on the imagineClub website.
I approached the section of file uploads and just wanted to quickly point out an excellent post by Ken Egozi about how to properly handle file uploads with MonoRail.

FileBinderAttribute to ease FileUpload in MonoRail – by Ken Egozi

It’s really nice to see that MonoRail has File upload baked directly into the framework. It’s as easy as that:

public void Upload([DataBind("Document")] Document document, HttpPostedFile uploadedFile)
{
	if (uploadedFile != null)
	{
		//TODO: Save File to Disk, Test this properly
	}
}

But what Ken addresses is a neat way to keep this testable without obscuring the controller code.

Also, apparently Ken has written his own weblog engine ontop of MonoRail and even opensourced it for the public to look at and hopefully learn something from it. It’s really great to see real application code somewhere instead of just samples and short demos. Also from what I saw in the repository it’s not too complex to make you cry and yet real enough to show you some interesting things about MonoRail.

Filed under .NET, Castle, Coding
Jul 24, 2009

ARFetch attribute in MonoRail

1 Comment

MonoRail and ASP.NET MVC while being very different both almost mirror their features. Few things are impossible in one of both and the only really major difference between those two is that MonoRail comes packed with a suggested data access strategy: ActiveRecord.

This pre-packing is completely optional, it’s very easy to implement whatever data access logic you like, but if you choose ActiveRecord you’ll benefit from some nice things like the ARFetch attribute.

See this action method and judge for yourself:

public void Detail([ARFetch("Id")] NewsPost post)
{
    PropertyBag["post"] = post;
}

You just tell MonoRail through ARFetch what request-parameter is the object’s Id and it will fetch that entity from your DB and pass it into your method. It’s so simple that it’s almost tragic, yet it’s a huge time saver in most CRUD cases (edit, update and delete usually involve fetching the entity first).

Also, for a change, ARFetch is one of those few things inside MonoRail that needs zero documentation. It just works! (Besides the fact that you need to know it exists of course).

Filed under .NET, Castle, Coding
Jul 20, 2009

Building a databound contact form with MonoRail – Part 2: Sending Emails

0 Comments

This is part 2 of a 3 part tutorial on writing a databound contact form with Castle Monorail that gets sent off by email. We already touched FormHelpers and DataBinding in Part1: Views and Databinding, now we’ll see how easy it is to send a email template with MonoRail.

The other parts of this tutorial:

Sending Emails

We left off with a Thanks controller method that gets a ContactRequest parameter and now should send off the data by email.

1 – Configuring our Servers

Anything involving emails usually requires a SMTP server. The same thing goes for MonoRail, yet MR will default the SMTPServer setting to 127.0.0.1 if you don’t explicitly configure it through your web.config. Unfortunately for me I don’t have a SMTP server sitting on my box, so I had to change that setting through the monorail configuration node inside our web.config:

<monorail smtpHost="smtp.server.com">
  <controllers>
	  <assembly>MonoRail.ContactForm</assembly>
  </controllers>
  .
  .

You can optionally also optionally configure smtpPort, smtpUsername and smtpPassword.

2 – Sending a sample Message

We’ll jump ahead a bit and send a email message right away to verify that our settings so far have been working. Sending emails is as simple as calling the DeliverEmail method from within our Thanks controller action:

public void Thanks([DataBind("FormData")] ContactRequest request)
{
    var message = new Message
                      {
                          To = "tigraine@tigraine.at",
                          From = "tigraine@tigraine.at",
                          Subject = "Hello World",
                          Body = "My first message"
                      };
    DeliverEmail(message);
}

It’s really that easy.

3 – Templating the Message

It’s simple to send emails as seen in step 2, but having to chop strings together to send emails is just awful and error prone. Especially when you want some fancy HTML layout in your emails you’ll want to leverage the power of your ViewEngine to create the email message.

MonoRail provides such a method with it’s RenderMailMessage method. RenderMailMessage takes in a viewname, a layout and a IDictionary of parameters that will get passed on to the view.

For this simple tutorial I chose not to use a layout, so I pass in null. Also make sure you cast your Dictionary to the non-generic IDictionary since there is a little bug with the generic IDictionary overload.

public void Thanks([DataBind("FormData")] ContactRequest request)
{
    var parameters = new Dictionary<string, object>{{"request", request}};
    var message = RenderMailMessage("contact", null, (IDictionary)parameters);
    DeliverEmail(message);
}

MonoRail will look for email-templates inside the Views\mail\ folder, so we’ll add our contact.vm there:

image One thing you’ll notice immediately is that all information about from, to, subject and body have not disappeared from our action method. This data will now get extracted from the view, allowing for easy customization.

To do so we need our view to look like this:

to: tigraine@tigraine.at
from: $request.Email
subject: $request.Subject

This is where the body starts
Message from $request.Name

$request.Text

MonoRail will extract the information from the to: from: fields and use them to send the message. The above also uses the parameters we passed in to render. $request here refers to the object passed into our dictionary with name request.

If run we’ll end up with a email simiar to this:

image

4 – Testing it

Email interactions are perfect examples of stuff that goes wrong without anyone noticing. Someone does some changes in the controller and all of a sudden you don’t get those annoying contact requests for a week. Usually you blame it on a slow week and by the time you suspect something is wrong you already ignored a month of customer feedback.

To avoid this we’ll want to unit test this, and while I usually write my tests first – it’s easier to follow if you know the code under test. Testing in MonoRail is quite simple once you know where to look, unfortunately the documentation is scattered and scarce.

We’ll begin by making our testclass derive from BaseControllerTest, a class inside the Castle.MonoRail.TestSupport assembly that is used to facilitate testing.

public class ContactBehaviorTest : BaseControllerTest
{
    
}

This provides us with a neat little function that allows us to sandbox our controller called PrepareController.

Testing that a message has been rendered through the template engine would therefore look like this:

[Fact]
public void Thanks_RendersTemplatedEmail()
{
    var controller = new ContactController();
    PrepareController(controller);

    controller.Thanks(null);

    Assert.True(HasRenderedEmailTemplateNamed("contact"));
}

This test merely verifies that a template was rendered, but we probably want to verify that the view gets passed the correct arguments:

[Fact]
public void Thanks_MailRendering_ParametersGetPassed()
{
    var controller = new ContactController();
    PrepareController(controller);

    var request = new ContactRequest();
    controller.Thanks(request);

    var parameters = RenderedEmailTemplates[0].Parameters["request"];
    Assert.Same(request, parameters);
}

We now have verified that the “request” parameter object is indeed the one passed into the action method. This is not perfect since we’d just want to verify that the correct values get passed around, not references. But for this tutorial this will suffice.

Next on our checklist should be the fact that the created message is indeed sent off. We do so by using the StubEngineContext our BaseControllerTest provides us with:

[Fact]
public void Thanks_EmailSending_SendsOutOneEmail()
{
    var controller = new ContactController();
    PrepareController(controller);
    var context = (StubEngineContext)Context;

    controller.Thanks(new ContactRequest());

    Assert.Equal(1, context.MessagesSent.Count);
}

This now simply verifies that we did indeed send a mail message.

Now we have a fully working contact form that gets sent off by email through a template. We may want to protect that form from bad input by validating some of our fields. Check back tomorrow for part 3 of this tutorial.

Ps: As always the source for this tutorial is available in my BitBucket samples repository. Usually one changeset represents one tutorial step.

Filed under .NET, Castle, Coding
Jul 18, 2009

Building a databound contact form with MonoRail – Part 1: Views and Databinding

0 Comments

In this tutorial we will look the steps necessary to create a form with Castle MonoRail that then gets sent off by email. It will touch FormsHelpers, DataBinding and using the EmailTemplateService to style and EmailSender to send a message.

The tutorial will probably be split into three parts:

Views and Databinding

I assume you already have a (maybe blank) MonoRail site running, if not you could check out this changeset on my sample-repository where the MonoRail sample app is still pristine.

1 – Creating the Controller

There are two components to a contact form: The form and the thanks screen.
In MVC speech that means we’ll have one Index action just serving up the view, and one Thanks action doing the email sending / heavy lifting.
Anyway the controller for now looks fairly simple:

public class ContactController : SmartDispatcherController
{
    public void Index()
    {
        
    }
}

2 – Creating the View

image The usual routine for creating MonoRail NVelocity views applies here. The \Views\<controllername>\<actionname>.vm convention dictates that our View is called “Index.vm” and placed inside the \Views\Contact\ folder

(Btw, you probably want to tell Visual Studio to open .vm files in HTML view with Rightclick .vm file –> Open With –> select HTML Editor –> Hit Set as Default)

Inside the View we need textfields for Name, Email and Subject. And of course one big textarea for the user’s text.

We all know how HTML works: we could go ahead and build a nice accessible form by putting together <input type… tags there and hand-coding everything ourselves. Or we’d just rely on the MonoRail FormsHelper to provide methods to generate the inputs for us:

<form method="post" action="$UrlHelper.For("%{action='Thanks'}")">
<fieldset>
    <legend>Contact Form</legend>
    <ol>
        <li>$FormHelper.LabelFor("FormData.Name", "Name")
        $FormHelper.TextField("FormData.Name")</li>
        <li>$FormHelper.LabelFor("FormData.Email", "Email")
        $FormHelper.TextField("FormData.Email")</li>
        <li>$FormHelper.LabelFor("FormData.Subject", "Subject")
        $FormHelper.TextField("FormData.Subject")</li>
        <li>$FormHelper.LabelFor("FormData.Text", "Message")
        $FormHelper.TextArea("FormData.Text", "%{rows='14', cols='0'}")</li>
    </ol>
    <input type="submit" id="submit" value="Send" />
</fieldset>
</form>

Note the $FormHelper.TextField(“FormData.Name”)call that results in a <input type="text" id="FormData_Name" name="FormData.Name" value="" />. One nice side-effect of using this helper is that it will look at the current request parameters and if a FormData.Email value is set display it as the textfields value.

Also Interesting here is the syntax NVelocity uses to specify Dictionary data inside the view: “%{key=’value’}” specifies a IDictionary that gets passed off to our helpers.

3 – Creating the DTO

A contact-request is a message, so I like to have a data-object to represent that message during processing. This also makes it easier for us to retrieve the inputs sent from the Form (more on that later).

So we create a class called ContactRequest in the Models\ folder that can easily hold our form data:

namespace MonoRail.ContactForm.Models
{
    public class ContactRequest
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Subject { get; set; }
        public string Text { get; set; }
    }
}

4 – Databinding the DTO to our Form

You may have noticed that I named all TextFields in step 2 FormData.something where something corresponds to the fields inside the DTO from step 3. FormData is just a arbitrary string to prefix all of my inputs, where the latter will be used by MonoRail’s DataBinder to map the values onto my DTO.

We just need to instruct MonoRail on our action method to bind to all Query parameters starting with FormData and stuff them into our ContactRequest object. Our controller now looks like this:

public class ContactController : SmartDispatcherController
{
    public void Index()
    {
        
    }

    public void Thanks([DataBind("FormData")] ContactRequest request)
    {
        
    }
}

If we debug into this action you can see that the request parameter gets filled by MonoRail with the values from the Query:

image

Since we now have a Thanks action on our Controller we also need to create a Thanks.vm view inside our Views\Contact\ folder. A blank one will do for this tutorial.

Now that we have the form up and bound our DTO to it, we’ll continue in our next tutorial step with rendering and email and sending it.

Filed under .NET, Castle, Coding
Jul 18, 2009

ActiveRecord gotchas when testing with an in memory database.

0 Comments

If the title sounds familiar to you, it’s intentional. After having to deal with this in pure NHibernate it came around to also bite me with ActiveRecord.

In short: in-memory SQLite will drop the schema whenever you close the NHibernate ISession object (since ActiveRecord uses NHibernate behind the scenes this poses a problem to us).

So, assuming you have setup ActiveRecord using an InPlaceConfiguratonSource similar to this:

IDictionary<string, string> properties = new Dictionary<string, string>();
properties.Add("connection.driver_class", "NHibernate.Driver.SQLite20Driver");
properties.Add("dialect", "NHibernate.Dialect.SQLiteDialect");
properties.Add("connection.provider",                "NHibernate.Connection.DriverConnectionProvider");
properties.Add("connection.connection_string", "Data Source=:memory:;Version=3;New=True;");
properties.Add("show_sql", "true");
properties.Add("proxyfactory.factory_class",                "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");

var source = new InPlaceConfigurationSource();
source.Add(typeof (ActiveRecordBase), properties);

ActiveRecordStarter.Initialize(source, typeof (Member).Assembly.GetTypes());
ActiveRecordStarter.CreateSchema();

You will not be able to run any queries against it because there is no schema present. In fact the code will consistently blow up with a SQLiteException stating “no such table: ….”. Unfortunately it’s not really possible to change the SessionFactory implementation here because that code is inside ActiveRecord.

Thank god I found this handy guide that suggested subclassing the DriverConnectionProvider class to replace the CloseConnection call with a fake like this:

public class SqLiteInMemoryTestingConnectionProvider : NHibernate.Connection.DriverConnectionProvider
{     public static System.Data.IDbConnection Connection = null;     public override System.Data.IDbConnection GetConnection()     {         if (Connection == null)             Connection = base.GetConnection();         return Connection;     }     public override void CloseConnection(System.Data.IDbConnection conn)     {     }
}

I then had to pass that new ConnectionProvider into NH through the configuration and all was well:

properties.Add("connection.provider",                "ImagineClub.Tests.SqLiteInMemoryTestingConnectionProvider, ImagineClub.Tests");

Only catch is, this doing the AR Initialization is painfully slow so I wrote a baseclass for my xUnit tests that makes sure AR Init is only run once and that the ActiveRecordStarter.CreateSchema() is run before every test (xUnit runs the testclass constructor before each test):

The final implementation for all my tests looks like this:

public class ActiveRecordInMemoryTestBase
{     public ActiveRecordInMemoryTestBase()     {         if (!ActiveRecordStarter.IsInitialized)             Initialize();         ActiveRecordStarter.CreateSchema();     }     private static void Initialize()     {         IDictionary<string, string> properties = new Dictionary<string, string>();         properties.Add("connection.driver_class", "NHibernate.Driver.SQLite20Driver");         properties.Add("dialect", "NHibernate.Dialect.SQLiteDialect");         properties.Add("connection.provider",                        "ImagineClub.Tests.SqLiteInMemoryTestingConnectionProvider, ImagineClub.Tests");         properties.Add("connection.connection_string", "Data Source=:memory:;Version=3;New=True;");         properties.Add("show_sql", "true");         properties.Add("proxyfactory.factory_class",                        "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");         var source = new InPlaceConfigurationSource();         source.Add(typeof (ActiveRecordBase), properties);         ActiveRecordStarter.Initialize(source, typeof (Member).Assembly.GetTypes());         ActiveRecordStarter.CreateSchema();     }
}

public class SqLiteInMemoryTestingConnectionProvider : NHibernate.Connection.DriverConnectionProvider
{     public static System.Data.IDbConnection Connection = null;     public override System.Data.IDbConnection GetConnection()     {         if (Connection == null)             Connection = base.GetConnection();         return Connection;     }     public override void CloseConnection(System.Data.IDbConnection conn)     {     }
}

Caution: If you copy/paste the above make sure to change the namespace and assemblyname for your SqLiteInMemoryTestingConnectionProvider to match yours.

So a database dependant unit test would look like this:

public class DatabaseTest : ActiveRecordInMemoryTestBase
{     [Fact]     public void DatabaseIsEmpty()     {         Assert.Equal(0, Member.FindAll().Length);     }
}

Initial runs are quite slow due to the AR Init, but the whole test-suite should run quite fast since only the schema creation is run before each test.

Filed under .NET, Castle, Coding, NHibernate
Jul 15, 2009

Making simple things hard: NVelocity

0 Comments

I was pretty done with the world after spending almost 2 days with xhtml/css coding for the new iC-Website. Turns out the programming gods want to teach me a lesson. Look at my Google Search log:

image

What you see here is me spending almost 45 minutes on formatting a date!

I need to take the date and split it into 3 parts so I can stick it into the following markup:

<div class="date">
    <span class="day">$day</span><span class="month">$month</span>
    <hr />
    <span class="year">$year</span>
</div>

I thought, hey that should be really simple, just call DateTime.ToString() and all will be well. And because it was so obvious I tried to create a macro to keep my viewcode clean. The result was:

#macro ( dateBox $currentDate )
#set ($day = $currentDate.Day.ToString("00") )
#set ($month = $currentDate.Month.ToString("00") )
#set ($year = $currentDate.ToString("yy") )
<div class="date">
    <span class="day">$day</span><span class="month">$month</span>
    <hr />
    <span class="year">$year</span>
</div>
#end

I still have no explanation why passing a DateTime into the macro isn’t working. Maybe because calling macros in NV isn’t the same as calling a CLR method. So I had to abandon the macro idea and just code it the way it is.

Now what really pissed me off to the point where I almost considered using ASPView as a view engine was that I spent almost 45 minutes with this for one simple reason: NVelocity won’t report errors as long as they don’t break the parser.

Perfect example:

$DateTime.Now.Format("dd MM yyyy")

Will just result in a “$DateTime.Now.Format("dd MM yyyy")” output, for no apparent reason other than the fact that there is no Format() method on the DateTime. Clearly my bad, I’m stupid and far too dependent on IntelliSense, but if NV isn’t telling me how I screwed up it’s really hard to find the mistake. Especially without syntax highlighting and intellisense DateTime.Format(…) looks perfectly reasonable at first.

Finally I ended up with this:

#set ($day = $currentDate.ToString("dd") )
#set ($month = $currentDate.ToString("MM") )
#set ($year = $currentDate.ToString("yy") )
<div class="date">
    <span class="day">$day</span><span class="month">$month</span>
    <hr />
    <span class="year">$year</span>
</div>
Filed under .NET, Castle, Coding
Jul 14, 2009

Using ELMAH Error logging with Castle MonoRail Rescues

0 Comments

On my last project I made ELMAH (the ever awesome ASP.NET error logging framework) work with ASP.NET MVC by modifying the routing logic a bit. It was quite simple since ASP.NET MVC throws HttpExceptions around quite liberally and you are frequently presented with a YSOD that then gets logged by ELMAH.

Using MonoRail the general routine of setting up ELMAH still applies (even simpler), but it’s customary to have a general rescue view that informs the user when something went wrong. Since the rescue concept in MR basically swallows Exceptions and prevents them from reaching ELMAH we need to serve them to ELMAH through ErrorSignaling.

Defining a rescue in MonoRail according to the tutorials looks like this:

[Rescue("generalError")]
public class DemoController : SmartDispatcherController
{
    [Rescue("indexError")]
    public void Index()
    {
        throw new DivideByZeroException();
    }
}

The string passed to the RescueAttribute identifies the name of the view to load within your Views\rescues\ folder if an exception occurs. This is bad for us because we can’t execute any code to signal ELMAH on the way to the view and within the view.

This is where the RescueController overload for RescueAttribute comes into play. You can define a whole controller that will handle exceptions and we can execute code there before rendering a view. To do so we just need to implement IRescueController and inherit from SmartDispatcherController:

[Layout("default")]
public class RescueController : SmartDispatcherController, IRescueController
{
    public void Rescue(Exception exception, IController controller, IControllerContext controllerContext)
    {
        ErrorSignal.FromCurrentContext().Raise(exception);
        RenderSharedView(Path.Combine("rescues", "generalerror"));
    }
}

We can use this new controller by changing the Rescue attribute:

[Rescue(typeof(RescueController))]
public void Index()
{
    throw new DivideByZeroException();
}

Now in case you want to have multiple error-pages (like one general and one telling the user he did something wrong) you could also define multiple rescue methods inside your RescueController and call each of those when needed:

[Rescue(typeof(RescueController))]
public class DemoController : SmartDispatcherController
{
    [Rescue(typeof(RescueController), "IndexRescue")]
    public void Index()
    {
        throw new DivideByZeroException();
    }

    public void List()
    {
        throw new NotImplementedException();
    }
}

If an exception was to occur in List() it would get handled by the Rescue method inside your RescueController, if Index throws MR will try to call a method called IndexRescue. And both can be logged by ELMAH.

Filed under .NET, Castle, Coding
Jul 3, 2009

Running from trunks can be tough

4 Comments

I just spent almost 10 hours running in circles collecting different releases of NHibernate, Fluent NHibernate and castle, in a rather futile attempt to make them work together.

NHibernate is currently in 2.1 Beta1 at revision 2.1.0.2001 referencing the latest Castle.DynamicProxy2 at revision 2.1.0.0.

Fluent NHibernate’s current trunk compiles against NHibernate 2.1.0.1001 that in turn is compiled against Castle.DynamicProxy2 2.0.3 thus breaking.

So, while the NHibernate Project and the Castle project managed to match their versions pretty well, the Fluent NHibernate trunk was not.

So, the obvious choice would be to just take all the assemblies that are packed with Fluent NHibernate and work from that. But by doing so I then lack Calst MicroKernel and Windsor, two libraries that are not packed with Fluent NHibernate.

At that point I gave up and simply recompiled the Fluent NHibernate trunk with the latest NHibernate trunk.

In case you need Fluent NHibernate with Castle Windsor i packed my results for you: FluentNHibernateWithCastle.7z

Hope this helps.

Filed under .NET, Castle, NHibernate
May 30, 2009

Comparing Castle ActiveRecord to Fluent NHibernate

58 Comments

I’ve used my fair share of ORM tools lately and I keep coming back to NHibernate more and more. But sometimes it feels like “too much”. Going for a dedicated data access layer often feels like a bit of overkill and isn’t all that exciting to do, so for smaller projects I sometimes took the easy way and used LinQ to Sql.
Usually LinQ to Sql would then come around to bite me at some point and I’d hate myself for using it. So when I lately tried Castle ActiveRecord (watch this wonderful presentation by Ayende and Hammet at InfoQ: Painless Persistence with Castle ActiveRecord) I was blown away: A simpler way to build stuff with NHibernate.
No complete abstraction of NHibernate, but a layer ontop that makes life easier. (You can access the Session manually and do your crazy NHibernate stuff if you want to).

Since ActiveRecord was created to avoid some of the crazy configuration stuff that was in NHibernate at that time, I thought it might be interesting to compare ActiveRecord to the current state of NHibernate configuration, namely: Fluent NHibernate.

This is by no means a matchup, what you use hugely depends on your needs. And since both are essentially the same it boils down to taste. I haven’t used either for any real application (only old NHibernate with XML), so this is my personal rundown on the samples and spikes I did lately.

Let’s assume the typical Blog sample model:

model

I’ll only focus on the BlogPost class since it is on both ends of a parent/child relationship.

Mapping

First, how does the the ActiveRecord mapping look like:

[ActiveRecord]
public class BlogPost : ActiveRecordBase<BlogPost>
{
    [PrimaryKey]
    public int Id { get; set; }
    [Property]
    public string Headline { get; set; }
    [Property]
    public string PostText { get; set; }
    [Property]
    public DateTime PostedOn { get; set; }
    [BelongsTo]
    public User Poster { get; set; }
    [HasMany]
    public IList<Comment> Comments { get; set; }
}

Now the NHibernate mappings:

public class BlogPost
{
    public virtual int Id { get; set; }
    public virtual string Headline { get; set; }
    public virtual User Poster { get; set; }
    public virtual IList<Comment> Comments { get; set; }
    public virtual string PostText { get; set; }
    public virtual DateTime PostedOn { get; set; }
}
public class BlogPostMap : ClassMap<BlogPost>
{
    public BlogPostMap()
    {
        Id(m => m.Id);
        Map(m => m.Headline);
        Map(m => m.PostText);
        Map(m => m.PostedOn);
        HasMany(m => m.Comments);
        References(m => m.Poster);
    }
}

Cool, both APIs look good. Very readable and no XML.

NHibernate has the ability to have the Model separated from the mappings, a feature that I like when doing enterprise applications. But for something simpler, not really relevant. Where Fluent NHibernate really blows AR away is the auto mapper feature Ayende is so happy with.

Initialization

ActiveRecord hasn’t departed from XML yet, but there are three ways to load a configuration. The simplest would probably be the inplace configuration source, but it’s more or less a in-memory mirror of the XML config:

var properties = new Hashtable();
properties.Add("hibernate.connection.driver_class", "NHibernate.Driver.SQLite20Driver");
properties.Add("hibernate.dialect", "NHibernate.Dialect.SQLiteDialect");
properties.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("hibernate.connection.connection_string", "Data Source=:memory:;Version=3;New=True;");
var source = new InPlaceConfigurationSource();
source.Add(typeof (ActiveRecordBase), (IDictionary<string, string>) properties);
ActiveRecordStarter.Initialize(typeof(BlogPost).Assembly, source);
ActiveRecordStarter.CreateSchema();

The Fluent NHibernate configuration looks way better since you don’t have to worry about connectionstrings or other properties that nobody remembers:

public static ISessionFactory CreateSessionFactory()
{
    return
        Fluently
            .Configure()
            .Database(SQLiteConfiguration.Standard.InMemory())
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<BlogPost>())
            .ExposeConfiguration(BuildSchema)
            .BuildSessionFactory();
}

private static void BuildSchema(Configuration config)
{
    new SchemaExport(config)
        .Create(false, true);
}

I’d vote for Fluent NHibernate on this one, but having the configuration externalized in XML is something you’d probably do anyway.

Where the differences really begin are the querying:

Querying with ActiveRecord is mostly done through static methods, so ease of use is king here:

var post = BlogPost.Find(1);

While NHibernate requires me to retrieve a ISession before giving me access to anything.

var mySession = factory.OpenSession();
var post = mySession.Get<BlogPost>((object)1);

The one is more OO, the other is simpler. I have to say I prefer the added complexity since it makes it easier to test that your code interacts with the session object. (Although I’d not overuse that, going against an in-memory db and verifying the results should be the better way to create durable tests).

Since both AR and NH use the NH Criteria API I won’t compare complex queries.

So, how to conclude on the usability? Not having to think about how to pass the session around is quite nice, but when using NHibernate you could easily just write your session to some global and use it from there.

Validation

Now, what would a ORM be without a good validation framework.

ActiveRecord comes prepacked with the Castle.Components.Validator assembly that allows a rather cool attribute based validation API:

[Property, ValidateEmail, ValidateNonEmpty]
public string Email { get; set; }
var user = new User();
if (user.IsValid())
    user.Save();

While NHibernate doesn’t have a built-in Validation framework, there is the NHibernate Validator (documentation) project that also allows a very clean attribute based validation.

[NotNull]
public static string blacklistedZipCode;

But as before, it’s a bit “heavier” than AR and allows you to have external ValidatorClasses if you need them. Also cool, but something I don’t really care about is that NHV is also XML based, so you could allow your users/admins to tweak the validation rules after deployment.

I guess that’s enough for now, use what you find suits your project better.  :)

Filed under .NET, Castle, NHibernate
May 27, 2009

Setting a InsertedOn Field with Castle ActiveRecord

2 Comments

If I want a field to contain the date of insertion I’d usually have to hook into the Create method somewhere be it my repository or whatever.
With Castle ActiveRecord it’s as simple as overriding the Create() method in your Entity:

[ActiveRecord]
public class Comment : ActiveRecordBase<Comment>
{
    [PrimaryKey]
    public long Id { get; set; }
    [Property]
    public DateTime CreatedOn { get; set; }
    [Property]
    public string Message { get; set; }
    private void SetInsertionTimestamp()
    {
        CreatedOn = DateTime.Now;
    }
    public override void Create()
    {
        SetInsertionTimestamp();
        base.Create();
    }
    public override void CreateAndFlush()
    {
        SetInsertionTimestamp();
        base.CreateAndFlush();
    }
}
Filed under .NET, Castle, Coding
May 26, 2009

Projects

dynamic css for .NET