Lorem Ipsum

Once in a while you need to fill in some dummy-text. Usually this is done, by leveraging the “lorem ipsum” text.

While there are a couple of websites, that can create this text (like http://www.lipsum.com/), this is actually unnecessary while working with Micorsoft Word 2007. Just type in =lorem(10,5) and you’ll get about 10 paragraphs with up to 5 lines of text per paragraph.

This is kinda neat.

Painless filtering in NHibernate

The Stage

Let’s assume, there exists an application, which is already heavily relying on NHibernate. This app is supposed to be extended. All wordings are currently available in a single locale and re stored in the database. This is matter to change, since we want to introduce multi-language capabilities for our wordings.

The Plan

The simplest way to achieve the requirement would be to extend the domain-model in such a way, that a new column would be added to the tables in the database. This column would contain the locale of the text. Instead of a single row for each text, we would end up with a single row for each locale for each text.

In order to retrieve a certain text from the wording-table of the database, we not only need to know which text to get, but we also need to know which local of the text we need to get. So this would end up in an additional criteria when retrieving data from the database. This is the point where NHibernates comes into play. NHibernate offers global filters, which can be used in conjunction with regular queries.

I will demonstrate how to make use of these filter by showing a little example.

The Implementation

Let’s take a small app, which is persisting pizza and toppings using NHibernate. Therefore we have POCOs and according mappings.

namespace Pizza.Entities
{
    /// <summary>
    /// Business Entity representing a pizza-topping
    /// </summary>
    public class Topping
    {
        /// <summary>
        /// The internal, unique id of this topping
        /// </summary>
        /// <value>The id.</value>
        public virtual int Id { get; set; }
        /// <summary>
        /// the name of the topping
        /// </summary>
        /// <value>The name.</value>
        public virtual string Name { get; set; }
    }
    /// <summary>
    /// Business Entity representing a pizza
    /// </summary>
    public class Pizza
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Pizza"/> class
        /// </summary>
        public Pizza()
        {
            Toppings = new List<Topping>();
        }
        /// <summary>
        /// The internal, unique id of this pizza
        /// </summary>
        /// <value>The id.</value>
        public virtual int Id { get; set; }
        /// <summary>
        /// the name of the pizza
        /// </summary>
        public virtual string Name { get; set; }
        /// <summary>
        /// the toppings, which are being used by the pizza
        /// </summary>
        public virtual IList<Topping> Toppings { get; private set; }
    }
}
<class name="Topping" table="Toppings">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
</class>
<class name="Pizza" table="Pizzas">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
  <list name="Toppings" table="PizzaToppings" cascade="all">
    <key column="PizzaId" />
    <index column="Position"/>
    <many-to-many column="ToppingId" class="Topping" />
  </list>
</class>

As you can see, pizza as well as toppings each have a name. A pizza also has a set of toppings.

So far, so good. To support multiple locales we could go several ways. We could introduces a property called Name_de as well as Name_en to support german (DE) and englisch (EN) locales. An alternative approach would be, to add a property called Locale, which hold the locale of the name. If I would like to get english pizzas I would need to filter for pizza entities, which have a locale of “en”.

OK, let’s go with the second alternative. But how do I restrict my queries to only fetch pizza entities with locale=en? With NHibernate-Filter!

First of all we need to define a filter.

<filter-def name="localized">
  <filter-param name="myLocale" type="System.String"/>
</filter-def>

The next step is, to include this newly created filter in the mappings.

<class name="Topping" table="Toppings">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
  <property name="Locale"/>
  <filter name="localized" condition=":myLocale = Locale"/>
</class>
<class name="Pizza" table="Pizzas">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
  <property name="Locale"/>
  <list name="Toppings" table="PizzaToppings" cascade="all">
    <key column="PizzaId" />
    <index column="Position"/>
    <many-to-many column="ToppingId" class="Topping">
      <filter name="localized" condition=":myLocale = Locale"/>
    </many-to-many>
  </list>
  <filter name="localized" condition=":myLocale = Locale"/>
