<?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>John Zablocki&#039;s dllHell.net</title>
	<atom:link href="http://dllhell.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://dllhell.net</link>
	<description>Write code.  Not too much.  Mostly C#.</description>
	<lastBuildDate>Fri, 30 Mar 2012 21:27:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>On Signing Git Tags on Windows</title>
		<link>http://dllhell.net/2012/03/30/on-signing-git-tags-on-windows/</link>
		<comments>http://dllhell.net/2012/03/30/on-signing-git-tags-on-windows/#comments</comments>
		<pubDate>Fri, 30 Mar 2012 21:23:58 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=309</guid>
		<description><![CDATA[Since I started working at Couchbase, I&#8217;ve had to get used to a whole new set of tools and processes. Most of this new process revolves around Git. I&#8217;ve previously lamented the Git experience on Windows. I&#8217;m not sure whether &#8230; <a href="http://dllhell.net/2012/03/30/on-signing-git-tags-on-windows/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Since I started working at Couchbase, I&#8217;ve had to get used to a whole new set of tools and processes.  Most of this new process revolves around Git.  I&#8217;ve <a href="dllhell.net/2010/10/04/on-removing-saved-passwords-in-mercurial/">previously lamented</a> the Git experience on Windows.  I&#8217;m not sure whether it&#8217;s gotten better or I&#8217;m just learning to use Git more.  Maybe it&#8217;s a little of both&#8230;</p>
<p>Still, there are pain points.  Git certainly has a strong *nix bias.  There are assumptions about what tools are available or installed on your machine.  As a Windows developer, you&#8217;ll find yourself searching for Windows variants of these tools.  This was the case today when I set out to create a signed tag on the Couchbase .NET Client.  </p>
<p>In theory, it&#8217;s a simple command.</p>
<p><code>git tag -s v1.0 -m "A message"</code></p>
<p>To sign a tag, you need to have <a href="http://gnupg.org/documentation/howtos.en.html">GPG</a> installed.  I installed <a href="http://gpg4win.org/">Gpg4win</a>, which installs a nice GUI for managing keys and the GPG command line interface.  My ignorance of the process was clear as I repeatedly attempted to use the GUI (GNU Privacy Assistant &#8211; Key Manager) to create my key.  That GUI appears to create valid keys, but wherever it stores the related key part files is not where the GPG command line expects to find them.  </p>
<p>Instead, be sure to use the command line client. Start with:</p>
<p><code>gpg --gen-key</code></p>
<p>Answer the questions when prompted (using the defaults is fine).  Be sure to make sure that the email address you set for the key is the one you set for your user.email git config value.  If key creation fails, you might manually need to create the directory <em>c:\users\&lt;USER&gt;\.gnupg</em>, which GPG will apparently not do on its own.  After you create the key using &#8211;gen key, you should have no problem running the tag command above.  </p>
<p>The errors that I was seeing along the way were &#8220;gpg: no writable public keyring found&#8221; and &#8220;signing failed: secret key not available.&#8221;  </p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2012/03/30/on-signing-git-tags-on-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Wicked Easy NoSQL with Couchbase Server</title>
		<link>http://dllhell.net/2011/12/30/on-wicked-easy-nosql-with-couchbase-server/</link>
		<comments>http://dllhell.net/2011/12/30/on-wicked-easy-nosql-with-couchbase-server/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 15:45:18 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Couchbase]]></category>
		<category><![CDATA[NoSQL]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=267</guid>
		<description><![CDATA[NoSQL doesn&#8217;t have to be difficult. Generally speaking, it isn&#8217;t. But admittedly, and especially on Windows, it&#8217;s not always as clean as it could be. Each database has its challenges. Some are difficult to install. Some are difficult to configure. &#8230; <a href="http://dllhell.net/2011/12/30/on-wicked-easy-nosql-with-couchbase-server/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>NoSQL doesn&#8217;t have to be difficult.  Generally speaking, it isn&#8217;t.  But admittedly, and especially on Windows, it&#8217;s not always as clean as it could be.  Each database has its challenges.  Some are difficult to install.  Some are difficult to configure. Some have poor server admin tools.  Some lack strong client library support.  One of the NoSQL offerings that really gets things right is Couchbase Server.  OK, full disclosure, this is my first post as a Developer Advocate for Couchbase!</p>
<p>Couchbase was formed when Membase and CouchOne merged.  <a href="http://www.couchbase.org/get/couchbase/2.0.0">Couchbase Server 2.0</a> is going to be a hybrid NoSQL database, combining features from both distributed key/value stores and document oriented databases.  The 2.0 product will be released in 2012.  In January 2012, an interim 1.8 release will be the first official release of the merged Couchbase Server, formerly Membase Server.  As part of my responsibilities at Couchbase, I&#8217;m working on the .NET client library for Couchbase Server 1.8.  Below is a preview of what&#8217;s coming.  If you&#8217;ve used Membase Server with .NET, you should be familiar with the code below.  If you&#8217;re new to Couchbase Server, I&#8217;m going to start from the beginning.</p>
<p><strong>Installing Couchbase Server</strong></p>
<p>Most NoSQL databases have Windows installers, though sometimes these aren&#8217;t kept up to date.  In the case of CouchDB, there are a couple of different MSI packages available, but only one works (at least as of October 2011).  MongoDB has a command line installer for its service.  Couchbase Server, fortunately, has an officially supported Windows installer.   You can download the <a href="http://www.couchbase.com/downloads">latest installer here</a>.  As I write this, the latest server version is 1.7.2.  Check back later in January for 1.8.  Grab the Community Edition of Membase Server, which is appropriate for development purposes.  Membase Server will be renamed Couchbase Server with the 1.8 release.  You can also grab the 2.0 Developer Preview, which already sports the new name.  </p>
<p>After you run the installer, you&#8217;ll be taken the web based admin console.  The admin console is where you&#8217;ll be able to configure your cluster and manage the nodes within that cluster.  In local development, you&#8217;ll likely have a single node cluster (e.g., your dev machine).  </p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/12/Membase-22.png"><img src="http://dllhell.net/wp-content/uploads/2011/12/Membase-22-1024x966.png" alt="" title="Membase-2" width="640" height="603" class="alignnone size-large wp-image-297" /></a></p>
<p>Once you&#8217;ve gotten the server up and running, it&#8217;s time to write some code.  If you create a simple console app, the easiest way to include the Couchbase .NET client library in your app is to use Nuget.  After you add the reference, add the following using statement:</p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/12/nuget1.png"><img src="http://dllhell.net/wp-content/uploads/2011/12/nuget1.png" alt="" title="nuget" width="900" height="600" class="alignnone size-full wp-image-303" /></a></p>
<p><strong>Hello, Couchbase!</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">Couchbase</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>Then add the following line to your Main method:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> Main<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> args<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    var client <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> CouchbaseClient<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>After you add these lines, compile the app.  You&#8217;ll probably get a strange compilation error that the namespace &#8216;Couchbase&#8217; can&#8217;t be found.  The reason you&#8217;ll see this error is that Visual Studio 2010 (I&#8217;ve made the assumption that you&#8217;re using 2010) defaults console projects to use the .NET 4 Client Profile, which is a subset of .NET 4.  You&#8217;ll need to update the .NET version to .NET 4.0 (or 3.5).  After making this change, you&#8217;ll be able to build.</p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/12/net-version-selector.png"><img src="http://dllhell.net/wp-content/uploads/2011/12/net-version-selector.png" alt="" title="net-version-selector" width="840" height="680" class="alignnone size-full wp-image-305" /></a></p>
<p>Next, you&#8217;ll need to add some configuration info to your app.config.  The entire file should look as follows:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configSections<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;section</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;membase&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;Couchbase.Configuration.CouchbaseClientSection, Couchbase&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configSections<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;membase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servers</span> <span style="color: #000066;">bucket</span>=<span style="color: #ff0000;">&quot;default&quot;</span> <span style="color: #000066;">bucketPassword</span>=<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">uri</span>=<span style="color: #ff0000;">&quot;http://127.0.0.1:8091/pools/default&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>   
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/membase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>In the config section, you provide the client details on how to connect and to where data will be written.  To tell the CouchbaseClient to use the app.config section, update the declaration as follows:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">var client <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> CouchbaseClient<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;membase&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>Saving and reading primitive data types is just as easy as saving and reading user defined types.  So I&#8217;ll create a couple of classes Brewery and Beer (intentionally simplified).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">&#91;</span>Serializable<span style="color: #008000;">&#93;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Brewery <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Name <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> City <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> State <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">&#91;</span>Serializable<span style="color: #008000;">&#93;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Beer <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Name <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> Brewery Brewery <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">decimal</span> ABV <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>These classes are just POCOs (Plain Old CLR Objects) that have been marked Serializable.  I&#8217;ll new up an instance of each in my Main method.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">var brewery <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Brewery <span style="color: #008000;">&#123;</span> 
&nbsp;
    City <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Hartford&quot;</span>, 
    State <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;CT&quot;</span>, 
    Name <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Thomas Hooker Brewery&quot;</span> 
<span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
var beer <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Beer <span style="color: #008000;">&#123;</span> 
    Brewery <span style="color: #008000;">=</span> brewery, 
    Name <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;American Pale Ale&quot;</span>, 
    ABV <span style="color: #008000;">=</span> 5<span style="color: #008000;">.</span>3m
<span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>Next, I&#8217;ll persist the Beer instance by calling the client&#8217;s Store method.  Note that the StoreMode requires the additional using statement be added for Enyim.Caching.Memcached.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">client<span style="color: #008000;">.</span><span style="color: #0000FF;">Store</span><span style="color: #008000;">&#40;</span>StoreMode<span style="color: #008000;">.</span><span style="color: #0000FF;">Set</span>, beer<span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span>, beer<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>After storing, I&#8217;ll read the Beer back out and display its name.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">var savedBeer <span style="color: #008000;">=</span> client<span style="color: #008000;">.</span><span style="color: #0000FF;">Get</span><span style="color: #008000;">&lt;</span>Beer<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;beer&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span>savedBeer<span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>And that&#8217;s it, wicked easy, right? Admitedly, this is a very simplified introduction to Couchbase Server.  As I&#8217;m now taking over the .NET client library, I&#8217;ll be posting more detailed tutorials and samples.  </p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2011/12/30/on-wicked-easy-nosql-with-couchbase-server/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>On Getting Started with Node.js, MongoDB and Heroku on Windows</title>
		<link>http://dllhell.net/2011/11/08/on-getting-started-with-node-js-mongodb-and-heroku-on-windows/</link>
		<comments>http://dllhell.net/2011/11/08/on-getting-started-with-node-js-mongodb-and-heroku-on-windows/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 18:10:13 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[heroku]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=231</guid>
		<description><![CDATA[I recently had the opportunity to see David Padbury present on Node.js at the New England Code Camp. An earlier version of his slides is available here. Recently while prepping for an upcoming presentation on Windows Phone 7 location services, &#8230; <a href="http://dllhell.net/2011/11/08/on-getting-started-with-node-js-mongodb-and-heroku-on-windows/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently had the opportunity to see David Padbury present on Node.js at the New England Code Camp.  An earlier version of his slides is available <a href="http://www.slideshare.net/davidpadbury/nodejs-javascripts-in-your-backend">here</a>.  Recently while prepping for an <a href="http://www.meetup.com/DevBoston/events/31894842/">upcoming presentation</a> on Windows Phone 7 location services, I decided that I&#8217;d incorporate Node.js into my demo.  This post will <strong>briefly</strong> introduce the technologies in its title and describe the process of getting them installed and running on a Windows box.  </p>
<h3>Node.js</h3>
<p>Hopefully at this point, you have at least heard of <a href="http://nodejs.org">Node.js</a>.  If you haven&#8217;t, stop what you&#8217;re doing right now and <a href="http://www.bing.com/search?q=node.js" target="_blank">Bing it</a>.  Node is one of those disruptive technologies that&#8217;s going to change the way we build web apps in the years ahead.  Well, it might not <em>totally</em> change how we build them.  But things will start to look very different because of it.</p>
<p>OK, so what is Node.js?  Node is an evented I/O web server.  Such web servers use a single thread (yes, you read that correctly) to handle all requests and rely on non-blocking I/O and callbacks to achieve massive levels of concurrency.  The operating system provides facilities for performing non-blocking I/O.  Windows supports this feature via <a href="http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx">I/O Completion Ports</a>.  Basically, that single thread gets a request, sends it off to do something using non-blocking I/O, waits for a callback upon I/O completion and then sends the response.</p>
<h3>MongoDB</h3>
<p>It&#8217;s somewhat forgivable if you haven&#8217;t heard of Node.js.  We all miss our exits from time to time.  But <a href="http://mongodb.org">MongoDB</a>?  There&#8217;s really no excuse for not knowing about this NoSQL staple!  It&#8217;s an amazing product.  But I&#8217;ll mention briefly that MongoDB is a document-oriented, schema-less database.  JavaScript is used for queries and commands and documents are stored as BSON (Binary JSON).  If you want more introductory material, check out <a href="http://www.codevoyeur.com/Presentations.aspx#dotnetmongo">my presentations</a>.</p>
<h3>Heroku</h3>
<p>Heroku started out as a service for deploying Ruby on Rails apps to EC2, though recently they&#8217;ve expanded their offerings.  Heroku now supports Node.js, Python and Java, among others.  They offer a platform that allows your app to be deployed via a Git push.  You get some basic web and database resources for free and pay as your app needs to scale out.  It&#8217;s all seamless.  <a href="http://dllhell.net/2011/08/10/on-free-orchard-hosting-with-bitbucket-and-appharbor/">AppHarbor</a> offers a similar service for ASP.NET apps and is arguably simpler.</p>
<h3>Installing Node on Windows</h3>
<p>There isn&#8217;t an installer for Node.  You simply grab the latest executable from <a href="http://nodejs.org/#download">http://nodejs.org/#download</a> and drop it somewhere like c:\Program Files\Node\Node.exe.  Add the directory to your path.  Open up cmd and type node.  You should get the interactive node console.  I won&#8217;t bother reposting the &#8220;<a href="http://nodejs.org/">Hello, World</a>!&#8221; exercise.  But you should go through the exercise either in the interactive shell or by simply working in a text editor and creating a JS file and then running &#8220;node yourfile.js&#8221; from the command line.</p>
<p>OK, I&#8217;ll re-post so you don&#8217;t have to click over.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> http <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
http.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  res.<span style="color: #660066;">writeHead</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">200</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'Content-Type'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'text/plain'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  res.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Hello World<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1337</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;127.0.0.1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Server running at http://127.0.0.1:1337/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Save that code snippet to a file hello.js and run &#8220;node hello.js&#8221;</p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/11/Capture.png"><img src="http://dllhell.net/wp-content/uploads/2011/11/Capture.png" alt="" title="Capture" width="555" height="99" class="alignnone size-full wp-image-244" /></a></p>
<p>Browse to <a href="http://localhost:1337">http://localhost:1337</a> and Node should respond with the expected &#8220;Hello, World!&#8221; response.  What&#8217;s most exciting about this exercise is that Node is running on Windows, <a href="http://blog.nodejs.org/2011/06/23/porting-node-to-windows-with-microsoft%E2%80%99s-help/">thanks to Microsoft</a>.  Be warned that if you scroll to the comments in that post, there are some clear Linux zealots who say some dumb, dumb things about Microsoft.  Don&#8217;t get me wrong, I have a dual boot of Ubuntu and Win7 on one of my Vaios.  But I hate the &#8220;MS can&#8217;t do anything right crowd.&#8221;  Leaving the soapbox&#8230; </p>
<h3>Installing NPM on Windows</h3>
<p>OK, so bare bones Node is now running.  To do more, you&#8217;ll need to grab some of the numerous node modules.  As Nuget is to .NET, <a href="http://npmjs.org/">NPM</a> is to Node.  For a young framework, Node has a shockingly rich package library accessible via NPM.  Keep in mind, NPM on Windows is <a href="https://github.com/isaacs/npm">considered experimental</a>. </p>
<p>Installation requires Git, so make sure you have that <a href="http://code.google.com/p/msysgit/downloads/list?can=3">installed</a>. Once you do, run the following commands:</p>
<pre>git clone --recursive https://github.com/isaacs/npm.git npm
cd npm
node cli.js install npm -gf</pre>
<p>Make sure you didn&#8217;t skip that &#8211;recursive step.   Things break if you do.  Also keep in mind that if your Node.exe directory is under Program Files, that&#8217;s protected by Windows and you&#8217;ll need to run cmd as an admin.  The NPM installation creates files in the Node.exe directory.  You can test your installation by grabbing the express web framework for Node.js.</p>
<pre>npm install express</pre>
<h3>Creating a Heroku Node.js App</h3>
<p>The first thing you need to do is create an empty git repository in the directory in which you&#8217;ll create your app. </p>
<pre>git init</pre>
<p>After you&#8217;ve created your Heroku account and the git repo, you need to install the <a href="http://devcenter.heroku.com/articles/node-js#prerequisites">Heroku client</a>.  Once you&#8217;ve done that, open a command line and enter:</p>
<pre>heroku login</pre>
<p>You&#8217;ll be prompted to enter your email and password.  After you successfully authenticate, you should receive a message that you need to either upload an existing SSH public key or create a new one.  If you haven&#8217;t created an SSH key before, you can also use <a href="http://help.github.com/win-set-up-git/">ssh-keygen</a> to do so.  </p>
<p>Next, open your text editor of choice and create a .js file named client.js (or whatever you want to name it).  Add the following code (from <a href="http://devcenter.heroku.com/articles/node-js">Heroku&#8217;s Node quick start</a> docs).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> express <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'express'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> app <span style="color: #339933;">=</span> express.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span>express.<span style="color: #660066;">logger</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
app.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>request<span style="color: #339933;">,</span> response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  response.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Hello World!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> port <span style="color: #339933;">=</span> process.<span style="color: #660066;">env</span>.<span style="color: #660066;">PORT</span> <span style="color: #339933;">||</span> <span style="color: #CC0000;">3000</span><span style="color: #339933;">;</span>
app.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span>port<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Listening on &quot;</span> <span style="color: #339933;">+</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Note that this snippet assumes you&#8217;ve used NPM to install express as outlined above.  You can test the code by running:</p>
<pre>Node.exe client.js</pre>
<p> and browsing to <a href="http://localhost:3000">http://localhost:3000</a>.  </p>
<p>Next, you&#8217;re going to need to create a package.json file to tell Heroku which dependencies your app will need.  The file should look like below (current version of express is 2.5.0, yours might vary).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;your-app-name&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;version&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;0.0.1&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;dependencies&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;express&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;2.5.0&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;mongoskin&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;0.1.3&quot;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>From the directory where your node app lives, run the following command:</p>
<pre>npm install</pre>
<p>Because this command copies dependencies locally into your directory structure, you&#8217;ll want to add the following line to your .gitignore file.  Heroku will use NPM to manage your dependencies on the server side.</p>
<pre>node_modules</pre>
<p>Next, create a file named Procfile (case sensitive) with no extension.  Its content should be:</p>
<pre>web: node client.js</pre>
<p>This file will tell Heroku to start a web process using node to run client.js.  </p>
<p>Next, you&#8217;ll want to create the app on Heroku, using the cedar runtime stack.  The runtime stack is basically just the Heroku environment config (OS, installed libraries, etc.).  </p>
<pre>heroku create --stack cedar</pre>
<p>This will create an app with a unique name, which you can rename to something more meaningful via the following command:</p>
<pre>heroku rename mymeaningfulname</pre>
<p>Heroku also creates a git remote for you, so you can push your code to Heroku.  </p>
<pre>git push heroku master</pre>
<p>One last step to get your app running on Heroku.</p>
<pre>heroku ps:scale web=1</pre>
<p>This command will start a web process, which you can verify is running with the following command:</p>
<pre>heroku ps</pre>
<p>Browse to http://yourmeangingfulname.herokuapp.com to see that your Hello, World! app is indeed running. </p>
<h3>MongoDB and NodeJS</h3>
<p>There are several options for using MongoDB with Node.js.  The <a href="https://github.com/christkv/node-mongodb-native">native driver</a> is accessible via NPM (npm install mongodb).  But don&#8217;t start here.  While the driver is powerful, it requires maddeningly dense code to use.  Your closures will have closures will have closures will have closures&#8230;  </p>
<p><a href="http://mongoosejs.com/">Mongoose</a> looks promising and simpler.  It&#8217;s a full ORM style Document Mapper.  But for a quick start, I prefer <a href="https://github.com/guileen/node-mongoskin">Mongoskin</a>.  It&#8217;s succinct and easy to use.  It doesn&#8217;t offer all of the document mapping features of Mongoose, but I&#8217;m pretty sure it has the lowest barrier to entry for using MongoDB on Node.js.  </p>
<pre>npm install mongoskin</pre>
<p>On Windows, you will likely see a message from NPM that it is &#8220;Not building native library for cygwin&#8221; followed by &#8220;command not found&#8221; and &#8220;unary operator expected&#8221; errors.  I admittedly don&#8217;t know what the cause or meaning of these errors is, but they can be ignored for dev.  </p>
<p>After installing mongoskin, modify your client.js file so it looks like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> express <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'express'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> mongo <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mongoskin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> app <span style="color: #339933;">=</span> express.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span>express.<span style="color: #660066;">logger</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
app.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>request<span style="color: #339933;">,</span> response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> conn <span style="color: #339933;">=</span> mongo.<span style="color: #660066;">db</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mongodb://localhost:27017/yourdbname'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	conn.<span style="color: #660066;">collection</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'users'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toArray</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> items<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span>
&nbsp;
		response.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span>JSON.<span style="color: #660066;">stringify</span><span style="color: #009900;">&#40;</span>items<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> port <span style="color: #339933;">=</span> process.<span style="color: #660066;">env</span>.<span style="color: #660066;">PORT</span> <span style="color: #339933;">||</span> <span style="color: #CC0000;">3000</span><span style="color: #339933;">;</span>
app.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span>port<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Listening on '</span> <span style="color: #339933;">+</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>This code assumes you have MongoDB running locally and that you have a collection named users with at least one document inserted. Restart your server (Ctrl+C your running Node and rerun node client.js).  Browse again to the app and you should see the JSon output.  </p>
<h3>MongoHQ and Heroku</h3>
<p><a href="https://www.mongohq.com/home">MongoHQ</a> is a hosted Mongo solution that offers integration with Heroku.  You can enable it by navigating to your app in the Heroku admin and clicking on &#8220;Add-Ons&#8221; in the upper right hand corner.  There&#8217;s a free version you can get started with (note, this requires a credit card though you&#8217;re not billed).  </p>
<p>Click through to the MongoHQ admin pages and create a user and get your connection string.  Update the line in client.js that creates the connection so it looks something like:</p>
<pre>var conn = mongo.db('mongodb://USER:PASSWORD@SUBDOMAIN.mongohq.com:PORT/DBNAME');</pre>
<p>That should be it.  Now commit and push. </p>
<pre>git add .
git commit -m "Commit message"
git push heroku master</pre>
<p>Browse to your app and you probably see nothing.  Using the MongoHQ admin pages, you can create the &#8220;users&#8221; collection and add a document.  If you do that and refresh, you should see the JSON formatted user document.</p>
<h3>Summary</h3>
<p>Now that Node.js runs on Windows, devs need to take a serious look.  Microsoft is not ignoring this technology and neither should those of us who develop Windows based apps.  This walkthrough hopefully gets you familiar with the tools and technologies you need to get started.  Heroku isn&#8217;t runnign Windows and it certainly isn&#8217;t necessary for running node, but for a sandbox it&#8217;s generally pretty useful to have.</p>
<p>At some point, I plan to get Node and MongoDB running on Azure.  When I do, I&#8217;ll post about that too.</p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2011/11/08/on-getting-started-with-node-js-mongodb-and-heroku-on-windows/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>On Updating Records with Object (Non)Relational Mappers in F#</title>
		<link>http://dllhell.net/2011/08/26/on-updating-records-with-object-non-relational-mappers-in-fsharp/</link>
		<comments>http://dllhell.net/2011/08/26/on-updating-records-with-object-non-relational-mappers-in-fsharp/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 01:59:28 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[fsharp]]></category>
		<category><![CDATA[NoSQL]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=210</guid>
		<description><![CDATA[I&#8217;m delivering a talk on NoSQL and F# at the F# User Group in Cambridge, MA in a few weeks. As I started prepping my old C# and NoSQL presentation for an F# makeover, it didn&#8217;t take long for me &#8230; <a href="http://dllhell.net/2011/08/26/on-updating-records-with-object-non-relational-mappers-in-fsharp/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m delivering a talk on NoSQL and F# at the <a href="http://fsug.org/SitePages/Home.aspx">F# User Group</a> in Cambridge, MA in a few weeks.  As I started prepping my old C# and NoSQL presentation for an F# makeover, it didn&#8217;t take long for me to find some critical differences that more or less fly in the face of common ORM patterns.  </p>
<p>The fetch-modify-update idiom is often used when dealing with updates to a record.  If you consider a form where an Artist record may be edited, the (web) workflow is typically to:</p>
<ol>
<li>Fetch the record for display on an edit form</li>
<li>Re-fetch the record when changes are submitted</li>
<li>Update any properties that were changed by the form (perhaps with MVVM and AutoMapper)</li>
<li>Save the record that was fetched and updated</li>
</ol>
<p>In abbreviated code, this might look like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">var artists <span style="color: #008000;">=</span> _mongoDatabase<span style="color: #008000;">.</span><span style="color: #0000FF;">GetCollection</span><span style="color: #008000;">&lt;</span>Artist<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>COLLECTION<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
var artist <span style="color: #008000;">=</span> artists<span style="color: #008000;">.</span><span style="color: #0000FF;">Find</span><span style="color: #008000;">&#40;</span>Query<span style="color: #008000;">.</span><span style="color: #0000FF;">FindOne</span><span style="color: #008000;">&#40;</span>Query<span style="color: #008000;">.</span><span style="color: #0000FF;">EQ</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;_id&quot;</span>, id<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
artist<span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span> <span style="color: #008000;">=</span> viewModel<span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span><span style="color: #008000;">;</span>
artists<span style="color: #008000;">.</span><span style="color: #0000FF;">Save</span><span style="color: #008000;">&#40;</span>artist<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>This pattern works well with ORMs such as the Entity Framework and NHibnerate.  It also works with O(Non)RMs such as the MongoDB C# driver, which is shown in the code above.  Again, the idea is to retrieve a record, modify some properties and save it back to the database, whether relational or NoSQL.  However, this pattern breaks one of the core functional programming concepts, namely immutability.  </p>
<p>As I sat down with the F# equivalent of my NoSQL demoware, I had a choice to make.  I could take advantage of F#&#8217;s multi-paradigm language features and simply allow for mutable Artist instances or I could work through the problem using immutability.  I chose the latter option, which I&#8217;ll describe below.  But first, I&#8217;ll note that this post is certainly geared towards C# developers who are new to F#.  F# developers probably don&#8217;t get too hung up on value bindings vs. variables as I do.  </p>
<p>The code in F# is still only 4 lines, but there are a couple of notable differences.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">let artists <span style="color: #008000;">=</span> mongoDatabase<span style="color: #008000;">.</span><span style="color: #0000FF;">GetCollection</span><span style="color: #008000;">&lt;</span>Artist<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Artists&quot;</span><span style="color: #008000;">&#41;</span>
let artist <span style="color: #008000;">=</span> artists<span style="color: #008000;">.</span><span style="color: #0000FF;">Find</span><span style="color: #008000;">&#40;</span>Query<span style="color: #008000;">.</span><span style="color: #0000FF;">FindOne</span><span style="color: #008000;">&#40;</span>Query<span style="color: #008000;">.</span><span style="color: #0000FF;">EQ</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;_id&quot;</span>, id<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
let updatedArtist <span style="color: #008000;">=</span> <span style="color: #008000;">&#123;</span> artist with Name <span style="color: #008000;">=</span> viewModel<span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span> <span style="color: #008000;">&#125;</span>
mongoCollection<span style="color: #008000;">.</span><span style="color: #0000FF;">Save</span><span style="color: #008000;">&#40;</span>updatedArtist<span style="color: #008000;">&#41;</span> <span style="color: #008000;">|&gt;</span> ignore</pre></td></tr></table></div>

<p>The requirement that artist be immutable leads to the use of an F# record.  An F# record is sort of like an anonymous class in C# (no constructor or methods), but it has a name and has built in facilities for copying one record to another.  That copying facility is what is demonstrated on the third F# line.  The updatedArtist value is a member for member copy of the artist, except for the Name property that is set to the view model&#8217;s name property.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">type Artist <span style="color: #008000;">=</span> <span style="color: #008000;">&#123;</span> Name <span style="color: #008000;">:</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">;</span> Genre <span style="color: #008000;">:</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">;</span> Id <span style="color: #008000;">:</span> ObjectId <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Records seem to work particularly well with ORMs and O(Non)RMs where POCOs are used to represent database records, whether documents or table rows.  </p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2011/08/26/on-updating-records-with-object-non-relational-mappers-in-fsharp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Creating an Orchard Module without Having to RTFM</title>
		<link>http://dllhell.net/2011/08/15/on-creating-an-orchard-module-without-having-to-rtfm/</link>
		<comments>http://dllhell.net/2011/08/15/on-creating-an-orchard-module-without-having-to-rtfm/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 17:37:28 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[orchard]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=176</guid>
		<description><![CDATA[Recently, I created my first Orchard module. Of course, rather than read the manual, I learned by copying the code for an existing plugin. So if you&#8217;re like me and you take a code-first approach to learning, read on as &#8230; <a href="http://dllhell.net/2011/08/15/on-creating-an-orchard-module-without-having-to-rtfm/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently, I created my first Orchard module.  Of course, rather than read the <a href="http://orchardproject.net/docs/Creating-a-module-with-a-simple-text-editor.ashx">manual</a>, I learned by copying the code for an existing plugin.  So if you&#8217;re like me and you take a code-first approach to learning, read on as I&#8217;m going to document my experience below.  Again, I haven&#8217;t RTFM (yet).  So assume that some of what I&#8217;m writing is either incomplete or wrong.  But the code works (or appears to be working).  So I must have gotten something right&#8230;</p>
<p>The module I created was a wrapper around LinkedIn&#8217;s <a href="http://developer.linkedin.com/plugins/member-profile-plugin">Member Profile widget</a>.  The module that I modeled my module after was the Facebook.Like module by the Orchard team.  Both modules are basically wrappers around JavaScript includes.  </p>
<p>I found it easiest to develop within the context of the Orchard source code, even though not entirely necessary.  Either <a href="http://orchard.codeplex.com/releases/view/65184">download</a> the source or clone <a href="https://hg01.codeplex.com/orchard">the repository</a>.  Setup an application in IIS that points to the Orchard.Web directory. After compiling the solution, you should be able to browse to Orchard and start setting up the site.</p>
<p>Modules are MVC apps.  Start by creating an empty ASP.NET MVC 3 project, choosing Razor as the view engine.  Save the new project to the Modules directory under the Orchard.Web directory.  Clean out any of the superfluous scripts or styles.  Add a reference to Orchard.Framework and Orchard.Core.  </p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/08/solution.png"><img src="http://dllhell.net/wp-content/uploads/2011/08/solution-138x300.png" alt="" title="solution" width="138" height="300" class="alignnone size-medium wp-image-196" /></a></p>
<p>Basically, what my module needs to do is capture the five possible pieces of information that must be passed to the LinkedIn scripts:</p>
<ol>
<li>Public profile URL</li>
<li>Display mode (inline, icon and name, icon)</li>
<li>Display text (displayed with the icon and name mode)</li>
<li>Display behavior (on click or on hover)</li>
<li>Whether to show connections</li>
</ol>
<p>So these five pieces of information will be used to create the model for the module.  This model will be used to create the module&#8217;s backing table, the editor template and the module&#8217;s view.  </p>
<p>The first piece to create in the module is the actual model class.  In my case, the model is the Profile (Profile.cs in the Models directory).  There are actually two models to create, one is a subclass of ContentPartRecord and one a subclass of ContentPart.  </p>
<p>The ContentPartRecord is basically the class that represents the database schema.  Again, I need to read more, but I can say from a couple of YSODs that a ProfilePartRecord class needs to have properties that match column names and all properties must be marked virtual.  I believe the virtual requirement is related to NHibernate being used for data access, but it could be something else with DynamicProxy.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> ProfilePartRecord <span style="color: #008000;">:</span> ContentPartRecord <span style="color: #008000;">&#123;</span>
&nbsp;
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">virtual</span> <span style="color: #6666cc; font-weight: bold;">string</span> ProfileUrl <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">virtual</span> <span style="color: #6666cc; font-weight: bold;">string</span> DisplayText <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">virtual</span> <span style="color: #6666cc; font-weight: bold;">string</span> DisplayBehavior <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">virtual</span> <span style="color: #6666cc; font-weight: bold;">string</span> DisplayMode <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">virtual</span> <span style="color: #6666cc; font-weight: bold;">bool</span> ShowConnections <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF; font-weight: bold;">public</span> ProfilePartRecord<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		DisplayBehavior <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;hover&quot;</span><span style="color: #008000;">;</span>
		DisplayMode <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;inline&quot;</span><span style="color: #008000;">;</span>
		ShowConnections <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>The ContentPart is essentially the view model for the module.  It&#8217;s the class that gets bound to the editor template and the actual module view template.  There won&#8217;t always be a one-to-one mapping between the ContentRecordPart and ContentPart, but in the case of my LinkedIn.Profile module, there was.  However, as I write this explanation, I suspect I could/should change that correspondence.  Note the use of the DataAnnotations validation attributes.  The editor template will make use of these.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> ProfilePart <span style="color: #008000;">:</span> ContentPart<span style="color: #008000;">&lt;</span>ProfilePartRecord<span style="color: #008000;">&gt;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
	<span style="color: #008000;">&#91;</span>Required<span style="color: #008000;">&#93;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> ProfileUrl <span style="color: #008000;">&#123;</span>
		get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">ProfileUrl</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
		set <span style="color: #008000;">&#123;</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">ProfileUrl</span> <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #008000;">&#91;</span>Required<span style="color: #008000;">&#93;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> DisplayText <span style="color: #008000;">&#123;</span>
		get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayText</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
		set <span style="color: #008000;">&#123;</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayText</span> <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #008000;">&#91;</span>Required<span style="color: #008000;">&#93;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> DisplayBehavior <span style="color: #008000;">&#123;</span>
		get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayBehavior</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
		set <span style="color: #008000;">&#123;</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayBehavior</span> <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #008000;">&#91;</span>Required<span style="color: #008000;">&#93;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> DisplayMode <span style="color: #008000;">&#123;</span>
		get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayMode</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
		set <span style="color: #008000;">&#123;</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayMode</span> <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">bool</span> ShowConnections <span style="color: #008000;">&#123;</span>
		get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">ShowConnections</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
		set <span style="color: #008000;">&#123;</span> Record<span style="color: #008000;">.</span><span style="color: #0000FF;">ShowConnections</span><span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Once the model is created, the rest of the module dependencies can be filled in.  The database migration probably makes sense as a next step.  A Migrations.cs file at the root of the project contains the Migrations class, which subclasses DataMigrationImpl.  If you&#8217;re not familiar with the concept of database migrations, I <a href="http://dllhell.net/2009/02/11/on-database-migrations-in-net/">wrote about them</a> in .NET a couple of years ago.  Basically, you create a class that represents a schema change to the database.  In the case of Orchard, Migrations use a Create method to add a table to the schema.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Migrations <span style="color: #008000;">:</span> DataMigrationImpl <span style="color: #008000;">&#123;</span>
&nbsp;
	<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> Create<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
		SchemaBuilder<span style="color: #008000;">.</span><span style="color: #0000FF;">CreateTable</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ProfilePartRecord&quot;</span>, table <span style="color: #008000;">=&gt;</span> table
			<span style="color: #008000;">.</span><span style="color: #0000FF;">ContentPartRecord</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">.</span><span style="color: #0000FF;">Column</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ProfileUrl&quot;</span>, DbType<span style="color: #008000;">.</span><span style="color: #6666cc; font-weight: bold;">String</span><span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">.</span><span style="color: #0000FF;">Column</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;DisplayText&quot;</span>, DbType<span style="color: #008000;">.</span><span style="color: #6666cc; font-weight: bold;">String</span><span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">.</span><span style="color: #0000FF;">Column</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;DisplayBehavior&quot;</span>, DbType<span style="color: #008000;">.</span><span style="color: #6666cc; font-weight: bold;">String</span><span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">.</span><span style="color: #0000FF;">Column</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;DisplayMode&quot;</span>, DbType<span style="color: #008000;">.</span><span style="color: #6666cc; font-weight: bold;">String</span><span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">.</span><span style="color: #0000FF;">Column</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ShowConnections&quot;</span>, DbType<span style="color: #008000;">.</span><span style="color: #0000FF;">Boolean</span><span style="color: #008000;">&#41;</span>                
		<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		ContentDefinitionManager<span style="color: #008000;">.</span><span style="color: #0000FF;">AlterPartDefinition</span><span style="color: #008000;">&#40;</span>
			<span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>ProfilePart<span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span>, cfg <span style="color: #008000;">=&gt;</span> cfg<span style="color: #008000;">.</span><span style="color: #0000FF;">Attachable</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
	<span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #008000;">...</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>The table and column names must map to the model&#8217;s ContentPartRecord subclass.  If you&#8217;re worried about collisions, you don&#8217;t need to.  Tables are prefixed (with the namespace I think).  I admit, I am not sure what the call to AlterPartDefinition with the lambda is doing, but it was in the Facebook.Like module.  So I assume it&#8217;s necessary.  Remember, I said I didn&#8217;t RTFM&#8230;  I&#8217;m also not clear what the widget mapping in the migration does either, but again, it was in the Facebook.Like and appears to be meaningful.  I&#8217;ll eventually look into these items.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">   <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> UpdateFrom1<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		<span style="color: #008080; font-style: italic;">// Create a new widget content type with our map</span>
		ContentDefinitionManager<span style="color: #008000;">.</span><span style="color: #0000FF;">AlterTypeDefinition</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;LinkedInProfileWidget&quot;</span>, cfg <span style="color: #008000;">=&gt;</span> cfg
			<span style="color: #008000;">.</span><span style="color: #0000FF;">WithPart</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ProfilePart&quot;</span><span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">.</span><span style="color: #0000FF;">WithPart</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;WidgetPart&quot;</span><span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">.</span><span style="color: #0000FF;">WithPart</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;CommonPart&quot;</span><span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">.</span><span style="color: #0000FF;">WithSetting</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Stereotype&quot;</span>, <span style="color: #666666;">&quot;Widget&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span>
	<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>The next piece that needs to be included is the content part driver.  Under Drivers, I have ProfileDriver.cs.  ProfileDriver is a subclass of ContentPartDriver.  Basically, this class is what gets data to the templates.  ProfileDriver overrides Display and two Editor methods.  In the Display method, the ProfilePart is mapped to a dynamic, which becomes the model for the module&#8217;s display view.  The Editor methods provide a means for locating and displaying the editor template and saving changes, both within the context of the admin pages.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> ProfileDriver <span style="color: #008000;">:</span> ContentPartDriver<span style="color: #008000;">&lt;</span>ProfilePart<span style="color: #008000;">&gt;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> DriverResult Display<span style="color: #008000;">&#40;</span>ProfilePart part, <span style="color: #6666cc; font-weight: bold;">string</span> displayType, dynamic shapeHelper<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span> 
		<span style="color: #0600FF; font-weight: bold;">return</span> ContentShape<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Parts_Profile&quot;</span>,
			<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">=&gt;</span> shapeHelper<span style="color: #008000;">.</span><span style="color: #0000FF;">Parts_Profile</span><span style="color: #008000;">&#40;</span>ProfileUrl<span style="color: #008000;">:</span> part<span style="color: #008000;">.</span><span style="color: #0000FF;">ProfileUrl</span>,
											DisplayText<span style="color: #008000;">:</span> part<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayText</span>,
											DisplayBehavior<span style="color: #008000;">:</span> part<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayBehavior</span>,
											DisplayMode<span style="color: #008000;">:</span> part<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayMode</span>,
											ShowConnections<span style="color: #008000;">:</span> part<span style="color: #008000;">.</span><span style="color: #0000FF;">ShowConnections</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> DriverResult Editor<span style="color: #008000;">&#40;</span>ProfilePart part, dynamic shapeHelper<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		<span style="color: #0600FF; font-weight: bold;">return</span> ContentShape<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Parts_Profile_Edit&quot;</span>,
			<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">=&gt;</span> shapeHelper<span style="color: #008000;">.</span><span style="color: #0000FF;">EditorTemplate</span><span style="color: #008000;">&#40;</span>
				TemplateName<span style="color: #008000;">:</span> <span style="color: #666666;">&quot;Parts/Profile&quot;</span>,
				Model<span style="color: #008000;">:</span> part,
				Prefix<span style="color: #008000;">:</span> Prefix<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> DriverResult Editor<span style="color: #008000;">&#40;</span>ProfilePart part, IUpdateModel updater, dynamic shapeHelper<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		updater<span style="color: #008000;">.</span><span style="color: #0000FF;">TryUpdateModel</span><span style="color: #008000;">&#40;</span>part, Prefix, <span style="color: #0600FF; font-weight: bold;">null</span>, <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
		<span style="color: #0600FF; font-weight: bold;">return</span> Editor<span style="color: #008000;">&#40;</span>part, shapeHelper<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>In the Handlers namespace, the ProfileHandler extends ContentHandler.  Content handlers define what happens to a content part during certain events, such as OnActivated and OnLoading.  In the case of the ProfileHandler in my LinkedIn project, none of these events is used.  The only code in the handler is that which adds the repository dependency to the Filters collection of the handler.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> ProfileHandler <span style="color: #008000;">:</span> ContentHandler
<span style="color: #008000;">&#123;</span>
	<span style="color: #0600FF; font-weight: bold;">public</span> ProfileHandler<span style="color: #008000;">&#40;</span>IRepository<span style="color: #008000;">&lt;</span>ProfilePartRecord<span style="color: #008000;">&gt;</span> repository<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		Filters<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>StorageFilter<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">For</span><span style="color: #008000;">&#40;</span>repository<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>In terms of actual code, that&#8217;s it.  The next step is to create the Razor templates.  Under Views/EditorTemplates/Parts is Profile.cshtml.  This is simply a CRUD form that will be loaded in the admin pages.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">@model LinkedIn<span style="color: #008000;">.</span><span style="color: #0000FF;">Profile</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Models</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ProfilePart</span>
&nbsp;
<span style="color: #008000;">&lt;</span>fieldset<span style="color: #008000;">&gt;</span>
  <span style="color: #008000;">&lt;</span>legend<span style="color: #008000;">&gt;</span>LinkedIn Profile Widget<span style="color: #008000;">&lt;/</span>legend<span style="color: #008000;">&gt;</span>
&nbsp;
  <span style="color: #008000;">&lt;</span>div <span style="color: #6666cc; font-weight: bold;">class</span><span style="color: #008000;">=</span><span style="color: #666666;">&quot;editor-label&quot;</span><span style="color: #008000;">&gt;</span>
    @Html<span style="color: #008000;">.</span><span style="color: #0000FF;">LabelFor</span><span style="color: #008000;">&#40;</span>model <span style="color: #008000;">=&gt;</span> model<span style="color: #008000;">.</span><span style="color: #0000FF;">ProfileUrl</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&lt;/</span>div<span style="color: #008000;">&gt;</span>
  <span style="color: #008000;">&lt;</span>div <span style="color: #6666cc; font-weight: bold;">class</span><span style="color: #008000;">=</span><span style="color: #666666;">&quot;editor-field&quot;</span><span style="color: #008000;">&gt;</span>
    @Html<span style="color: #008000;">.</span><span style="color: #0000FF;">TextBoxFor</span><span style="color: #008000;">&#40;</span>model <span style="color: #008000;">=&gt;</span> model<span style="color: #008000;">.</span><span style="color: #0000FF;">ProfileUrl</span><span style="color: #008000;">&#41;</span>
    @Html<span style="color: #008000;">.</span><span style="color: #0000FF;">ValidationMessageFor</span><span style="color: #008000;">&#40;</span>model <span style="color: #008000;">=&gt;</span> model<span style="color: #008000;">.</span><span style="color: #0000FF;">ProfileUrl</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&lt;/</span>div<span style="color: #008000;">&gt;</span>          
&nbsp;
  <span style="color: #008000;">...</span>
&nbsp;
  <span style="color: #008000;">&lt;</span>div <span style="color: #6666cc; font-weight: bold;">class</span><span style="color: #008000;">=</span><span style="color: #666666;">&quot;editor-label&quot;</span><span style="color: #008000;">&gt;</span>
    @Html<span style="color: #008000;">.</span><span style="color: #0000FF;">LabelFor</span><span style="color: #008000;">&#40;</span>model <span style="color: #008000;">=&gt;</span> model<span style="color: #008000;">.</span><span style="color: #0000FF;">ShowConnections</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&lt;/</span>div<span style="color: #008000;">&gt;</span>
  <span style="color: #008000;">&lt;</span>div <span style="color: #6666cc; font-weight: bold;">class</span><span style="color: #008000;">=</span><span style="color: #666666;">&quot;editor-field&quot;</span><span style="color: #008000;">&gt;</span>
    @Html<span style="color: #008000;">.</span><span style="color: #0000FF;">CheckBoxFor</span><span style="color: #008000;">&#40;</span>model <span style="color: #008000;">=&gt;</span> model<span style="color: #008000;">.</span><span style="color: #0000FF;">ShowConnections</span><span style="color: #008000;">&#41;</span>
    @Html<span style="color: #008000;">.</span><span style="color: #0000FF;">ValidationMessageFor</span><span style="color: #008000;">&#40;</span>model <span style="color: #008000;">=&gt;</span> model<span style="color: #008000;">.</span><span style="color: #0000FF;">ShowConnections</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&lt;/</span>div<span style="color: #008000;">&gt;</span>
&nbsp;
<span style="color: #008000;">&lt;/</span>fieldset<span style="color: #008000;">&gt;</span></pre></td></tr></table></div>

<p>The Views/Parts/Profile.cshtml template is where the LinkedIn scripts are loaded in.  Right now, I have the model setup to reflect the different settings, but some settings are mutually exclusive.  Until I have a chance to update the UI to reflect these mutual exclusions, I have some hacky logic to determine which script to load.  The logic is:</p>
<ul>
<li>If the display mode is inline, everything shows and there is no need for hover or click behavior</li>
<li>Else If the display mode is icon, show the icon only (no name) and set hover or click behavior as set in the admin tools </li>
<li>Else same as Else If, but include the display text (typically person&#8217;s name)</li>
</ul>
<p>This logic could be tighter and I&#8217;ll eventually update the ProfilePart to be more in line with how the scripts render.  But for now, it&#8217;s simple and works.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">&lt;</span>script src<span style="color: #008000;">=</span><span style="color: #666666;">&quot;http://platform.linkedin.com/in.js&quot;</span> type<span style="color: #008000;">=</span><span style="color: #666666;">&quot;text/javascript&quot;</span><span style="color: #008000;">&gt;&lt;/</span>script<span style="color: #008000;">&gt;</span>
@<span style="color: #0600FF; font-weight: bold;">if</span><span style="color: #008000;">&#40;</span>@Model<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayMode</span> <span style="color: #008000;">==</span> <span style="color: #666666;">&quot;inline&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&lt;</span>script type<span style="color: #008000;">=</span><span style="color: #666666;">&quot;IN/MemberProfile&quot;</span> data<span style="color: #008000;">-</span>id<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.ProfileUrl&quot;</span> data<span style="color: #008000;">-</span>format<span style="color: #008000;">=</span><span style="color: #666666;">&quot;inline&quot;</span> related<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.ShowConnections.ToString().ToLower()&quot;</span><span style="color: #008000;">&gt;&lt;/</span>script<span style="color: #008000;">&gt;</span>
<span style="color: #008000;">&#125;</span> 
<span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>@Model<span style="color: #008000;">.</span><span style="color: #0000FF;">DisplayMode</span> <span style="color: #008000;">==</span> <span style="color: #666666;">&quot;icon&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&lt;</span>script type<span style="color: #008000;">=</span><span style="color: #666666;">&quot;IN/MemberProfile&quot;</span> data<span style="color: #008000;">-</span>id<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.ProfileUrl&quot;</span> data<span style="color: #008000;">-</span>format<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.DisplayBehavior&quot;</span> related<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.ShowConnections.ToString().ToLower()&quot;</span><span style="color: #008000;">&gt;&lt;/</span>script<span style="color: #008000;">&gt;</span>    
<span style="color: #008000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #008000;">&#123;</span> 
<span style="color: #008000;">&lt;</span>script type<span style="color: #008000;">=</span><span style="color: #666666;">&quot;IN/MemberProfile&quot;</span> data<span style="color: #008000;">-</span>id<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.ProfileUrl&quot;</span> data<span style="color: #008000;">-</span>format<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.DisplayBehavior&quot;</span> data<span style="color: #008000;">-</span>text<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.DisplayText&quot;</span> related<span style="color: #008000;">=</span><span style="color: #666666;">&quot;@Model.ShowConnections.ToString().ToLower()&quot;</span><span style="color: #008000;">&gt;&lt;/</span>script<span style="color: #008000;">&gt;</span>          
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>The placement.info file in the root of the the project contains a chunk of XML used to place the Profile templates within the broader template structure of the site.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Placement<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Place</span> <span style="color: #000066;">Parts_Profile</span>=<span style="color: #ff0000;">&quot;Content:10&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Place</span> <span style="color: #000066;">Parts_Profile_Edit</span>=<span style="color: #ff0000;">&quot;Content:7.5&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Placement<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>Finally, the Module.txt contains information used by the admin pages to link the module to the listing of installed modules.  Here you define items like the author, dependencies, name and website for the module.</p>
<pre>
Name: LinkedIn.Profile
AntiForgery: enabled
Author: John Zablocki
Website: http://bitbucket.org/johnzablocki/orchardlinkedinprofile
Version: 0.1
OrchardVersion: 1.0
Description: This a module for using the LinkedIn Profile widget
Features:
    LinkedIn.Profile:
		Name: LinkedIn Profile
        Description: LinkedIn Profile widgets.
		Category: Widget
		Dependencies: Orchard.Widgets
</pre>
<p>If you have been playing along at home, you can now test out the module.  After you&#8217;ve built the solution, you can navigate to your local site.  In the admin dashboard, LinkedIn.Profile should show up on the list of installed modules (Installed tab of Modules page).  </p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/08/installed.png"><img src="http://dllhell.net/wp-content/uploads/2011/08/installed-300x72.png" alt="" title="installed" width="300" height="72" class="alignnone size-medium wp-image-198" /></a></p>
<p>If you click the name of the module (LinkedIn.Profile) you should be taken to the Features tab of the Modules page, anchored at the LinkedIn.Profile module.  Click enable.  </p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/08/features.png"><img src="http://dllhell.net/wp-content/uploads/2011/08/features-300x49.png" alt="" title="features" width="300" height="49" class="alignnone size-medium wp-image-199" /></a></p>
<p>Navigate next to Widgets.  Click &#8220;Add&#8221; in any one of the content areas.  </p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/08/widgets.png"><img src="http://dllhell.net/wp-content/uploads/2011/08/widgets-300x89.png" alt="" title="widgets" width="300" height="89" class="alignnone size-medium wp-image-201" /></a></p>
<p>LinkedIn.Profile should be an option.  Click through and you should see the form you created under EditorTemplates.  </p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/08/editor.png"><img src="http://dllhell.net/wp-content/uploads/2011/08/editor-93x300.png" alt="" title="editor" width="93" height="300" class="alignnone size-medium wp-image-202" /></a></p>
<p>Fill out the values and view your home page.  You should then see the LinkedIn Profile widget.  </p>
<p><a href="http://dllhell.net/wp-content/uploads/2011/08/widget-final.png"><img src="http://dllhell.net/wp-content/uploads/2011/08/widget-final-300x212.png" alt="" title="widget-final" width="300" height="212" class="alignnone size-medium wp-image-203" /></a></p>
<p>Well that&#8217;s an Orchard Module in a nutshell.  This example is hardly the most complex, but it illustrates several basic concepts of putting a module together from scratch.  I should also note that there are some command line tools included with Orchard to help automate some of the project setup.  I think they&#8217;re part of the Web Platform Installer.  Honestly, I haven&#8217;t tried them yet.  </p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2011/08/15/on-creating-an-orchard-module-without-having-to-rtfm/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>On Free Orchard Hosting with Bitbucket and AppHarbor</title>
		<link>http://dllhell.net/2011/08/10/on-free-orchard-hosting-with-bitbucket-and-appharbor/</link>
		<comments>http://dllhell.net/2011/08/10/on-free-orchard-hosting-with-bitbucket-and-appharbor/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 16:11:21 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[appharbor]]></category>
		<category><![CDATA[bitbucket]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[orchard]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=160</guid>
		<description><![CDATA[If you&#8217;re not familiar with the Orchard Project, you should be. Orchard is an open source, mostly-CMS framework built on top of ASP.NET MVC. I say mostly-CMS because the project has goals of becoming more of a generalized component framework. &#8230; <a href="http://dllhell.net/2011/08/10/on-free-orchard-hosting-with-bitbucket-and-appharbor/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re not familiar with the <a href="http://orchardproject.net/">Orchard Project</a>, you should be.  Orchard is an open source, mostly-CMS framework built on top of ASP.NET MVC.  I say mostly-CMS because the project has goals of becoming more of a generalized component framework.  </p>
<p>I first saw Orchard in action at the <a href="http://nycgivecamp.org/">NYC GiveCamp</a>.  One of the teams built out a site for a charity using Orchard, which at that point had been released for about a week (I think).  As a CMS, it&#8217;s reasonably feature rich.  It&#8217;s not quite WordPress yet, but it&#8217;s more than adequate for use in a typical content heavy site.</p>
<p>I&#8217;m working on starting an ALT.NET group up here in Boston &#8211; Beantown ALT.NET.  My first efforts with getting the group off the ground were of course to buy a domain and put up a site.  I grabbed the domain beantownalt.net (bostonalt.net was taken) from <a href="http://www.namecheap.com?aff=21463">Namecheap</a>, since <a href="http://www.huffingtonpost.com/2011/03/31/bob-parsons-godaddy-ceo-elephant-hunt_n_843121.html">Bob Parsons is sick individual</a>.  </p>
<p>For the site, I considered the usual suspects.  I know <a href="http://fairfieldwestchester.net/">Fairfield/Westchester .NET</a> uses WordPress.  But running an ALT.NET site on a PHP app didn&#8217;t feel right.  I think that group used to run on Dot Net Nuke, but running an ALT.NET site on VB.NET is worse than running it on PHP!  I also considered <a href="https://bitbucket.org/johnzablocki/meringue/overview">Meringue</a>, since I know the developer.  But it doesn&#8217;t have the module support I wanted.  </p>
<p>Ultimately, Orchard was an easy choice. It&#8217;s built on MVC and <a href="http://orchardproject.net/docs/Orchard-dependencies-and-libraries.ashx">lots of ALT.NET technologies</a>, such as <a href="http://code.google.com/p/autofac/">Autofac</a> and <a href="http://nhforge.org/">NHibernate</a>.</p>
<p>At first, I setup BeantownALT.NET on a hosted VPS (damn impulse purchases) that I have.  But I can&#8217;t really justify the cost of that server for the demoware that I host there.  So I&#8217;m going to move the sites on that box to a cheaper solution, namely <a href="http://www.appharbor.com">AppHarbor</a>.</p>
<p>AppHarbor is <a href="http://www.heroku.com/">Heroku</a> for .NET.  You commit your code to either a Mercurial or Git repository then push it to AppHarbor.  AppHarbor then builds your solution, runs your tests and viola, your app is live in the cloud.  It&#8217;s really that simple.  In fact it&#8217;s so simple, I&#8217;m going to move Beantown ALT.NET&#8217;s website to AppHarbor as I write this post.</p>
<p>First things first.  You&#8217;ll need to grab the Orchard bits.  You can grab them from CodePlex <a href="http://orchard.codeplex.com/releases/view/65184">here</a>.  I&#8217;m just grabbing the web zip as I&#8217;m going to push the prebuilt web package to a Mercurial repository setup on Bitbucket.</p>
<p>OK, so <a href="http://www.bitbucket.org">Bitbucket</a>&#8230;  If you&#8217;re a Windows developer and you&#8217;re using Git and GitHub, I have to ask why.  The Windows experience with <a href="http://mercurial.selenic.com/">Mercurial</a> is simply cleaner.  More importantly, Bitbucket offers Free private repositories.  That&#8217;s right, free and private.  GitHub doesn&#8217;t offer that.  I know, I know&#8230;  Rails is hosted at GitHub, so everyone uses it.  Get over it and get some free repositories devs!</p>
<p>Anyway, so once you&#8217;ve done the sensible thing and signed up for Bitbucket, create a new repository and clone it locally.  </p>
<pre>hg clone https://username@bitbucket.org/username/project project</pre>
<p>Back to Orchard&#8230;  You could try to get the source code and set it up to build at AppHarbor, but really there&#8217;s no need to do that.  If you do that, start by renaming Orchard.sln to AppHarbor.sln so that AppHarbor can disambiguate which solution to build (Orchard has a few in the source tree).  Getting the Orchard source to build is a topic for a different post.  </p>
<p>Since you&#8217;ll likely just be using your Orchard site for content management, just download the web files zip instead.  This package has the compiled bits ready to be deployed.  Extract those files to your Mercurial repository.  Once you do that, move the files out of the Orchard directory into the root of your repository (sibling with the .hg directory).  You need to move these files since we&#8217;re pushing only content and this is the website root.  </p>
<p>Your repository should look something like:</p>
<pre>
/yourproject
     /.hg
     /App_Data
     /bin
     /Config
     /Core
     /Media
     /Modules
     /Themes
     /.hgignore
     /Global.asax
     /install.sql
     /Refresh.html
     /Web.config
</pre>
<p>Now go ahead and hg add and hg commit the source files.  <strong>If you have an .hgignore file setup to ignore your bin directories, you&#8217;ll need to reverse that here.</strong>  Remember, this is the prebuilt Orchard and you&#8217;re going to want to have the binaries deployed as well.</p>
<p>Next login to AppHarbor (assuming you&#8217;ve already signed up).  Create a new application and click into its properties pages (just click on the name of the app on the left hand side of the top navigation bar).  Under the repository URL, you should see a link &#8220;Create build URL: (show/hide).&#8221;  Click show/hide and copy the link that appears.  Also, while in AppHarbor, click on &#8220;Settings&#8221; and check the option to allow write access, as Orchard will need this setting to manage modules and the like.</p>
<p>Next, you&#8217;ll need to navigate to the &#8220;Admin&#8221; tab for your repository on Bitbucket.  Look for the &#8220;Additional options/settings&#8221; widget and click &#8220;Services.&#8221;  Select &#8220;POST&#8221; from the list and paste the build URL from AppHarbor.  Save the changes.  You&#8217;ve now wired Bitbucket to AppHarbor.  Also, in the admin section, find the &#8220;User access&#8221; widget and give read access to the &#8220;apphb&#8221; user.  Don&#8217;t miss this step or it won&#8217;t work!  Every push to Bitbucket will now trigger a build at AppHarbor.  Yes, it&#8217;s that easy&#8230;</p>
<p>Go ahead and push your changes to Bitbucket.  Once the commit is complete, you should see a &#8220;Builds&#8221; section appear in your application&#8217;s properties pages at AppHarbor.  You&#8217;ll also see a list of Application URLs.  Navigate to one and you should see the setup page for your new Orchard site.  </p>
<p>At AppHarbor, on the property pages for your application, you can add a SQL database.  When you create that database, copy the connection string and paste it into the form for creating your site.  Once you hit submit, you&#8217;re in Orchard.  </p>
<p>So that&#8217;s it.  Free hosting for your Orchard site (assuming you can stay within the pretty generous free limits), deployed via Mercurial.  Kind of awesome, right?  </p>
<p>Oh yeah, the one thing I should definitely mention is that all builds are clean!  What this means is that each time you hg push, you get a clean deploy of Orchard, meaning your settings will be lost.  So you have one of two options.  The first option is not to push again.  Manage your site and updates through Orchard.  This option is how I plan to work.  Option two is to run your site locally, make updates locally, add content locally, etc.  You should be able to connect to your AppHarbor DB locally.  Then just push your code when its ready to go live.</p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2011/08/10/on-free-orchard-hosting-with-bitbucket-and-appharbor/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>On a Quick and Dirty Asynchronous Python Client for SimpleGeo</title>
		<link>http://dllhell.net/2011/05/10/on-a-quick-and-dirty-asynchronous-python-client-for-simplegeo/</link>
		<comments>http://dllhell.net/2011/05/10/on-a-quick-and-dirty-asynchronous-python-client-for-simplegeo/#comments</comments>
		<pubDate>Tue, 10 May 2011 02:14:37 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[simplegeo]]></category>
		<category><![CDATA[Tornado]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=122</guid>
		<description><![CDATA[SimpleGeo maintains a Python client library that is both easy to use and feature complete (in terms of API coverage). Searching by long/lat is demonstrated below: 1 2 3 4 5 from simplegeo import Client client = Client&#40;&#34;KEY&#34;, &#34;SECRET&#34;&#41; places &#8230; <a href="http://dllhell.net/2011/05/10/on-a-quick-and-dirty-asynchronous-python-client-for-simplegeo/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>SimpleGeo maintains a Python client library that is both easy to use and feature complete (in terms of API coverage).  Searching by long/lat is demonstrated below:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> simplegeo <span style="color: #ff7700;font-weight:bold;">import</span> Client
client = Client<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;KEY&quot;</span>, <span style="color: #483d8b;">&quot;SECRET&quot;</span><span style="color: black;">&#41;</span>
places = client.<span style="color: black;">places</span>
features = client.<span style="color: black;">places</span>.<span style="color: black;">search</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">41.773847</span>,-<span style="color: #ff4500;">72.672477</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> features<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">properties</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>The client library performs two basic tasks, wrapping the API call along with its HTTP/OAuth internals and deserializing the JSon response into domain objects.  While the JSon deserialization will likely prove plenty robust for most scenarios, there is a case where the client&#8217;s HTTP component is insufficient.  The specific scenario occurs when working with an evented I/O web server like Tornado.</p>
<p>Tornado is a single-threaded web server that relies on non-blocking I/O and callbacks to handle large (thousands) of concurrent requests with minimal overhead.  For more on evented I/O web servers, see <a href="http://codevoyeur.com/presentations.aspx#tornado">http://codevoyeur.com/presentations.aspx#tornado</a>.  The important thing to understand about this class of web servers is that any synchronous code you run on that single thread will block all other requests.  </p>
<p>SimpleGeo’s Python client uses the httplib2 Python module, which is a blocking client.  In other words, when a request is made to SimpleGeo, Tornado cannot handle any other requests until the request completes.  While SimpleGeo certainly seems to have infrastructure in place to handle large volumes, it’s still unwise to block requests while attempting to gain access to a network resource.</p>
<p>Fortunately, Tornado includes an asynchronous HTTP client that uses its non-blocking socket library.  I’ve started to rewrite pieces of the SimpleGeo Python client to use Tornado’s AsyncHTTPClient.  I’ll walk through these changes below.</p>
<p>First, I thinks it’s reasonable to leave as much of the original SimpleGeo code in place.  With that in mind, I keep a dependency on the simplegeo module and reuse the models and utilities from there.  The only changes need to be made to the Client hierarchy (each of SimpleGeo’s API s has a corresponding client class).</p>
<p>All client requests are made via the _request method in the base Client class (found in __init__.py in the simplegeo directory).  Most of the code in this function deals with constructing the request  details, before sending the request.  The response content is returned along with the headers.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> _request<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, endpoint, method, data=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    ...
    <span style="color: #008000;">self</span>.<span style="color: black;">headers</span>, content = <span style="color: #008000;">self</span>.<span style="color: black;">http</span>.<span style="color: black;">request</span><span style="color: black;">&#40;</span>endpoint, method, body=body,headers=headers<span style="color: black;">&#41;</span>
    ...
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">headers</span>, content</pre></td></tr></table></div>

<p>Modifying the blocking code above to instead use Tornado wasn&#8217;t too difficult.  I had to modify the signature to now accept a callback and replace the blocking call with the call to use AsyncHTTPClient below.  All of the request construction was able to stay in place.  Notice too that the new _request no longer has a return value.  The data will come back in a callback.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> _request<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, endpoint, method, data=<span style="color: #008000;">None</span>, callback=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    ...
    <span style="color: black;">http_client</span> = AsyncHTTPClient<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    http_client.<span style="color: black;">fetch</span><span style="color: black;">&#40;</span>HTTPRequest<span style="color: black;">&#40;</span>url=endpoint, method=method, headers=headers, body=body<span style="color: black;">&#41;</span>, callback=callback<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So far I&#8217;ve modified only the Places API Client.  That&#8217;s the API that lets you find places data using addresses, lat/long, IP address, etc.  The Places Client has a method search, to search by lat/long.  It has some code for constructing the endpoint URI for the corresponding API call and then calls _request from the base Client.  It then returns the object graph using the SimpleGeo provided models.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> search<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, lat, lon, radius=<span style="color: #008000;">None</span>, query=<span style="color: #008000;">None</span>, category=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
   ...
   <span style="color: black;">result</span> = <span style="color: #008000;">self</span>._request<span style="color: black;">&#40;</span>endpoint, <span style="color: #483d8b;">'GET'</span>, data=kwargs<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
&nbsp;
   fc = json_decode<span style="color: black;">&#40;</span>result<span style="color: black;">&#41;</span>
   <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span>Feature.<span style="color: black;">from_dict</span><span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> f <span style="color: #ff7700;font-weight:bold;">in</span> fc<span style="color: black;">&#91;</span><span style="color: #483d8b;">'features'</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>Making this method work with the asynchronous version of _request first requires accepting a callback to pass to _request.  However, this callback requires a layer of indirection because of the flow of work.  </p>
<p>The callback that the app layer wants will be passed a Feature list.  The callback that the AsyncHTTPClient requires is passed the HTTP response.  So I can&#8217;t simply pass the same callback through the layers.  To get around that, I wrap the app layer callback in a inline function that will in turn call the app layer&#8217;s callback.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> search<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, lat, lon, radius=<span style="color: #008000;">None</span>, query=<span style="color: #008000;">None</span>, category=<span style="color: #008000;">None</span>, callback=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    ...
    <span style="color: #ff7700;font-weight:bold;">def</span> callback_wrapper<span style="color: black;">&#40;</span>response<span style="color: black;">&#41;</span>:
            fc = json_decode<span style="color: black;">&#40;</span>response.<span style="color: black;">body</span><span style="color: black;">&#41;</span>            
            callback<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>Feature.<span style="color: black;">from_dict</span><span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> f <span style="color: #ff7700;font-weight:bold;">in</span> fc<span style="color: black;">&#91;</span><span style="color: #483d8b;">'features'</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>            
&nbsp;
    <span style="color: #008000;">self</span>._request<span style="color: black;">&#40;</span>endpoint, <span style="color: #483d8b;">'GET'</span>, data=kwargs, callback=callback_wrapper<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Finally, at the calling app creates the Client instance and provides the callback to receive the features.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="python" style="font-family:monospace;">@tornado.<span style="color: black;">web</span>.<span style="color: black;">asynchronous</span>
<span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
&nbsp;
    client = Client<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;vvc2y7nAjkx6fUaJqQ94FT7nAdZCWQrA&quot;</span>, <span style="color: #483d8b;">&quot;CJYFj8Sy3WwDL2sFfQXJnDdyXh7BqDU2&quot;</span><span style="color: black;">&#41;</span>
    client.<span style="color: black;">places</span>.<span style="color: black;">search</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">41.773847</span>,-<span style="color: #ff4500;">72.672477</span>, callback=<span style="color: #008000;">self</span>.<span style="color: black;">on_search_complete</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> on_search_complete<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, features<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> feature <span style="color: #ff7700;font-weight:bold;">in</span> features:
        <span style="color: #008000;">self</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span>feature.<span style="color: black;">properties</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span> + <span style="color: #483d8b;">&quot;&lt;br /&gt;&quot;</span><span style="color: black;">&#41;</span>	
    <span style="color: #008000;">self</span>.<span style="color: black;">finish</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Hopefully the point of the callback_wrapper is clearer having seen the Tornado code.  Again, the problem is that the code in the RequestHandler expects to work with a Feature list.  So it passes a callback to the client that will work with a feature list.  The code in the Client layer expects to work with and HTTPResponse, so the Places Client can&#8217;t simply pass its Feature list callback through to the AsyncHTTPClient.</p>
<p>There are a couple pieces that I have to add back in, namely checking the response status and raising appropriate errors when the status is not in the 200 or 300 range.  I&#8217;ll also build out the other search functions as I need them.  But for now, if you&#8217;re in need of a Tornado/SimpleGeo client, this should get you started.</p>
<p>Code is available at <a href="https://bitbucket.org/johnzablocki/asyncsimplegeo/">https://bitbucket.org/johnzablocki/asyncsimplegeo/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2011/05/10/on-a-quick-and-dirty-asynchronous-python-client-for-simplegeo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On (Almost) Speaking at the PostgreSQL Conference</title>
		<link>http://dllhell.net/2011/03/25/on-almost-speaking-at-the-postgresql-conference/</link>
		<comments>http://dllhell.net/2011/03/25/on-almost-speaking-at-the-postgresql-conference/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 22:59:30 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Presenting]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=113</guid>
		<description><![CDATA[Shortly before leaving to go speak at the PostgreSQL East conference today, I tweeted rather ominously - Heading over to deliver a .NET and#MongoDB talk at the PostgreSQL conference. Anticipating an empty room or lots of angry DBAs! #pgeast As &#8230; <a href="http://dllhell.net/2011/03/25/on-almost-speaking-at-the-postgresql-conference/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Shortly before leaving to go speak at the PostgreSQL East conference today, I tweeted rather ominously -</p>
<blockquote><p>Heading over to deliver a .NET and#MongoDB talk at the PostgreSQL conference. Anticipating an empty room or lots of angry DBAs! #pgeast
</p></blockquote>
<p>As it turned out, I had not a single attendee join me for my would-be discussion.  I can’t say I’m surprised.  I submitted a talk not expecting to be selected.  I didn’t have time to prepare a new, more relevant talk for the event.  But I had one prepared so I figured it was worth a shot.  </p>
<p>I was selected, which I think has more to do with my relationship with 10gen.   I’ve spoken on MongoDB and .NET at the Hartford, New York City and Philly code camps, the NYC and Philly ALT.NET groups and I have two more coming up in Philly and New Jersey.  So 10gen has been good at engaging me in the community and recently inviting me to speak at the Mongo Philly event.  Anyway, long story short, 10gen is a great at community outreach and I love to talk about MongoDB and .NET.</p>
<p>I knew I was topically out of place at this conference.  There was a point on the speakers’ distribution list where the following statement was made (in response to the suggestion of using PowerPoint over OpenOffice:</p>
<blockquote><p>I beg to disagree, using Powerpoint on a FLOSS conference simply doesn&#8217;t look right to me</p></blockquote>
<p>Yeah, this is a crowd ready for a talk on .NET and MongoDB.</p>
<p>I’m not bitter about not having anyone show to my talk.  I generally get a respectable turn out at code camps or user group meetings.  I don’t feel slighted.  But I do think I realize now that there’s really just no interest in the broader development community to learn from or about .NET and our development world.  </p>
<p>This notion was made clear to me when one person walked into my room about 10 minutes after my talk should have started.  I joked with him that he could have dedicated MongoDB training.  He offered that he didn’t know .NET so it wouldn’t be of value to him.  </p>
<p>At the NYC Code Camp, topics like node.js and Ruby on Rails are popular.  A good segment of .NET devs have been schooled in the idea that you can learn a lot about your platform by learning about other platforms.  This is a tenet of ALT.NET.  It seems clear to me that such thinking doesn’t exist in communities like that of PostgreSQL’s.  </p>
<p>To be fair, I have never used PostgreSQL and couldn’t imagine ever finding myself wanting to try it.  But I wouldn’t dismiss it.  And I’ve worked with MySQL quite a bit and were it not for MongoDB and SQL Server having a development edition, I’d probably give it a try.  But anyone who knows me in the technical sense knows that I try to avoid the class of problems that needs to be solved by an RDBMS.</p>
<p>So as Microsoft actively courts the open source community by sponsoring projects and foundations such as Python, Mercurial and Apache, the open source community still feels like MS is back in 2001 with Steve Ballmer calling Linux a cancer.</p>
<p>I invested little more than changing a title slide and walking a few blocks to the event today, so I’m not particularly bothered by the fact that my talk didn’t get an attendee.  But I’m disappointed because I was looking forward to a healthy debate about .NET, MongoDB and exposing a group of people to something novel.  After all, that’s why we present, right?  And after all, what’s more novel to a bunch of PHP/Java/Ruby Postgres devs and DBAs than a talk about .NET and MongoDB?</p>
<p>So having heard comments like “Microsoft shouldn’t make operating systems anymore” and the line above about PowerPoint, I won’t be submitting proposals to such narrowly focused product conferences – at least ones where I’m likely to be the only .NET developer in the building. </p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2011/03/25/on-almost-speaking-at-the-postgresql-conference/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>On a Quick and Dirty SimpleGeo Client for .NET</title>
		<link>http://dllhell.net/2011/02/01/on-a-quick-and-dirty-simplegeo-client-for-net/</link>
		<comments>http://dllhell.net/2011/02/01/on-a-quick-and-dirty-simplegeo-client-for-net/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 00:36:06 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[simplegeo]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=105</guid>
		<description><![CDATA[SimpleGeo is a free service providing, among other location-based services, a places API. Provide a longitude and latitude and get details including the names and addresses of businesses and points of interest near this location. While the data is not &#8230; <a href="http://dllhell.net/2011/02/01/on-a-quick-and-dirty-simplegeo-client-for-net/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.simplegeo.com">SimpleGeo</a> is a free service providing, among other location-based services, a places API.  Provide a longitude and latitude and get details including the names and addresses of businesses and points of interest near this location.  While the data is not complete (you may or may not get a phone number), it is still impressively comprehensive.</p>
<p>The SimpleGeo team has provided client libraries for Python, Java and a few other platforms, but no .NET.  There was a CodePlex project named <a href="http://simplegeodotnet.codeplex.com/">SimpleGeo.NET</a> that was until around April or May 2010 actively maintained.  Unfortunately, it seems to have fallen out of sync with the official SimpleGeo API.  It&#8217;s also written in VB.NET, which I think prevented the community from rescuing the codebase.  </p>
<p>More recently, another <a href="https://github.com/jbattermann/SimpleGeo.Net/">SimpleGeo.NET</a> client popped up on GitHub.  This codebase is written in C#, but it&#8217;s still very early in its development.  Its developer, Jörg Battermann, seems to be developing a rich API with the support for Silverlight and Windows Phone 7.  While it seems likely that this project will eventually become for SimpleGeo what NoRM was to MongoDB, it is mostly throwing NotImplementedExceptions at this time.  </p>
<p>Unfortunately, I have a somewhat immediate need for a SimpleGeo client in C#.  This meant having to hack something together for rapid consumption.  It was actually pretty easy to get working, so I figured I&#8217;d share the code for those too impatient to wait on Jörg Battermann&#8217;s project.  </p>
<p>SimpleGeo has a straightforward RESTful API.  Authentication is done through two-legged OAuth.  Basically, it&#8217;s just a signed request with no security token used for user authorization.  API calls return GeoJSON.   </p>
<p>Places are known as &#8220;Features&#8221; in SimpleGeo terms.  When looking up places near a given longitude/latitude pair, the GeoJSON returns a collection of features.  I created a brute force domain model that simply mirrors the GeoJSON.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> FeatureCollection <span style="color: #008000;">&#123;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> Total <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>        
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Type <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> IList<span style="color: #008000;">&lt;</span>Feature<span style="color: #008000;">&gt;</span> Features <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Features look like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Feature <span style="color: #008000;">&#123;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> Geometry Geometry <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Type <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Id <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> Properties Properties <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Most of the interesting data is in the Properties class.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Properties <span style="color: #008000;">&#123;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Province <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> City <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Name <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> IList<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&gt;</span> Tags <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Country <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Phone <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Href <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Address <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Owner <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Postcode <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> IList<span style="color: #008000;">&lt;</span>Classifier<span style="color: #008000;">&gt;</span> Classifiers <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Geometry and Classifier classes round out the model.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Geometry <span style="color: #008000;">&#123;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Point <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> IList<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">decimal</span><span style="color: #008000;">&gt;</span> Coordinates <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>        
&nbsp;
    <span style="color: #008000;">&#125;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Classifier <span style="color: #008000;">&#123;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Category <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Type <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Subcategory <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>With that model in place, it was somewhat trivial to get the rest working.  Borrowing a bit from Jörg Battermann&#8217;s work, I create a Client class that extends <a href="http://hammock.codeplex.com">Hammock for REST&#8217;s</a> RestClient.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Client <span style="color: #008000;">:</span> RestClient <span style="color: #008000;">&#123;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">internal</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> AUTHORITY <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;http://api.simplegeo.com&quot;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">internal</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> VERSIONPATH <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;1.0&quot;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> OAuthCredentials _credentials <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">event</span> Action<span style="color: #008000;">&lt;</span>FeatureCollection<span style="color: #008000;">&gt;</span> RequestCompleteEventHandler<span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008000;">...</span>
     <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Hammock has built in support for OAuth, so I just used that, borrowing again the Jorg&#8217;s constructor.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> Client<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> oAuthKey, <span style="color: #6666cc; font-weight: bold;">string</span> oAuthSecret<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
            _credentials <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> OAuthCredentials<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                Type <span style="color: #008000;">=</span> OAuthType<span style="color: #008000;">.</span><span style="color: #0000FF;">RequestToken</span>,
                SignatureMethod <span style="color: #008000;">=</span> OAuthSignatureMethod<span style="color: #008000;">.</span><span style="color: #0000FF;">HmacSha1</span>,
                ParameterHandling <span style="color: #008000;">=</span> OAuthParameterHandling<span style="color: #008000;">.</span><span style="color: #0000FF;">HttpAuthorizationHeader</span>,
                ConsumerKey <span style="color: #008000;">=</span> oAuthKey,
                ConsumerSecret <span style="color: #008000;">=</span> oAuthSecret
            <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
&nbsp;
            Authority <span style="color: #008000;">=</span> AUTHORITY<span style="color: #008000;">;</span>
            VersionPath <span style="color: #008000;">=</span> VERSIONPATH<span style="color: #008000;">;</span>
            Credentials <span style="color: #008000;">=</span> _credentials<span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>My very, very hacky GetNearbyPlaces implementation is as follows:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> FeatureCollection GetNearbyPlaces<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span> latitude, <span style="color: #6666cc; font-weight: bold;">double</span> longitude, <span style="color: #6666cc; font-weight: bold;">string</span> query <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">null</span>, <span style="color: #6666cc; font-weight: bold;">string</span> category <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
            var path <span style="color: #008000;">=</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Format</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;places/{0},{1}.json&quot;</span>, latitude, longitude<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">//TODO: less ternary operator!</span>
            path <span style="color: #008000;">+=</span> <span style="color: #008000;">!</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsNullOrEmpty</span><span style="color: #008000;">&#40;</span>query<span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;?q=&quot;</span> <span style="color: #008000;">+</span> query <span style="color: #008000;">:</span> <span style="color: #666666;">&quot;&quot;</span><span style="color: #008000;">;</span>
            path <span style="color: #008000;">+=</span> <span style="color: #008000;">!</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsNullOrEmpty</span><span style="color: #008000;">&#40;</span>category<span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> 
                <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsNullOrEmpty</span><span style="color: #008000;">&#40;</span>query<span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;?&quot;</span> <span style="color: #008000;">:</span> <span style="color: #666666;">&quot;&amp;&quot;</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;category=&quot;</span> <span style="color: #008000;">+</span> category<span style="color: #008000;">:</span> <span style="color: #666666;">&quot;&quot;</span><span style="color: #008000;">;</span>
&nbsp;
            var request <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> RestRequest<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> Path <span style="color: #008000;">=</span> path <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
            var response <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Request</span><span style="color: #008000;">&#40;</span>request<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>response<span style="color: #008000;">.</span><span style="color: #0000FF;">StatusCode</span> <span style="color: #008000;">==</span> HttpStatusCode<span style="color: #008000;">.</span><span style="color: #0000FF;">OK</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                var jObj <span style="color: #008000;">=</span> JObject<span style="color: #008000;">.</span><span style="color: #0000FF;">Parse</span><span style="color: #008000;">&#40;</span>response<span style="color: #008000;">.</span><span style="color: #0000FF;">Content</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #0600FF; font-weight: bold;">return</span> JsonConvert<span style="color: #008000;">.</span><span style="color: #0000FF;">DeserializeObject</span><span style="color: #008000;">&lt;</span>FeatureCollection<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>response<span style="color: #008000;">.</span><span style="color: #0000FF;">Content</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">//TODO: raise intelligent exceptions</span>
                <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> FeatureCollection<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> Features <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>Feature<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>I use Hammock&#8217;s request and response sending/receiving methods and pass the result to <a href="http://json.codeplex.com/">JSON.NET</a> which does a brilliant job of hydrating my FeatureCollection object graph.  </p>
<p>The code is far from perfect and is clearly a work in progress.  But it works.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">&#91;</span>Test<span style="color: #008000;">&#93;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> Can_Get_NearbyPlaces_With_Query<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            Client client <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Client<span style="color: #008000;">&#40;</span>OAUTH_KEY, OAUTH_SECRET<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            var collection <span style="color: #008000;">=</span> client<span style="color: #008000;">.</span><span style="color: #0000FF;">GetNearbyPlaces</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">37.7645</span>, <span style="color: #008000;">-</span><span style="color: #FF0000;">122.4294</span>, <span style="color: #666666;">&quot;Starbucks&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>var feature <span style="color: #0600FF; font-weight: bold;">in</span> collection<span style="color: #008000;">.</span><span style="color: #0000FF;">Features</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span>feature<span style="color: #008000;">.</span><span style="color: #0000FF;">Properties</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot; at &quot;</span> <span style="color: #008000;">+</span> feature<span style="color: #008000;">.</span><span style="color: #0000FF;">Properties</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Address</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>If you want an even hackier version, check out my <a href="https://bitbucket.org/johnzablocki/codevoyeur-samples/src/23308b92a842/src/PresentationSamples/WP7Location/SimpleGeoPlaces/">SimpleGeo WP7 experiment</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2011/02/01/on-a-quick-and-dirty-simplegeo-client-for-net/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>On Ignoring Windows Phone 7 App Build Directories in Mercurial</title>
		<link>http://dllhell.net/2010/11/23/on-ignoring-windows-phone-7-app-build-directories-in-mercurial/</link>
		<comments>http://dllhell.net/2010/11/23/on-ignoring-windows-phone-7-app-build-directories-in-mercurial/#comments</comments>
		<pubDate>Tue, 23 Nov 2010 00:44:52 +0000</pubDate>
		<dc:creator>jzablocki</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mercurial hg wp7]]></category>

		<guid isPermaLink="false">http://dllhell.net/?p=99</guid>
		<description><![CDATA[When working with any modern version control system, it&#8217;s pretty common to have some global or project specific ignore file that tells your VCS of choice to ignore certain types of files on adds and commits. When working with Mercurial, &#8230; <a href="http://dllhell.net/2010/11/23/on-ignoring-windows-phone-7-app-build-directories-in-mercurial/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>When working with any modern version control system, it&#8217;s pretty common to have some global or project specific ignore file that tells your VCS of choice to ignore certain types of files on adds and commits.  When working with Mercurial, you can create a file named .hgignore and save it to the root of your project.  </p>
<p>As I&#8217;ve done every time I work with a new VCS, I Google around to find someone else&#8217;s ignore patterns and use that in my project.  This practice followed me from Subversion to Git to Mercurial, my current VCS of choice.  </p>
<p>This evening while setting up a new solution that contains a Windows Phone VS2010 project, I noticed that hg status was showing .dll and .pdb files as untracked.  My ignore file clearly excludes the bin directory and I&#8217;ve never seen this behavior before.  What I quickly discovered was that by default, WP7 apps build to a Bin directory, not bin as do web and class library projects.  The obj directory is still lowercase obj.  This is a small but subtle difference and could result in either in an unnecessary add or two.  Adding Bin to your .hgignore solves the problem.</p>
<p>To add to the Web&#8217;s collection of .hgignore files, I&#8217;ve included mine below&#8230; </p>
<pre>
syntax: glob
#-- Files
*.bak.*
*.bak
thumbs.db

#-- Directories
App_Data/*
bin/
obj/
Bin/
_ReSharper.*/
tmp/

#-- Microsoft Visual Studio specific
*.user
*.suo
</pre>
]]></content:encoded>
			<wfw:commentRss>http://dllhell.net/2010/11/23/on-ignoring-windows-phone-7-app-build-directories-in-mercurial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

