<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Thoughts from the Wet Coast</title>
    <description>The musings of an ASP.NET Developer from the We(s)t Coast of Canada</description>
    <link>http://www.charlesnurse.com/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.6.1.0</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://www.charlesnurse.com/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>My name</dc:creator>
    <dc:title>Thoughts from the Wet Coast</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ThoughtsFromTheWetCoast" /><feedburner:info uri="thoughtsfromthewetcoast" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Project Naif - 1: An Introduction</title>
      <description>&lt;p&gt;&lt;em&gt;(adj) naif, naïve&amp;#160; -- &lt;/em&gt;&lt;em&gt;marked by unaffected simplicity&lt;/em&gt;&lt;/p&gt;  &lt;p align="right"&gt;&lt;em&gt;- &lt;a href="http://www.merriam-webster.com/dictionary/naif"&gt;Merriam Webster&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p align="left"&gt;I have been working for a while on a library of simple components, which I have called Project “Naif”.&amp;#160; Naif is the masculine form of the more common adjective “naïve”.&amp;#160;&amp;#160; Both words are originally French and while naïve is in fairly common usage in English, naif is much less used.&amp;#160; But they mean the same thing – &lt;em&gt;marked by unaffected simplicity&lt;/em&gt; - as defined by Merriam Webster.&lt;/p&gt;  &lt;p align="left"&gt;There are two major reasons for this project.&amp;#160; &lt;/p&gt;  &lt;p align="left"&gt;Firstly, as I have been doing quite a bit of development on Windows Phone “Mango” I have realized that some of the more sophisticated frameworks do not work on the reduced “Client Profile” that Windows Phone supports, and I needed something lightweight that would accomplish these tasks.&amp;#160; &lt;/p&gt;  &lt;p align="left"&gt;Secondly, I saw this as a challenge – a way to learn some new concepts and techniques.&lt;/p&gt;  &lt;p align="left"&gt;This Project is a living project - as I need a component I will build one, but at the time of writing – my little library has the following components:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="left"&gt;A simple lock based on the Monitor object&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Thread safe collections – SynchronizedDictionary and SynchronizedList&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;A simple DI (dependency injection) container&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;A cache provider model with two simple implementations – one based on the ASP.NET runtime cache and one based on a simple Dictionary&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;A simple data framework which supports Unit of Work, the Repository pattern, caching and transactions&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;An oAuth 2 Client&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="left"&gt;For most of these components there are some quite well-known open source projects available – many of them though can be quite complex, and as stated above, my goal is to be as simple as possible.&amp;#160; &lt;/p&gt;  &lt;p align="left"&gt;Inspired by some of the recent micro-ORMs (Dapper, Massive and Peta-Poco) – many of these components are single classes and all of the components mentioned above are compiled into a single assembly which is currently about 35-40K in size.&amp;#160; They may not work in every scenario, but they certainly provide a robust set of tools for my Windows Phone development.&lt;/p&gt;  &lt;p align="left"&gt;So in this series, I am going to describe many of these components, and why I made some of the design choices.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/nVVYiM4AeBg" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/nVVYiM4AeBg/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/Project-Naif-1-An-Introduction.aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=e23f5c58-653f-4e05-a4bb-c3a96968baac</guid>
      <pubDate>Sun, 06 May 2012 13:33:57 -0700</pubDate>
      <category>Development</category>
      <category>Patterns</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=e23f5c58-653f-4e05-a4bb-c3a96968baac</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=e23f5c58-653f-4e05-a4bb-c3a96968baac</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/Project-Naif-1-An-Introduction.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=e23f5c58-653f-4e05-a4bb-c3a96968baac</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=e23f5c58-653f-4e05-a4bb-c3a96968baac</feedburner:origLink></item>
    <item>
      <title>DotNetNuke Module Development 101: 2 - What is a Module?</title>
      <description>&lt;p&gt;In the &lt;a href="http://charlesnurse.com/post/DotNetNuke-Module-Development-101-1-I-did-it-My-Way.aspx"&gt;first post&lt;/a&gt; in this series I pointed out that DotNetNuke places few requirements on module developers, and this is often daunting to new developers &amp;ndash; &amp;ldquo;where do I start?&amp;rdquo; being a common refrain.&lt;/p&gt;