</class>

This way I specify that by using the filter I want to restrict my results by the column Locale. It’s important to notice, that this will only happen when I’m actually using this filter. When I’m not using the filter this restriction is being ignored. Thus: the filter is optional!

OK, so how does this actually work in my application – how do I use such a filter? What I don’t want: I don’t want to change all my existing queries to include a filter for the locale column. Instead I’m just activating the previously defined filter and assign a certain value.

// enable the filter
_session.EnableFilter("localized").SetParameter("myLocale", "de");
// do some plain ol’ querying
var pizzaList = _session.CreateCriteria<Entities.Pizza>().List<Entities.Pizza>();

That’s it. There is nothing more to it. I can leave all my queries the way they are and just execute them like before. Let’s take a look at the SQL statements that are being created, because they will show the usage of the filter.

SELECT this_.Id as Id2_0_, this_.Name as Name2_0_, this_.Locale as Locale2_0_
    FROM Pizzas this_
    WHERE @p0 = this_.Locale;@p0 = 'de'

This shows the strength of NHibernate-Filters. Besides the modification of the mappings and the activation of the filter I don’t need to modify anything. I don’t need to alter my queries. The filter is being applied by NHibernate behind the scenes.

This also works in more complex scenarios. Let’s assume I have a pizza with several toppings. I only want to get a pizza in german – and of course I also want to get german toppings as well. This works as too.

var multiPizza = new Entities.Pizza {Name = "Multikulti", Locale = "de"};
multiPizza.Toppings.Add(new Topping {Name = "Käse", Locale = "de"});
multiPizza.Toppings.Add(new Topping {Name = "Mushrooms", Locale = "en"});
_session.Save(multiPizza);
_session.Flush();
_session.Clear();
var fromDb = _session.CreateCriteria<Entities.Pizza>().Add(Expression.Eq("Id", multiPizza.Id)).List<Entities.Pizza>()[0];
Assert.That(fromDb.Locale, Is.EqualTo("de"),"pizza locale");
Assert.That(fromDb.Toppings,Has.Count.EqualTo(1));
foreach (var topping in fromDb.Toppings)
{
    Assert.That(topping.Locale, Is.EqualTo("de"),"topping locale");
}

I already activated and set the filter in the constructor of my class – so I don’t need to do this over again. At least not as long as I reuse the same session. Let’s take a look at the SQL send tot eh database – this is just impressive!

SELECT this_.Id as Id2_0_, this_.Name as Name2_0_, this_.Locale as Locale2_0_
    FROM Pizzas this_
    WHERE @p0 = this_.Locale
        AND this_.Id = @p1;@p0 = 'de', @p1 = 4
SELECT toppings0_.PizzaId as PizzaId1_, toppings0_.ToppingId as ToppingId1_, toppings0_.Position as Position1_, topping1_.Id as Id1_0_, topping1_.Name as Name1_0_, topping1_.Locale as Locale1_0_
    FROM PizzaToppings toppings0_ left outer join Toppings topping1_ on
        toppings0_.ToppingId=topping1_.Id
    WHERE  @p0 = topping1_.Locale
        and toppings0_.PizzaId=@p1;@p0 = 'de', @p1 = 4

Conclusion

The use of NHibernate-Filters introduces a very transparent way to extend the applicationlogic to include additional filter criteria.

  • Instead of storing a newly localized text in a seperate column, this doesn’t require any schema-changes.
  • Only the rows to a certain locale are being retrieved, this might reduced bandwith.

Where’s that data?

ASP.Net applications have a special folder call App_Data, which is specifically designed to hold application-data such as databases. SQL-Server express will place it’s .mdf files here by default.

Because this directory is being protected by the .Net-framework and thus not accessible by clients, it’s a good idea to place other data here as well.