&lt;p&gt;So where do you start?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Before we actually start to build our first module lets look at what constitutes a module.&amp;nbsp; In the default DotNetNuke skin/template that is used when installing DotNetNuke there are a number of examples of Text/HTML modules.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As an example Figure 1 shows 3 such modules on the Home Page.&lt;/p&gt;
&lt;table style="width: 650px;" border="0" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="650" valign="top"&gt;
&lt;h6&gt;Figure 1: Examples of HTML modules on the Home Page of the Default Template&lt;/h6&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="650" valign="top"&gt;&lt;a rel="lightbox" href="http://www.charlesnurse.com/image.axd?picture=image_7.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.charlesnurse.com/image.axd?picture=image_thumb_5.png" border="0" alt="image" width="644" height="409" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Some of the content on the page is provided by the module and some of the content is provided by the framework.&amp;nbsp; In figure 1, while all three modules are HTML modules they all have slightly different &amp;ldquo;headers&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Module 1&amp;rsquo;s heading is in a larger font than Module 2 and Module 3 doesn&amp;rsquo;t have a heading at all.&amp;nbsp; This module &amp;ldquo;chrome&amp;rdquo; is provided by the container which has been applied to the module.&amp;nbsp; The module header text is provided by the framework (Figure 2 &amp;ndash; red box), the styling of the chrome is provided by the container, and the text/images in the &amp;ldquo;body&amp;rdquo; of the module are provided by the module itself (Figure 2 &amp;ndash; blue box).&lt;/p&gt;
&lt;table style="width: 650px;" border="0" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="650" valign="top"&gt;
&lt;h6&gt;Figure 2: The components of a Module&lt;/h6&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="650" valign="top"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.charlesnurse.com/image.axd?picture=image_8.png" border="0" alt="image" width="644" height="417" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This means that as a module developer, I don&amp;rsquo;t need to worry about the external chrome &amp;ndash; or the module header &amp;ndash; this is done for me, I can focus on the content inside the blue box.&lt;/p&gt;
&lt;h2&gt;IModuleControl&lt;/h2&gt;
&lt;p&gt;DotNetNuke is built on top of Microsoft&amp;rsquo;s ASP.NET Web Framework, using the Web Forms model.&amp;nbsp; This model is based on Web Forms (.aspx files) and Web User Controls (.ascx files), as well as Web Controls (which are compiled as part of a class library).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Every page in DotNetNuke is a Web Form &amp;ndash; in fact every page is the same Web Form &amp;ndash; Default.aspx.&lt;/p&gt;
&lt;p&gt;Sections of the page are made up of dynamically injected Controls &amp;ndash; most of which are Web User Controls, and in most cases a module is implemented as a Web User Control (.ascx).&amp;nbsp; So in order to create a module we need to first create a User Control.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;But not just any User Control.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;DotNetNuke needs to know certain things about a module &amp;ndash; and conversely the module might need certain things from the DotNetNuke core, so there is an additional requirement that the User Control needs to implement a DotNetNuke interface &amp;ndash; IModuleControl&lt;/p&gt;
&lt;table style="width: 650px;" border="0" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="650" valign="top"&gt;
&lt;h6&gt;Figure 3: The IModuleControl interface which defines a Module Control&lt;/h6&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="650" valign="top"&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;    public interface IModuleControl
    {
        Control Control { get; }
        string ControlPath { get; }
        string ControlName { get; }
        string LocalResourceFile { get; set; }
        ModuleInstanceContext ModuleContext { get; }
    }&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To make life easier for module developers, the core provides a few base classes which already implement this interface and which can be used as a base by module developers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PortalModuleBase&lt;/strong&gt; &amp;ndash; this was the original base class for all modules &amp;ndash; In DotNetNuke 5.0 the requirement was modified to implement IModuleControl, and this class was refactored to accomplish this.&amp;nbsp; It exposes a lot of extra properties and methods (in addition to the 5 properties that constitute IModuleControl) &amp;ndash; most of which can also be accessed through the ModuleContext property. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ModuleUserControlBase&lt;/strong&gt; &amp;ndash; this new (in DotNetNuke 5.0) base class is a simple implementation of IModuleControl, based on the UserControl base class.&amp;nbsp; In addition to the 5 members of IModuleControl it adds a simple method LocalizeString which is a helper method for localization. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ModuleControlBase&lt;/strong&gt; &amp;ndash; this base class (introduced in DotNetNuke 5.0) is based on the WebControl base class (rather than UserControl).&amp;nbsp; To use this base class the module control would be compiled as part of a class library. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Basically all we have to do then is to create a &amp;ldquo;control&amp;rdquo; which inherits from any of these 3 base classes.&amp;nbsp; This is the &lt;strong&gt;&lt;em&gt;only&lt;/em&gt;&lt;/strong&gt; requirement for building a DotNetNuke Module.&amp;nbsp; There is much more that DotNetNuke offers to module developers, but the minimum requirement is to create a &amp;ldquo;control&amp;rdquo; which implements the IModuleControl interface.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For most of the rest of this series we will be using the ModuleUserControlBase class as our starting point, and in part 3 of this series we will actually create our first DotNetNuke module.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/R9p1ZlHKzcM" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/R9p1ZlHKzcM/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/DotNetNuke-Module-Development-101-2-What-is-a-Module.aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=faa4d0a2-33e0-41ea-ac44-8753f98c85f7</guid>
      <pubDate>Tue, 03 Apr 2012 20:47:00 -0700</pubDate>
      <category>DotNetNuke</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=faa4d0a2-33e0-41ea-ac44-8753f98c85f7</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=faa4d0a2-33e0-41ea-ac44-8753f98c85f7</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/DotNetNuke-Module-Development-101-2-What-is-a-Module.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=faa4d0a2-33e0-41ea-ac44-8753f98c85f7</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=faa4d0a2-33e0-41ea-ac44-8753f98c85f7</feedburner:origLink></item>
    <item>
      <title>DotNetNuke Module Development 101: 1 - I did it My Way</title>
      <description>&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 10px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" align="right" src="http://images2.layoutsparks.com/1/112578/nice-kids-puzzle-piece.png" width="239" height="240" /&gt;DotNetNuke has a rich eco-system of Modules, both Open Source and Commercial.&amp;#160; In many ways this is our biggest strength as a CMS platform.&amp;#160; No matter what you want to do with your site – there is often a module that already does it.&lt;/p&gt;  &lt;p&gt;In my opinion this is due to the flexibility provided by the core DotNetNuke Framework.&amp;#160; Many other platforms are very prescriptive – as an extension developer you have to follow a fixed shopping list of rules – there is invariably only one way to create an extension, which may not work for what you want to do.&amp;#160; &lt;/p&gt;  &lt;p&gt;But DotNetNuke places very few requirements on what must be done to build an extension.&amp;#160; This frees developers to be creative – to think outside the box – which I feel explains the rich ecosystem of modules that already exists and continue to be developed.&lt;/p&gt;  &lt;p&gt;I have been working as a developer on DotNetNuke for nearly 8 years now.&amp;#160; During that time I have built many modules for personal use as well as a number of modules that are now part of the core distributions.&amp;#160; In addition, I have designed and created many of the hooks in the core which Module Developers can take advantage of.&lt;/p&gt;  &lt;p&gt;Recently, I have heard comments that “Module Development with DotNetNuke is difficult”.&amp;#160; &lt;/p&gt;  &lt;p&gt;I don’t agree with this sentiment – but, I think that our strength (flexibility) that I described above is also our weakness. There are a multitude of ways to build DotNetNuke modules -&amp;#160; and we don’t provide a prescriptive method of development.&amp;#160; While this provides flexibility, it can be somewhat daunting for new DotNetNuke developers – where do I start? is a common refrain.&lt;/p&gt;  &lt;p&gt;My goal in this series of posts is to provide some guidance – from my perspective – for both the beginner module developer and for more advanced developers, who may not be aware of all the hooks/features that DotNetNuke provides.&amp;#160; &lt;/p&gt;  &lt;p&gt;This is not “The Definitive Way of Module Development” – its not even “A Definitive Way of Module Development”, but (with apologies to Frank Sinatra) it is “My Way”.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/ytiQ2is-N1w" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/ytiQ2is-N1w/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/DotNetNuke-Module-Development-101-1-I-did-it-My-Way.aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=25201f9a-e8e6-4bed-a3ec-5b40d71c59a6</guid>
      <pubDate>Fri, 30 Mar 2012 11:58:06 -0700</pubDate>
      <category>DotNetNuke</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=25201f9a-e8e6-4bed-a3ec-5b40d71c59a6</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=25201f9a-e8e6-4bed-a3ec-5b40d71c59a6</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/DotNetNuke-Module-Development-101-1-I-did-it-My-Way.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=25201f9a-e8e6-4bed-a3ec-5b40d71c59a6</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=25201f9a-e8e6-4bed-a3ec-5b40d71c59a6</feedburner:origLink></item>
    <item>
      <title>Microsoft goes Open Source!!</title>
      <description>&lt;p&gt;Well – some of it anyway !!&lt;/p&gt;  &lt;p&gt;Today Scot Guthrie, Corporate Vice President in the Microsoft Server and Tools Business announced in a &lt;a href="http://weblogs.asp.net/scottgu/archive/2012/03/27/asp-net-mvc-web-api-razor-and-open-source.aspx"&gt;blog&lt;/a&gt; that some of the ASP.NET technologies that are used by web developers, including me, were to be made available under an open source license.&amp;#160; &lt;/p&gt;  &lt;p&gt;ASP.NET MVC has been available under a permissive license since its first release, but today that was extended to the new Web API Framework and to the ASP.NET WebPages/Razor Framework as well.&lt;/p&gt;  &lt;p&gt;But that isn’t all.&amp;#160; &lt;/p&gt;  &lt;p&gt;In addition to being made available under an open source license (Apache 2.0), the code repository on codeplex.com (&lt;a title="http://aspnetwebstack.codeplex.com/" href="http://aspnetwebstack.codeplex.com/"&gt;http://aspnetwebstack.codeplex.com/&lt;/a&gt;) is actually the live repository that the Microsoft development team will be using for their own source control, so we can watch as they fix bugs and make code changes.&amp;#160; &lt;/p&gt;  &lt;p&gt;And further, they will be taking some commits from the Community.&amp;#160; The team are using the new Git repository support that codeplex.com introduced a few days ago, and Scott Hanselman demonstrated live on stage at DevConnections accepting a pull request from Miguel de Icaza (of mono fame).&amp;#160; Now, don’t expect every pull request to be accepted – there will be careful review of every request and each request will need to meet a high quality bar and meet Microsoft’s goals for the platform, as the product will still be fully supported by Microsoft.&lt;/p&gt;  &lt;p&gt;So congratulations to the ASP.NET team.&amp;#160; Keep up the good work. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/XhBpKzXtGE8" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/XhBpKzXtGE8/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/Microsoft-goes-Open-Source!!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=55decee6-ec41-41b7-827a-d54e92893996</guid>
      <pubDate>Tue, 27 Mar 2012 18:56:31 -0700</pubDate>
      <category>ASP.NET</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=55decee6-ec41-41b7-827a-d54e92893996</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=55decee6-ec41-41b7-827a-d54e92893996</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/Microsoft-goes-Open-Source!!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=55decee6-ec41-41b7-827a-d54e92893996</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=55decee6-ec41-41b7-827a-d54e92893996</feedburner:origLink></item>
    <item>
      <title>Look Mom, NoSQL! – 6. My First RavenDB Application (2)</title>
      <description>&lt;p&gt;In my previous post in this series on NoSQL Databases, I showed how RavenDB embedded could be added to an existing ASP.NET MVC 3 application using NuGet and how it can be configured to use a folder in the App_Data folder.&amp;#160; &lt;/p&gt;  &lt;p&gt;In this blog I will add the code needed for my TaskController class to use RavenDB to store its data.&lt;/p&gt;  &lt;p&gt;Everything in RavenDB goes through an instance of IDocumentStore.&amp;#160; There are two classes in the RavenDB API which implement this interface DocumentStore and EmbeddedDocumentStore.&amp;#160; We will be using the latter.&lt;/p&gt;  &lt;p&gt;We can create a RavenDocumentStore class which is like the DataContext or DbContext classes in Entity Framework.&lt;/p&gt;  &lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="750"&gt;         &lt;h6&gt;Listing 1: The RavenDocumentStore Class&lt;/h6&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="750"&gt;         &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; RavenDocumentStore
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IDocumentStore instance;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IDocumentStore Instance
    {
        get
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (instance == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span class="str"&gt;&amp;quot;…&amp;quot;&lt;/span&gt;);
            &lt;span class="kwrd"&gt;return&lt;/span&gt; instance;
        }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IDocumentStore Initialize()
    {
        instance = &lt;span class="kwrd"&gt;new&lt;/span&gt; EmbeddableDocumentStore
                        {
                            ConnectionStringName = &lt;span class="str"&gt;&amp;quot;RavenDB&amp;quot;&lt;/span&gt;
                        };
        instance.Conventions.IdentityPartsSeparator = &amp;quot;-&amp;quot;;&lt;/pre&gt;

        &lt;pre class="csharpcode"&gt;        instance.Initialize();
        &lt;span class="kwrd"&gt;return&lt;/span&gt; instance;
    }
}&lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;pre class="csharpcode"&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;The static property Instance ensures that we only have one instance of the DocumentStore, and the Initialize method can be called in Application_Start.&amp;#160; We could have created the instance inside the Instance getter, but that would not be thread-safe.&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Listing 2: The Application Start method&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RavenDocumentStore.Initialize();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}&lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;pre class="csharpcode"&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;We are going to need an IDocumentSession to do the work.&amp;#160; We could create a new IDocumentSession instance at the beginning of each Action method and then dispose of it at the end of each method.&amp;#160; But MVC has two very convenient hooks to do this – OnActionExecuting and OnActionExecuted.&amp;#160; These methods are executed before and after each action method, so we will create a new IDocumentSession in OnActionExecuting and dispose of it in On ActionExecuted.&amp;#160; To do this we will create&amp;#160; a BaseRavenController class to act as a base class for our TaskController (Listing 3).&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Listing 3: The BasenRavenController class&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BaseRavenController : Controller
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; IDocumentSession RavenSession { get; set; }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnActionExecuting(ActionExecutingContext filterContext)
    {
        RavenSession = RavenDocumentStore.Instance.OpenSession();
        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnActionExecuting(filterContext);
    }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnActionExecuted(ActionExecutedContext filterContext)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (RavenSession != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            RavenSession.SaveChanges();
            RavenSession.Dispose();
        }
        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnActionExecuted(filterContext);
    }
}&lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Finally we can then modify each action method to use the RavenSession instead of the Entity Framework DbContext.&amp;#160; As an example the Index action (Listing 4) and the Edit actions (Listing 5) are shown.&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Listing 4: The Index Action method&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ViewResult Index()
{
    var tasks = RavenSession.Query&amp;lt;Task&amp;gt;().ToList();
    &lt;span class="kwrd"&gt;return&lt;/span&gt; View(tasks);
}&lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Listing 5: The Edit Action methods&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Edit(&lt;span class="kwrd"&gt;string&lt;/span&gt; id)
{
    Task task = RavenSession.Load&amp;lt;Task&amp;gt;(id);
    &lt;span class="kwrd"&gt;return&lt;/span&gt; View(task);
}