To access this folder a couple of different approaches come to mind. The first idea would be to just access /App_Data/mydata.db hardcoded. While this might work in most scenarios, it will fail if the application is installed in a virtual directory instead of the root.

OK, let’s try something different. How about ~/App_Data/mydata.db? Looks compelling. At runtime the .Net-framework will substitute “~” with the actual base-directory of the application. Unfortunately this is only done for certain elements. So this might not always work. You could of course get the actual path on the server side by using

Server.MapPath("~/App_Data/mydata.db");

Doing some research offers my preferred approach

Path.Combine(AppDomain.CurrentDomain.GetData("DataDirectory").ToString(), "mydata.db");

AppDomain.CurrentDomain.GetData("DataDirectory") will return the path to the App_Data folder wherever that’s actually may be. Nice.

Getting those ASMXs

Creating a ASMX-page to leverage some service functionality to a client is fairly easy. The nice thing about that is, that you can even consume these services from JavaScript.

But out-of-the-box you can only call those services either via SOAP 1.1, SOAP 1.2 or a POST-request. But what if you want to use a plain-ol’ GET-request? You’ll always get an error-message stating, that GET is not supported – what a bummer.

But working around this problem is quite easy to do. Just open up your code-behind of your ASMX-Service and add

[ScriptMethod(UseHttpGet = true)]

To the method you’re calling. Finally you’ll also have to add the HTTP-GET to the list of "known" protocolls for webservices in the web.config. This is done by adding

<webServices>
  <protocols>
    <add name="HttpGet"/>
  </protocols>
</webServices>

to the system.web section in the web.config.

Thats all.

Tab preview for Firefox in Windows 7

While the first beta of Firefox 3.6 did not offer the tab-preview for Windows 7 (you know, those little previews when you hover over running programs in your taskbar, which allow switching direct to a certain tab within Firefox), this feature was removed in the third beta. 🙁

Actually, this feature wasn’t really removed but rather just disabled. In order to re-active this feature you have to open the advanced settings (about:config) and then just enable browser.taskbar.previews.enable.

If you even want to be able to cycle through the browser tabs using [CTRL]+[Tab] you have to enable browser.ctrlTab.previews (you might have to create this settig if it does not yet exist) as well.

Detect 32bit/64bit OS

Even in a managed world like .Net sometimes you gotta know where you’re actually running in – 32-bit or 64-bit. But how do you figure out where you at?

Well, In an 64-bit OS all pointers are 8 bits wide, so just check for the size of your pointers!

if ( IntPtr.Size == 8 ) {
  // 64 bit machine
}} else if ( IntPtr.Size == 4 ) {
  // 32 bit machine
}}

Showing them all

In Windows Vista as well as in Windows 7 the Control Panel has had a major redesign, compared to Windows XP. All items are now organized into categories, and the actual dialogs might not be accessible right from the control panel.

To overcome this “shortage” you can start-up a new explorer window, and type in the address-bar shell:::{ED7BA470-8E54-465E-825C-99712043E01C}. This will open up a new view, showing about 250 entries for all dialogs within the control panel; happy tuning.

3.300,91

Denial of SMS

For quite some time my HTC Touch Pro (running Windows Mobile 6.1) refuses to send text-messages (SMS). This is quite annoying. Whenever I write a SMS and hit the send-button I get a message stating: “the phone is not ready. wait 15 seconds and try again”. Of course waiting 15 seconds doesn’t do anything …

But now I found some kind of cure: save the message in the drafts folder and the move it to the outbox … and much to my surprise the message is being send! 🙂

Automated Builds – Getting started

The Intro

A couple of years ago I got started scripting my builds using NAnt. I considered that to be a great opportunity to increase the quality of my builds and to get all those manual steps done, which might otherwise be skipped – due to dullness.

So after getting the build al straightened up, the logical next step was to get someone else to actually do the building of the app. Since the build-script was up and running, this wasn’t that hard to accomplish. So I found CruiseControl.Net.

This was already way back in 2004 – so way before Microsoft release TeamFoundationServer.

Since then CCNet served me very well, but to be honest I didn’t really kept up with latest developments in CCNet.

So I will show a little bit, of I used CCNet to improve my build process and how to get going with continues integration.

Prep’ing the project

First of, in order to take full advantge of CCNet you need to have a working build-script to automate the build of the project.

Well, starting with Visual Studio 2005 the project files are based on MSBuild – so you will already have a working build-script in place. Either you stick with this script, or you decide to roll your own. That’s what I chose, but sticking with MSBuild is fine as well. Just out of personal preference I use NAnt for my builds. But to be honest – to actually do the compiling and stuff, I use the MSBuild-Task of the NAnt Contribution project, which in turn utilizes the MSBuild script of Visual Studio.

So my super-simple NAnt file looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<project xmlns="http://nant.sf.net/schemas/nant.xsd" name="Pizza">
    <target name="Compile">
        <msbuild project="Pizza.sln"  >
            <property name="Configuration" value="Debug"/>
        </msbuild>
    </target>
</project>

Setting up a new server

So it’s way overdue to pay some respect to the recent 1.5.0 CTP release of CCNet.

OK, let’s take the the new CTP for a spin. I just downloaded the ZIP file, extracted it into a common location and then take a deep dive into the config. This is one of the biggest downturns of CCNet – the hugh chunk of XML configuration. Well, anyway.

Since we want to start out simple, we’ll stick with a really simple ccnet.config as well. So you should have a servers folder, which contains a ccnet.config file. This holds all you ccnet configuration.

<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
    <project name="Pizza">
        <workingDirectory>d:\ccnet\repositories\Pizza</workingDirectory>
        <artifactDirectory>d:\ccnet\repositories\Pizza\Artifacts</artifactDirectory>
        <sourcecontrol type="svn">
          <trunkUrl>file:///D:/SVNRepositories/Pizza/trunk/</trunkUrl>
          <workingDirectory>d:\ccnet\repositories\Pizza\Source</workingDirectory>
          <executable>d:\svn-win32\bin\svn.exe</executable>
          <tagOnSuccess>False</tagOnSuccess>
        </sourcecontrol>
        <triggers>
          <intervalTrigger seconds="900" />
        </triggers>
        <tasks>
          <nant description="main build">
            <executable>d:\nant\bin\NAnt.exe</executable>
            <buildFile>d:\ccnet\repositories\Pizza\Source\default.build</buildFile>
            <targetList>
              <target>Compile</target>
            </targetList>
          </nant>
        <publishers>
          <xmllogger />
          <modificationHistory />
        </publishers>
        <state type="state" directory="d:\ccnet\repositories\Pizza" />
    </project>
</cruisecontrol>

This configuration checks every 900 seconds my local, file-based SVN-repository for changes. If any changes were found, or a build was forced, the target “Compile” of the default.build script is being executed.

This is pretty cool. So now we’ve build our self a very basic build-server, which checks regularly for any modifications and if needed creates a new build. This way I can make sure that whenever I check something into the SVN repository I still get a working – or at least building – application.

Accessing the Build-Server

But wait, event though we’ve got our builds automated we haven’t yet any way to access the output of the build; or at least see what CCNet is actually doing and getting to know of any errors that where encountered during the build.

Basically there are two “interfaces” to CCNet. Either through the web-dashboard or via a little windows-app. For the web-dashboard you need to have IIS installed as well as ASP.Net. To get the web-dashboard up and running just create a new virtual web and point it to your location of CCNet. There should be a sub-folder “webdashboard”, that’s where you want to point your virtual directory. That’s already all you need to get going.

You should then see the dashboard, which will tell you whether your build succeed or in the case of a failure what went wrong during the build.

ccnet_dashboard

I think for now, this is working quite well. I kinda have get the feeling, that I’ll soon write some more about how to evolve your build-experience … 🙂