[HttpPost]
&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Edit(Task task)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (ModelState.IsValid)
    {
        RavenSession.Store(task);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; RedirectToAction(&lt;span class="str"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;);
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; View(task);
}&lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;That is basically it – although there is one last change that needs to be made.&amp;#160; RavenDB uses a “key” to identify each document.&amp;#160; By default, just like an Identity column in SQL Server, RavenDB will generate this key automatically – the default behaviour being to create a key of the form “tasks/1” – i.e. the plural of the object’s name followed by the default “/” separator and a hilo generated integer.&amp;#160; &lt;/p&gt;

&lt;p&gt;The default separator can be changed and we did that in Listing 1 by setting the IdentityPartsSeparator&amp;#160; to a “-“, so that we didn’t interfere with the Url separator in our routes.&amp;#160; And since we now have a string “key” the Id property of our Task object (and all the Action method parameters) can be changed to a string.&lt;/p&gt;

&lt;p&gt;Figure 1 and Figure 2 show the Tasks Application running in List and Edit mode.&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Figure 1: The MyTasks MVC Application in List (Index) view&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.charlesnurse.com/image.axd?picture=image_5.png" width="640" height="309" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Figure 2: The MyTasks MVC Application in Edit view&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.charlesnurse.com/image.axd?picture=image_6.png" width="640" height="412" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;



&lt;p&gt;So that’s it – its not very hard at all to start working with RavenDB.&amp;#160; The only challenge so far being that I cannot look into the Data Store in the same way that I can with the SQL Server tools in Visual Studio or SQL Management Studio.&lt;/p&gt;

&lt;p&gt;However, this is not the end of this series of Blogs.&amp;#160; I will continue to explore NoSQL databases, in particular RavenDB.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/k7Nyy03C0QA" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/k7Nyy03C0QA/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-6-My-First-RavenDB-Application-(2).aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=7b2e1883-be2a-46dc-a5d7-b1b00a97b0ca</guid>
      <pubDate>Fri, 18 Nov 2011 18:13:30 -0700</pubDate>
      <category>Data</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=7b2e1883-be2a-46dc-a5d7-b1b00a97b0ca</pingback:target>
      <slash:comments>9</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=7b2e1883-be2a-46dc-a5d7-b1b00a97b0ca</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-6-My-First-RavenDB-Application-(2).aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=7b2e1883-be2a-46dc-a5d7-b1b00a97b0ca</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=7b2e1883-be2a-46dc-a5d7-b1b00a97b0ca</feedburner:origLink></item>
    <item>
      <title>Look Mom, NoSQL! – 5. My First RavenDB Application (1)</title>
      <description>&lt;p&gt;In my continuing series on NoSQL Databases I have been mainly describing some of the concepts behind NoSQL (and in particular Document) Databases.&amp;#160; In this post I will start to dive into some code.&lt;/p&gt;  &lt;p&gt;As mentioned earlier I will be using RavenDB as this is a .NET friendly database. &lt;/p&gt;  &lt;p&gt;In this first example lets create a simple ASP.NET MVC 3 Application that uses RavenDB as its data source.&lt;/p&gt;  &lt;p&gt;I will start with a simple “My Tasks” Application which I created by using the Internet Application template in ASP.NET MVC 3.&amp;#160; Next I created a simple Task model class (Listing 1).&lt;/p&gt;  &lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="750"&gt;         &lt;h6&gt;Listing 1: The Task class&lt;/h6&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="750"&gt;         &lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Task
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; TaskId { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Title { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Description { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsComplete { get; set; }
    }&lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;pre class="csharpcode"&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;I then used the Scaffolding available in ASP.NET MVC 3 to create a TaskController (Figure 1), as well as the Entity Framework DataContext class and all the Razor Views necessary for CRUD operations.&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Figure 1: Scaffold a new TaskController class&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;&lt;a href="http://www.charlesnurse.com/image.axd?picture=image.png" rel="lightbox"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.charlesnurse.com/image.axd?picture=image_thumb.png" width="624" height="411" /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;And finally I created a SQL Server Compact Edition Database to store the data and a Tasks table with columns that matched the names and types of the Task class’s properties.&lt;/p&gt;

&lt;p&gt;To prove that everything was wired up correctly I browsed to the application and added some data (Figure 2).&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Figure 2: A List of Tasks&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;&lt;a href="http://www.charlesnurse.com/image.axd?picture=image_1.png" rel="lightbox"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.charlesnurse.com/image.axd?picture=image_thumb_1.png" width="640" height="252" /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;But the goal of this application is to use RavenDB as the database, not to create an EF Code First/SQL CE application.&lt;/p&gt;

&lt;p&gt;As I mentioned in the &lt;a href="http://www.charlesnurse.com/post/Look-Mom-NoSQL!-3-On-Ravens-Wings.aspx"&gt;3rd post&lt;/a&gt; in this series, RavenDB can be configured in three different ways.&amp;#160; I am going to use the embedded mode.&amp;#160; Luckily, RavenDB is available as a NuGet &lt;a href="http://nuget.org/List/Packages/RavenDB-Embedded"&gt;package&lt;/a&gt;.&amp;#160; To add a NuGet package to a Visual Studio project we can right-click on the References folder (Figure 3).&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Figure 3: Add a new Nuget package&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;&lt;a href="http://www.charlesnurse.com/image.axd?picture=image_2.png" rel="lightbox"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.charlesnurse.com/image.axd?picture=image_thumb_2.png" width="303" height="135" /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;and select “Manage NuGet Packages”.&amp;#160; In the Package Manager window enter Raven&amp;#160; in the search box and install the RavenDB (Embedded) package (Figure 4).&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Figure 4: Install RavenDB using NuGet&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;&lt;a href="http://www.charlesnurse.com/image.axd?picture=image_3.png" rel="lightbox"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.charlesnurse.com/image.axd?picture=image_thumb_3.png" width="630" height="480" /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;The installation adds quite a few assemblies to the bin folder.&lt;/p&gt;

&lt;p&gt;Next we need to configure Raven, so we will create a Folder in the App_Data folder call “Database” (Figure 5),&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Figure 5: Create a new Database Folder for the RavenDB database&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;&lt;a href="http://www.charlesnurse.com/image.axd?picture=image_4.png" rel="lightbox"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.charlesnurse.com/image.axd?picture=image_thumb_4.png" width="264" height="248" /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;and we will modify the connection string that RavenDB added to the web.config to point to the folder we just created.&lt;/p&gt;

&lt;table border="0" cellspacing="5" cellpadding="5" width="750"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;h6&gt;Listing 2: Update connection string in web.config&lt;/h6&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="750"&gt;
        &lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;RavenDB &amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;connectionString&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;DataDir = ~\App_Data\Database&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;pre class="csharpcode"&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;So now we are all set up ready to convert our application to use RavenDB, and in the next post I will show how to hook up the existing TaskController class, so we can store our tasks in an embedded RavenDB database instead of a SQL Compact database.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/zQiIyXLvM98" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/zQiIyXLvM98/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-5-My-First-RavenDB-Application-(1).aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=480d2575-e220-4579-a889-6ff1296e3dbc</guid>
      <pubDate>Thu, 17 Nov 2011 08:07:07 -0700</pubDate>
      <category>Data</category>
      <category>ASP.NET</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=480d2575-e220-4579-a889-6ff1296e3dbc</pingback:target>
      <slash:comments>6</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=480d2575-e220-4579-a889-6ff1296e3dbc</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-5-My-First-RavenDB-Application-(1).aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=480d2575-e220-4579-a889-6ff1296e3dbc</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=480d2575-e220-4579-a889-6ff1296e3dbc</feedburner:origLink></item>
    <item>
      <title>Look Mom, NoSQL! – 4. And to CAP it all</title>
      <description>&lt;p&gt;As my frequent readers would have noticed already, I have been diving into NoSQL databases recently – in particular Document Databases.&amp;#160; But why do we need NoSQL databases in the first place.&amp;#160; Surely the relational databases we have been using work fine – in fact they work very well in most situations.&amp;#160; &lt;/p&gt;  &lt;p&gt;The problem with them is they don’t always scale very well – and when I mean scale, I mean scale really big – across multiple nodes in a cluster.&amp;#160; I alluded to this in the first post in this series, but as an aside I have decided to explore why in further detail in this post.&lt;/p&gt;  &lt;p&gt;It all comes down to the CAP (or Consistency, Availability and Partition Tolerance) Theorem.&amp;#160; This theorem states that when working with distributed systems you can only achieve two of the three goals, so you need to decide what is important to you.&lt;/p&gt;  &lt;p&gt;If Consistency is most important then you would choose a relational database which excels at Consistency.&amp;#160; Examples of when Consistency would be important are in financial systems or nuclear power stations, where it is critical that every piece of data is accounted for.&amp;#160; &lt;/p&gt;  &lt;p&gt;However, in most cases, “eventual consistency” is all that matters.&amp;#160; For example in a content management system if a Page Editor updates a page it is not critical that every user sees that change immediately, as long as at some time in the near future (seconds or minutes) the update is visible.&amp;#160; &lt;/p&gt;  &lt;p&gt;In most applications it is more important that some version of the data is available at all times – i.e. the A or Availability of the CAP theorem.&amp;#160; In systems that focus on Availability, server uptime is more important than the exact version of the data.&lt;/p&gt;  &lt;p&gt;Finally, the P or Partition Tolerance defines the ability of the data to be distributed (partitioned) across multiple servers – this allows for hugely scalable systems, like Google or Facebook.&lt;/p&gt;  &lt;p&gt;Document Databases (as with most NoSQL databases) excel at the A (Availability) and P (Partition Tolerance) corners of the triad and so are less good at Consistency - eventual consistency is good enough.&amp;#160; &lt;/p&gt;  &lt;p&gt;Thus Document Databases are fast and can scale, but would never be used to run a financial system or a nuclear power station.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/MUn-vnLP2mc" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/MUn-vnLP2mc/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-4-And-to-CAP-it-all.aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=b0d04060-64d4-4e7f-ae93-ba620696c68f</guid>
      <pubDate>Wed, 16 Nov 2011 21:05:54 -0700</pubDate>
      <category>Data</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=b0d04060-64d4-4e7f-ae93-ba620696c68f</pingback:target>
      <slash:comments>8</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=b0d04060-64d4-4e7f-ae93-ba620696c68f</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-4-And-to-CAP-it-all.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=b0d04060-64d4-4e7f-ae93-ba620696c68f</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=b0d04060-64d4-4e7f-ae93-ba620696c68f</feedburner:origLink></item>
    <item>
      <title>Look Mom, NoSQL! – 3. On Raven’s Wings</title>
      <description>&lt;p&gt;In my continuing research into NoSQL databases I needed to find a database to work with.&amp;#160; As a .NET developer I was immediately drawn to &lt;a href="http://www.ravendb.net/home"&gt;RavenDB&lt;/a&gt; – a Document Database written in .NET&amp;#160; by Ayende Rahien of NHibernate and Rhino Mocks fame.&lt;/p&gt;  &lt;p&gt;Not only is RavenDB written in .NET but it supports LINQ – who can complain at that !!&amp;#160; RavenDB is open source (with a commercial license option).&amp;#160; It can be used in 3 modes:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;As a Windows Service &lt;/li&gt;    &lt;li&gt;As an IIS Application &lt;/li&gt;    &lt;li&gt;Embedded in a .NET Application &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;As .NET developers,&amp;#160; one of RavenDB’s strengths is that its Indexes can be written using LINQ queries:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;from post &lt;span class="kwrd"&gt;in&lt;/span&gt; docs.Posts
select category &lt;span class="kwrd"&gt;in&lt;/span&gt; post.Categories
select &lt;span class="kwrd"&gt;new&lt;/span&gt; { category }&lt;/pre&gt;

&lt;p&gt;Unlike RDMS Systems, RavenDB’sIndexes do not slow CRUD performance.&amp;#160; This is because the Indexes are processed in the background and the results persisted in a &lt;a href="http://incubator.apache.org/lucene.net/"&gt;Lucene&lt;/a&gt; Index.&amp;#160; &lt;/p&gt;

&lt;p&gt;For those of you who need to compare this to how relational database systems work, a RavenDB Index is like a View – with the addition that the data is saved to disk – not dynamically generated on demand.&amp;#160; This is one of the reasons why Document Databases are fast.&amp;#160; You can find more information on how RavenDB indexes work in the RavenDB &lt;a href="http://ravendb.net/documentation/how-indexes-work"&gt;documentation&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Like most Document Databases RavenDB supports a RESTFull Interface.&amp;#160; For example, assuming that there is a RavenDB installed on port 8080 as an IIS application, using something like Fiddler, we can send an HTTP GET statement&amp;quot;&lt;/p&gt;

&lt;pre&gt;GET &lt;a href="http://localhost:8080/docs/bobs_address"&gt;http://localhost:8080/docs/bobs_address&lt;/a&gt;&lt;/pre&gt;

&lt;p&gt;and assuming there is a document in the database with an id of bobs_address RavenDB will return a JSON document&amp;#160; and an HTTP&amp;#160; 200 OK response:&lt;/p&gt;

&lt;pre&gt;HTTP/1.1 200 OK

{
  &amp;quot;FirstName&amp;quot;: &amp;quot;Bob&amp;quot;,
  &amp;quot;LastName&amp;quot;: &amp;quot;Smith&amp;quot;,
  &amp;quot;Address&amp;quot;: &amp;quot;5 Elm St.&amp;quot;
}&lt;/pre&gt;

&lt;p&gt;If the url does not correspond to a valid document then RavenDB will respond with the typical 404 message&lt;/p&gt;

&lt;pre&gt;HTTP/1.1 404 Not Found&lt;/pre&gt;

&lt;p&gt;As a .NET application RavenDB also has a rich Client API, which I will dive into much more detail in future posts as I build a RavenDB application.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/WQdTSKm5ua8" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/WQdTSKm5ua8/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-3-On-Ravens-Wings.aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=9dca5bab-952a-44be-83c4-575b32ce6351</guid>
      <pubDate>Wed, 16 Nov 2011 08:23:07 -0700</pubDate>
      <category>Data</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=9dca5bab-952a-44be-83c4-575b32ce6351</pingback:target>
      <slash:comments>6</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=9dca5bab-952a-44be-83c4-575b32ce6351</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-3-On-Ravens-Wings.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=9dca5bab-952a-44be-83c4-575b32ce6351</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=9dca5bab-952a-44be-83c4-575b32ce6351</feedburner:origLink></item>
    <item>
      <title>Look Mom, NoSQL! – 2. NoSQL Database Types</title>
      <description>&lt;p&gt;A week or so ago the topic of NoSQL databases came up at a discussion at work, so I decided it was time I learnt about this topic.&lt;/p&gt;  &lt;p&gt;A few days ago Julie Lerman (@julielerman) tweeted that she had published an &lt;a href="http://msdn.microsoft.com/en-us/magazine/hh547103.aspx"&gt;article&lt;/a&gt; in MSDN Magazine on Document Databases (one of the major types of NoSQL databases) and reading that article started me on my research.&amp;#160; &lt;/p&gt;  &lt;p&gt;I purchased the Wrox Press book “Professional NoSQL” by Shashank Tiwari for my iPad Kindle App and much of this post is gleaned from the first few chapters&amp;#160; of that book (as well as from Julie’s article).&lt;/p&gt;  &lt;p&gt;In a previous &lt;a href="http://www.charlesnurse.com/post/Look-Mom-NoSQL-An-Introduction.aspx"&gt;post&lt;/a&gt; I introduced the concept of NoSQL databases, and in this post I will discus the three most common types of NoSQL databases.&lt;/p&gt;  &lt;h2&gt;Sorted Ordered Column-Oriented Stores&lt;/h2&gt;  &lt;p&gt;Google, who were one of the main pioneers of the trend to NoSQL databases, due to the sheer volume of data they store uses a system (Bigtable) that stores data in a column-oriented way.&amp;#160; This compares with typical Relational systems which are row-oriented.&lt;/p&gt;  &lt;p&gt;Each unit of data can be thought of as a set of key-value pairs, with the unit being identified by a “primary key”.&amp;#160; Bigtable calls this the “row key”.&amp;#160; The units of data are sorted and ordered on the basis of this row key.&amp;#160; &lt;/p&gt;  &lt;p&gt;So far this isn’t really much different than a Table in a Relational model that has a primary key field and a clustered index.&lt;/p&gt;  &lt;p&gt;What makes the store “column-oriented” is that the various pieces of information that define the “record” of data, can be divided into groups of columns or column families. For example, if we are saving information about a person, we may define &lt;em&gt;first_name&lt;/em&gt; and &lt;em&gt;last_name&lt;/em&gt; fields, which can be grouped in a &lt;em&gt;name&lt;/em&gt; column family.&amp;#160; Likewise we could define &lt;em&gt;street_address&lt;/em&gt;, &lt;em&gt;city&lt;/em&gt; and &lt;em&gt;zip_code&lt;/em&gt;, which can be grouped in a &lt;em&gt;address &lt;/em&gt;column family, and &lt;em&gt;sex &lt;/em&gt;and &lt;em&gt;age&lt;/em&gt; which can be grouped in a &lt;em&gt;profile&lt;/em&gt; column family.&lt;/p&gt;  &lt;p&gt;We now have 3 column families or buckets of information.&amp;#160; In a column-oriented store column families are typically defined at configuration or startup but the individual columns need not be pre-defined.&lt;/p&gt;  &lt;p&gt;Within each bucket, only key/value pairs are defined.&amp;#160; The column key identifies the column family or bucket to use and the row key identifies the individual columns within the bucket.&lt;/p&gt;  &lt;p&gt;Like many NoSQL databases there is not really a concept of NULL data.&amp;#160; New columns can be added at any time as it is just another key/value pair in the bucket.&lt;/p&gt;  &lt;p&gt;While data that relates to the same row key will often be stored in a contiguous fashion, this set up allows for data to be partitioned across multiple computer nodes.&lt;/p&gt;  &lt;p&gt;Examples of Sorted Ordered Column-Oriented Stores include: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;HBase (&lt;a href="http://hbase.apache.org"&gt;http://hbase.apache.org&lt;/a&gt;) – part of the Hadoop family – used by Facebook, StumbleUpon, Hulu, Yahoo and others and &lt;/li&gt;    &lt;li&gt;HyperTable (&lt;a href="http://www.hypertable.org"&gt;www.hypertable.org&lt;/a&gt;) - used by Baidu – China’s biggest search engine and Rediff – India’s biggest portal. &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Key/Value Stores&lt;/h2&gt;  &lt;p&gt;A &lt;a href="http://en.wikipedia.org/wiki/Hash_table"&gt;Hash Map or Hash Table&lt;/a&gt; is the simplest data structure that can hold a set of key/value pairs.&amp;#160; Such structures are popular because they are very efficient typically approaching O(1).&amp;#160; The key of a key/value pair must be unique and can be easily looked up.&lt;/p&gt;  &lt;p&gt;Examples of Key/Value Stores include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;BerkeleyDB &lt;/li&gt;    &lt;li&gt;MemBase (&lt;a href="http://www.membase.org"&gt;www.membase.org&lt;/a&gt;) – build on the popular MemCached Cache – used by Zynga &lt;/li&gt;    &lt;li&gt;Redis (&lt;a href="http://redis.io"&gt;http://redis.io&lt;/a&gt;) – used by CraigsList &lt;/li&gt;    &lt;li&gt;Cassandra (&lt;a href="http://cassandra.apache.org/"&gt;http://cassandra.apache.org/&lt;/a&gt;) – an Amazon Dynamo clone, developed by Facebook and open sourced – used by Facebook, Digg, Reddit, Twitter and others &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Document Databases&lt;/h2&gt;  &lt;p&gt;Document Databases are not document management systems.&amp;#160; A document in this case is a loosely structured set of key/value pairs in documents, typically using JSON (JavaScript Object Notation), not a Word Processing Document or Spreadsheet.&lt;/p&gt;  &lt;p&gt;One core benefit for object-oriented developers is that we can think of a document as mapping to an object, including any contained collections/objects, although in reality what we mean here are objects that are considered to be “&lt;a href="http://en.wikipedia.org/wiki/Domain-driven_design"&gt;aggregate roots&lt;/a&gt;”.&lt;/p&gt;  &lt;p&gt;Document Databases treat a document as a whole – rather than splitting it into its constituent key/value pairs.&lt;/p&gt;  &lt;p&gt;This post is getting quite long so I won’t get into further detail on this class of NoSQL databases, as I will be diving into Document Databases in more detail in future posts.&lt;/p&gt;  &lt;p&gt;Examples of Document Databases include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;MongoDB (&lt;a href="http://www.mongodb.org"&gt;www.mongodb.org&lt;/a&gt;) – created by 10gen – used by Foursquare and Github &lt;/li&gt;    &lt;li&gt;CouchDB (&lt;a href="http://www.couchbase.com"&gt;www.couchbase.com&lt;/a&gt;) - used by Apple, BBC, Cern &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/u2FKJmRNQhw" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/u2FKJmRNQhw/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-2-NoSQL-Database-Types.aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=92ffbea1-835a-4e6d-80e0-fcdb65f7a899</guid>
      <pubDate>Mon, 14 Nov 2011 08:08:46 -0700</pubDate>
      <category>Data</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=92ffbea1-835a-4e6d-80e0-fcdb65f7a899</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=92ffbea1-835a-4e6d-80e0-fcdb65f7a899</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/Look-Mom-NoSQL!-2-NoSQL-Database-Types.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=92ffbea1-835a-4e6d-80e0-fcdb65f7a899</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=92ffbea1-835a-4e6d-80e0-fcdb65f7a899</feedburner:origLink></item>
    <item>
      <title>Look Mom, NoSQL! – 1. An Introduction</title>
      <description>&lt;p&gt;Most .NET developers, whether we work on the Web with ASP.NET Web-Forms or MVC, on Windows Phone or in the browser with Silverlight, or on the desktop with WPF have worked with some form of Database.&lt;/p&gt;  &lt;p&gt;We are for the most part familiar with SQL Server, MySQL or Oracle Relational Database Management Systems (RDBMSs) – and we are used to writing database schemas and database code using some variety of SQL.&lt;/p&gt;  &lt;p&gt;We have come to terms with the idea of the “&lt;a href="http://en.wikipedia.org/wiki/Object-Relational_impedance_mismatch"&gt;Object-Relational Impedance Mismatch&lt;/a&gt;” – the fact that objects don’t always map well to database entities, and the rise in popularity of ORM (Object Relational Mapping) Frameworks like NHibernate and Entity Framework to address this mismatch.&lt;/p&gt;  &lt;p&gt;We also know that Relational Databases are often inefficient due to the complex “relationships” (joins) between tables.&amp;#160; Relational Databases excel at eliminating redundancy, thus reducing the amount of data stored through &lt;a href="http://en.wikipedia.org/wiki/Database_normalization"&gt;Database Normalization&lt;/a&gt;.&amp;#160; But normalization impacts performance, so if performance is critical we know we have to selectively de-normalize the database.&lt;/p&gt;  &lt;p&gt;Recently, there has been more and more “noise” around the term NoSQL and NoSQL databases.&amp;#160; But what are NoSQL databases and why are they becoming more popular.&amp;#160; &lt;/p&gt;  &lt;p&gt;As the topic came up at work I decided it was time that I dived into this technology to try and understand the strengths and weaknesses of these databases, and so I propose to share what I have learned in this series of Blog posts.&lt;/p&gt;  &lt;p&gt;To get things started then.&amp;#160; &lt;/p&gt;  &lt;p&gt;The term NoSQL basically means what it says – NoSQL databases do not use SQL because the data is not stored in relational tables, although some people have redefined the term as an acronym NoSQL = “Not Only SQL”.&amp;#160; Whatever the term means, NoSQL is used to describe databases that do not use a relational model and typically can store huge amounts of data – think Google, Facebook or Linked-In scale.&lt;/p&gt;  &lt;p&gt;All NoSQL databases share common goals of speed and scalability.&amp;#160; But the many different NoSQL databases approach these goals in different ways.&amp;#160; In the next post I will discus two of the major categories of NoSQL Databases and some of the common implementations.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsFromTheWetCoast/~4/yfolD2tESfE" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ThoughtsFromTheWetCoast/~3/yfolD2tESfE/post.aspx</link>
      <author>cnurse</author>
      <comments>http://www.charlesnurse.com/post/Look-Mom-NoSQL-An-Introduction.aspx#comment</comments>
      <guid isPermaLink="false">http://www.charlesnurse.com/post.aspx?id=cf4ecf99-85f6-4aae-9fd3-0944ea036f70</guid>
      <pubDate>Thu, 10 Nov 2011 23:34:36 -0700</pubDate>
      <category>Data</category>
      <dc:publisher>cnurse</dc:publisher>
      <pingback:server>http://www.charlesnurse.com/pingback.axd</pingback:server>
      <pingback:target>http://www.charlesnurse.com/post.aspx?id=cf4ecf99-85f6-4aae-9fd3-0944ea036f70</pingback:target>
      <slash:comments>15</slash:comments>
      <trackback:ping>http://www.charlesnurse.com/trackback.axd?id=cf4ecf99-85f6-4aae-9fd3-0944ea036f70</trackback:ping>
      <wfw:comment>http://www.charlesnurse.com/post/Look-Mom-NoSQL-An-Introduction.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.charlesnurse.com/syndication.axd?post=cf4ecf99-85f6-4aae-9fd3-0944ea036f70</wfw:commentRss>
    <feedburner:origLink>http://www.charlesnurse.com/post.aspx?id=cf4ecf99-85f6-4aae-9fd3-0944ea036f70</feedburner:origLink></item>
  </channel>
</rss>

