<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Chris Eldredge]]></title>
  <link href="http://chris.eldredge.io/atom.xml" rel="self"/>
  <link href="http://chris.eldredge.io/"/>
  <updated>2018-05-03T12:01:48+00:00</updated>
  <id>http://chris.eldredge.io/</id>
  <author>
    <name><![CDATA[Chris Eldredge]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Synology VPN Server Route Advertising]]></title>
    <link href="http://chris.eldredge.io/blog/2015/05/24/synology-vpn-server-route-advertising/"/>
    <updated>2015-05-24T16:43:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2015/05/24/synology-vpn-server-route-advertising</id>
    <content type="html"><![CDATA[<p>I have a Synology at home and it&#8217;s a great product. I recently installed
the VPN Server package and enabled L2TP/IPSec so I can get on my home
network when I&#8217;m roaming about.</p>

<p>The default options work fine if all you want to access is the Synology
system itself, but I noticed that after connecting my OS X client,
I couldn&#8217;t reach any other computers on my home network.</p>

<p>After much googling and head scratching, I figured out that L2TP does
not have a built in mechanism for configuring classless static routes and that
VPN Server does not go out of its way to make this work out of the box.</p>

<p>After establishing a connection over L2TP, a client will typically issue
a DHCP Inform broadcast message over the connection requesting such routes.
I let my WiFi router do DHCP so my Synology DHCP service is disabled. I don&#8217;t
know if it would reply to these messages over VPN or not.</p>

<p>Anyway, since the DHCP Inform message is sent on the L2TP virtual network,
it isn&#8217;t rebroadcast on the local LAN, so my WiFi router DHCP server never
sees it and can&#8217;t respond.</p>

<p>I was able to solve this problem by installing the 3rd party (unsigned)
<a href="http://syndnsmasq.the-ninth.com">SynDnsmasq</a> package on my Synology box.</p>

<p>Once I had the package installed, I set the contents of
<code>/volume1/@appstore/dnsmasq/etc/dnsmasq.conf</code> to:</p>

<pre><code>except-interface=eth0
except-interface=eth1
except-interface=eth2
except-interface=eth3

domain=localnet

dhcp-range=192.168.2.0,static
dhcp-option=option:router
dhcp-option=121,10.0.0.0/24,192.168.2.0
dhcp-option=249,10.0.0.0/24,192.168.2.0
dhcp-option=vendor:MSFT,2,1i
</code></pre>

<p>You&#8217;ll need to adjust the subnets/masks and router IPs to match
your home network and L2TP address range.</p>

<p>What this does is respond to DHCP Inform requests with a classless
static route for the home network (10.0.0.0/24) via the L2TP server
IP address (192.168.2.0).</p>

<p>I restarted SynDnsmasq, connected my OS X VPN client, and was off
to the races.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Solr, Jetty and CORS]]></title>
    <link href="http://chris.eldredge.io/blog/2015/04/02/solr-jetty-cors/"/>
    <updated>2015-04-02T10:29:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2015/04/02/solr-jetty-cors</id>
    <content type="html"><![CDATA[<p>Recently my pet project has been working on an <a href="https://github.com/emberjs/data">Ember Data</a> adapter that connects to Solr. This work combines two of my favorite technologies and I think has a lot of potential value for creating applications
quickly and easily in Ember that leverage the full power of Solr as a persistence
and retrieval engine. My fledgling project lives at <a href="https://github.com/chriseldredge/ember-solr">github.com/chriseldredge/ember-solr</a>. It&#8217;s heavily based on EmberFire.</p>

<p>One issue I ran into, of course, is dealing with cross-origin requests in the browser.
For my tests, my Ember app is running on localhost:4200 and my Solr server is running
on localhost:8983. The browser, rightly, will refuse to let requests from my Ember app
execute on Solr, unless the Solr server enables <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS">Cross-Origin Resource Sharing</a> headers.</p>

<p>Solr 5 ships with Jetty, and it turns out there&#8217;s already a servlet filter that
can do this for us. All we have to do is download it and configure it.</p>

<p>First, figure out which version of Jetty your Solr shipped with. Solr 5.0 comes with
Jetty 8.1.10. Now head over to the <a href="http://repo1.maven.org/maven2/org/eclipse/jetty/jetty-servlets/">jetty-servlets</a> folder on the maven.org repository, drill down into
the corresponding version, and download jetty-servlets-<em>version</em>.jar. Save the jar
into <code>$SOLR_HOME/server/lib</code>.</p>

<p>Next, open <code>$SOLR_HOME/server/etc/webdefault.xml</code> in a text editor.
Insert the following at bottom of the file, right before the closing <code>&lt;/web-app&gt;</code>
tag:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'>  <span class="nt">&lt;filter&gt;</span>
</span><span class='line'>    <span class="nt">&lt;filter-name&gt;</span>cross-origin<span class="nt">&lt;/filter-name&gt;</span>
</span><span class='line'>    <span class="nt">&lt;filter-class&gt;</span>org.eclipse.jetty.servlets.CrossOriginFilter<span class="nt">&lt;/filter-class&gt;</span>
</span><span class='line'>    <span class="nt">&lt;init-param&gt;</span>
</span><span class='line'>      <span class="nt">&lt;param-name&gt;</span>chainPreflight<span class="nt">&lt;/param-name&gt;</span>
</span><span class='line'>      <span class="nt">&lt;param-value&gt;</span>false<span class="nt">&lt;/param-value&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/init-param&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/filter&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;filter-mapping&gt;</span>
</span><span class='line'>    <span class="nt">&lt;filter-name&gt;</span>cross-origin<span class="nt">&lt;/filter-name&gt;</span>
</span><span class='line'>    <span class="nt">&lt;url-pattern&gt;</span>/*<span class="nt">&lt;/url-pattern&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/filter-mapping&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The third and final step is to start (or restart) your Solr server.</p>

<p>This example enables CORS requests for all origins. If you are going to do something
like this on your production server, you probably want to lock this down using the
<code>allowedOrigins</code> parameter.</p>

<p>The <code>chainPreflight</code> parameter is set to false so the
filter will short-circuit when a browser sends a pre-flight OPTIONS request.
This is necessary for Solr because the Solr update handler would respond with
a <code>400 Bad Request</code> since it doesn&#8217;t know what to do with an OPTIONS request.</p>

<p>You can find the other configuration parameters for the filter at <a href="https://wiki.eclipse.org/Jetty/Feature/Cross_Origin_Filter">wiki.eclipse.org</a>.</p>

<h2>Alternatives</h2>

<p>If you can&#8217;t or don&#8217;t want to use CORS, there are a couple other options available
to you. You could have your Ember app proxy requests to Solr, you could deploy your
Ember app on the same origin as your Solr server, or you could try to use JSON-P.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[NuGet Symbols and Aspnet vNext]]></title>
    <link href="http://chris.eldredge.io/blog/2015/01/05/nuget-symbols-and-aspnet-vnext/"/>
    <updated>2015-01-05T14:52:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2015/01/05/nuget-symbols-and-aspnet-vnext</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been working on a new release of Klondike for quite a while now.
My last release was <a href="https://github.com/themotleyfool/Klondike/releases">published</a>
on March 27th, 2014.</p>

<p>There&#8217;s been quite a bit of work off and on over the months, but I&#8217;ve kept
postponing a new version to add Just One More Feature. Scope creep, anyone?</p>

<p>One remaining issue I&#8217;m now working through is dealing with normal NuGet packages,
NuGet symbol packages, and looking ahead at Microsoft.NET 5 (aka .NET vNext).</p>

<p>Ignoring vNext, the <code>nuget pack</code> command takes an optional <code>-symbols</code> argument
which asks it to build two separate zip files: one that contains the DLLs,
documentation, content, scripts and other artifacts that a project would consume
from your package, and another one that contains the DLLs, PDBs (debugging symbols),
and source code for your package.</p>

<p>The symbol packages are intended to be uploaded somewhere like <a href="http://www.symbolsource.org/">SymbolSource.org</a>
where they will be processed for consumption by debuggers like Visual Studio and WinDbg.</p>

<p>Klondike allows both normal packages and symbol packages to be uploaded to a single
end point. This enables Klondike users to use NuGet for private libraries without
losing useful source level integration with Visual Studio.</p>

<p>On the surface, there is little to tell a symbol package from a normal one. Both packages
will have virtually identical manifests and metadata. The metadata will have a package
ID and version. Apart from the name of the package file (MyThing.1.0.nupkg vs MyThing.1.0.symbols.nupkg),
we have to fall back to heuristics to suss out one from the other.</p>

<p>This is what Klondike does: look at the files in the package and if there&#8217;s at least one
file in the <code>src</code> directory, and at least one <code>pdb</code> file in the <code>lib</code> directory, then
the package is deemed to be a symbol package.</p>

<p>With vNext, the waters are muddied. Commands like <code>kpm pack</code> produce a single package
that contains consumable contents but also includes PDBs and source. This sounds
great. Two use cases in a single payload.</p>

<p>The trouble is in how we distinguish between a normal package and a symbol package.
Klondike needs to treat them differently so when a client asks to download a
package, it gets the full normal package and not just the symbols and source.</p>

<p>At present, Klondike wrongly concludes that a vNext package is a symbol package.
My heuristic is wrong when dealing with such packages.</p>

<h2>It&#8217;s the file name stupid</h2>

<p>My first thought was, it is obvious from a file name like <code>MyThing.1.0.symbols.nupkg</code>
that a package should be treated as symbols-only. When files are uploaded using
multipart/mime, a helpful Content-Disposition header should tell me the name of the
file being uploaded.</p>

<p>Well, as it turns out, regardless of what the file is named on disk, the <code>nuget push</code>
command always lies to the server and says it&#8217;s uploading a file named <code>package</code>.</p>

<p>Push <code>MyThing.1.0.nupkg</code> and the server sees <code>package</code>. Push <code>MyThing.1.0.symbols.nupkg</code>
and the server sees <code>package</code>. Push a file that isn&#8217;t a package and the server sees&#8230;
you get it.</p>

<h2>It&#8217;s the endpoint stupid</h2>

<p>The client knows if a package is symbols or not. Maybe the client should use a different
endpoint to upload symbol packages from normal ones. Perhaps trying to handle both package
types from the same URL was a bad decision in the first place.</p>

<p>Changing it now would break any automated scripts that currently push packages to Klondike.
Maybe there&#8217;s not a ton of clients out there today, but it still rubs me the wrong way.</p>

<h2>It&#8217;s something else?</h2>

<p>Apart from requiring the client to use a different URL to push symbols, I&#8217;m at a loss of
how else to reliably tell the difference between symbols and normal packages. Since
the problem only affects vNext, I could add more complicated heuristics to see if
<code>aspnet50</code> or <code>aspnetcore50</code> are supported by the package. This does not sounds like
an approach that won&#8217;t need constant attention as new frameworks and versions are
introduced.</p>

<h2>What do</h2>

<p>It&#8217;s a bummer that symbol packages don&#8217;t have a simple flag in their manifests that proclaim
what they are. It&#8217;s a bummer that <code>nuget push</code> uses a hard-coded file name no matter what
type of package is being uploaded. It&#8217;s a bummer that vNext appears to be changing
the rules of what a normal package may contain.</p>

<p>Unless I&#8217;ve overlooked something, the right choice seems to be to require clients
to push symbol packages to an alternate URL.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Node + Owin: Living in the Future]]></title>
    <link href="http://chris.eldredge.io/blog/2014/05/01/node-plus-owin-living-in-the-future/"/>
    <updated>2014-05-01T17:04:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2014/05/01/node-plus-owin-living-in-the-future</id>
    <content type="html"><![CDATA[<p>Scott Hanselman recently blogged <a href="http://www.hanselman.com/blog/ItsJustASoftwareIssueEdgejsBringsNodeAndNETTogetherOnThreePlatforms.aspx">&#8220;It&#8217;s just a software issue&#8221;- Edge.js brings Node and .NET together on three platforms</a>
and to say the least I am intrigued.</p>

<p>I&#8217;ve been using Grunt (and therefore Node) to develop <a href="https://github.com/themotleyfool/Klondike/">Klondike</a>
for about 6 months and it never occurred to me that hosting managed .net code
from Node was an option.</p>

<p>After reading Scott&#8217;s post, my immediate question was if I could host an OWIN
application from Node. Some quick googling revealed <a href="https://github.com/bbaia/connect-owin">connect-owin</a>
is well on its way.</p>

<p>It took a little elbow grease to get from the toy app samples to being able
to initialize Klondike and serve requests.</p>

<h2>Proof of Concept</h2>

<p>On my Windows VM, I ran:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>npm install connect-owin express</span></code></pre></td></tr></table></div></figure>


<p>Then created this barebones Node program:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="kd">var</span> <span class="nx">owin</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;connect-owin&#39;</span><span class="p">),</span>
</span><span class='line'>    <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span>
</span><span class='line'><span class="nx">app</span><span class="p">.</span><span class="nx">all</span><span class="p">(</span><span class="s1">&#39;/api/*&#39;</span><span class="p">,</span> <span class="nx">owin</span><span class="p">(</span><span class="s1">&#39;bin/debug/NuGet.Lucene.Web.OwinHost.Sample.exe&#39;</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'><span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<h2>AppDomains and Configuration</h2>

<p>Klondike uses appSettings to configure where files are kept and which options
are enabled. It also has a fair amount of binding redirects that make sure
all the various assemblies pulled in from NuGet packages agree to use the
same version of DLL dependencies.</p>

<p>I realized quickly that when my assembly is loaded from Node, my config file
was being ignored.</p>

<p>I asked a <a href="https://github.com/tjanczuk/edge/issues/131">question</a> on the Edge
Github project to confirm, but inspecting source code it appears to be the case
that when Edge loads a managed assembly, it isn&#8217;t creating a full AppDomain
and specifying a config file to go with it.</p>

<p>To &#8220;trick&#8221; my configuration into being loaded, I copied node.exe from it&#8217;s home
in Program Files to my bin/Debug directory, and then copied my config file to
<code>node.exe.config</code> in the same local directory.</p>

<p>Sure enough, running <code>.\bin\Debug\node.exe server.js</code> happily pulled in my config settings
and binding redirects.</p>

<p>It would be nice if Issue 131 gets first-class support, but in the mean time
at least I know there&#8217;s a way to load complex applications into Edge.</p>

<h2>Whither Mono?</h2>

<p>Edge (and therefore connect-owin) have first-class support for the Mono Framework,
although unfortunately I was unable to get beyond an issue with Ninject. As it
turns out, Ninject has a separate build configuration to support Mono and the
packages on nuget.org won&#8217;t work when you try to use them with Mono.</p>

<p>This is pretty unfortunate and I&#8217;ll be looking for a new IoC container to replace
Ninject with. One that has built in integration with WebApi and SignalR would
be nice.</p>

<h2>The Future</h2>

<p>The Future is now. Being able to use Bower, Grunt and Node with integrated .NET
request processing means teams can use the same great front-end tools that
are sweeping the community by storm while still building rich server-side
components powered by .NET.</p>

<p>I&#8217;m a huge fan of c# and .NET, but love that this enables front-end developers
who aren&#8217;t to be able to contribute to these projects without forcing them to
stop using Grunt, Bower and whatever other favorite tools they bring from their
toolboxes.</p>

<p>Are Edge and connect-owin production ready? I don&#8217;t know, but I also don&#8217;t really
care. To me, these are ideal tools for development and testing, but once
<code>grunt build</code> gives me an app tree in <code>./dist</code> I&#8217;d rather just push my app to
the cloud and let someone else worry about hosting.</p>

<h2>Source</h2>

<p>My efforts to convert Klondike to support OWIN self hosting are a
work-in-progress, but you can see the source code on the <a href="https://github.com/themotleyfool/NuGet.Lucene/tree/webapi-odata/source/NuGet.Lucene.Web.OwinHost.Sample">webapi-oata</a>
branch of <a href="https://github.com/themotleyfool/NuGet.Lucene/">NuGet.Lucene</a>
on Github.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Default Streams with WebApi OData]]></title>
    <link href="http://chris.eldredge.io/blog/2014/04/29/Default-Streams/"/>
    <updated>2014-04-29T16:07:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2014/04/29/Default-Streams</id>
    <content type="html"><![CDATA[<p>NuGet package feeds provide metadata about packages, but after searching
for new packages to use or updates to existing ones, we also have to
be able to download the actual package.</p>

<p>The NuGet OData implementation provides links to download a package
by using the <code>default stream</code> concept.</p>

<p>In WCF Data Services, an entity indicates that it has a stream using the
aptly named <code>HasStreamAttribute</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="na">[DataServiceKey(&quot;Id&quot;, &quot;Version&quot;)]</span>
</span><span class='line'><span class="na">[HasStream]</span>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">DataServicePackage</span> <span class="p">:</span> <span class="n">IEquatable</span><span class="p">&lt;</span><span class="n">DataServicePackage</span><span class="p">&gt;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="c1">//snip</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>To build a URI for each instance, a custom implementation of
<code>IDataServiceStreamProvider</code> is wired into our <code>DataService</code>.</p>

<p>This is done differently in WebApi which does not include the
<code>HasStreamAttribute</code> at all.</p>

<p>Over a year ago, I asked on twitter:</p>

<div class='embed tweet'><blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/adjames?ref_src=twsrc%5Etfw">@adjames</a> Is there a webapi/odata equivalent of HasStreamAttribute and IDataServiceStreamProvider?</p>&mdash; Chris Eldredge (@creldredge) <a href="https://twitter.com/creldredge/status/289384233141669888?ref_src=twsrc%5Etfw">January 10, 2013</a></blockquote>
<script async src="http://chris.eldredge.io//platform.twitter.com/widgets.js" charset="utf-8"></script></div>


<p>At the time, the answer was no. However, I&#8217;m happy to report that
recent versions of WebApi do support this feature.</p>

<p>First, we need to tell our EDM model builder that the entity has
a default stream:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">MapODataRoutes</span><span class="p">(</span><span class="n">HttpConfiguration</span> <span class="n">config</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">var</span> <span class="n">builder</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ODataConventionModelBuilder</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">var</span> <span class="n">entity</span> <span class="p">=</span> <span class="n">builder</span><span class="p">.</span><span class="n">EntitySet</span><span class="p">&lt;</span><span class="n">ODataPackage</span><span class="p">&gt;(</span><span class="s">&quot;Packages&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">entity</span><span class="p">.</span><span class="n">EntityType</span><span class="p">.</span><span class="n">HasKey</span><span class="p">(</span><span class="n">pkg</span> <span class="p">=&gt;</span> <span class="n">pkg</span><span class="p">.</span><span class="n">Id</span><span class="p">);</span>
</span><span class='line'>    <span class="n">entity</span><span class="p">.</span><span class="n">EntityType</span><span class="p">.</span><span class="n">HasKey</span><span class="p">(</span><span class="n">pkg</span> <span class="p">=&gt;</span> <span class="n">pkg</span><span class="p">.</span><span class="n">Version</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">var</span> <span class="n">entityType</span> <span class="p">=</span> <span class="n">model</span>
</span><span class='line'>      <span class="p">.</span><span class="n">FindDeclaredType</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">ODataPackage</span><span class="p">).</span><span class="n">FullName</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">model</span> <span class="p">=</span> <span class="n">builder</span><span class="p">.</span><span class="n">GetEdmModel</span><span class="p">();</span>
</span><span class='line'>    <span class="n">model</span><span class="p">.</span><span class="n">SetHasDefaultStream</span><span class="p">(</span>
</span><span class='line'>       <span class="n">entityType</span> <span class="k">as</span> <span class="n">IEdmEntityType</span><span class="p">,</span> <span class="n">hasStream</span><span class="p">:</span> <span class="k">true</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// snip</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Next we&#8217;ll need to implement a custom <code>ODataSerializerProvider</code>
and <code>ODataEdmTypeSerializer</code> to provide a default stream URL for
entity instances:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">ODataPackageDefaultStreamAwareSerializerProvider</span>
</span><span class='line'>    <span class="p">:</span> <span class="n">DefaultODataSerializerProvider</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">private</span> <span class="k">readonly</span> <span class="n">ODataEdmTypeSerializer</span> <span class="n">entitySerializer</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="nf">ODataPackageDefaultStreamAwareSerializerProvider</span><span class="p">()</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">entitySerializer</span> <span class="p">=</span>
</span><span class='line'>          <span class="k">new</span> <span class="nf">ODataPackageDefaultStreamAwareEntityTypeSerializer</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">override</span> <span class="n">ODataEdmTypeSerializer</span> <span class="nf">GetEdmTypeSerializer</span><span class="p">(</span>
</span><span class='line'>      <span class="n">IEdmTypeReference</span> <span class="n">edmType</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">edmType</span><span class="p">.</span><span class="n">IsEntity</span><span class="p">())</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">entitySerializer</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="k">base</span><span class="p">.</span><span class="n">GetEdmTypeSerializer</span><span class="p">(</span><span class="n">edmType</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">DefaultStreamAwareEntityTypeSerializer</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
</span><span class='line'>    <span class="p">:</span> <span class="n">ODataEntityTypeSerializer</span> <span class="k">where</span> <span class="n">T</span> <span class="p">:</span> <span class="k">class</span>
</span><span class='line'><span class="err">{</span>
</span><span class='line'>    <span class="k">protected</span> <span class="nf">DefaultStreamAwareEntityTypeSerializer</span><span class="p">(</span>
</span><span class='line'>      <span class="n">ODataSerializerProvider</span> <span class="n">serializerProvider</span><span class="p">)</span>
</span><span class='line'>        <span class="p">:</span> <span class="k">base</span><span class="p">(</span><span class="n">serializerProvider</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">override</span> <span class="n">ODataEntry</span> <span class="nf">CreateEntry</span><span class="p">(</span>
</span><span class='line'>      <span class="n">SelectExpandNode</span> <span class="n">selectExpandNode</span><span class="p">,</span>
</span><span class='line'>      <span class="n">EntityInstanceContext</span> <span class="n">entityInstanceContext</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">entry</span> <span class="p">=</span> <span class="k">base</span><span class="p">.</span><span class="n">CreateEntry</span><span class="p">(</span><span class="n">selectExpandNode</span><span class="p">,</span>
</span><span class='line'>          <span class="n">entityInstanceContext</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="kt">var</span> <span class="n">instance</span> <span class="p">=</span> <span class="n">entityInstanceContext</span><span class="p">.</span><span class="n">EntityInstance</span> <span class="k">as</span> <span class="n">T</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">instance</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="kt">var</span> <span class="n">link</span> <span class="p">=</span> <span class="n">BuildLinkForStreamProperty</span><span class="p">(</span>
</span><span class='line'>              <span class="n">instance</span><span class="p">,</span> <span class="n">entityInstanceContext</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="n">entry</span><span class="p">.</span><span class="n">MediaResource</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ODataStreamReferenceValue</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">ContentType</span> <span class="p">=</span> <span class="n">ContentType</span><span class="p">,</span>
</span><span class='line'>                <span class="n">ReadLink</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Uri</span><span class="p">(</span><span class="n">link</span><span class="p">)</span>
</span><span class='line'>            <span class="p">};</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">entry</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">protected</span> <span class="k">virtual</span> <span class="kt">string</span> <span class="n">ContentType</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="s">&quot;application/octet-stream&quot;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">protected</span> <span class="k">abstract</span> <span class="kt">string</span> <span class="nf">BuildLinkForStreamProperty</span><span class="p">(</span>
</span><span class='line'>      <span class="n">T</span> <span class="n">entity</span><span class="p">,</span>
</span><span class='line'>      <span class="n">EntityInstanceContext</span> <span class="n">entityInstanceContext</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">ODataPackageDefaultStreamAwareEntityTypeSerializer</span> <span class="p">:</span> <span class="n">DefaultStreamAwareEntityTypeSerializer</span><span class="p">&lt;</span><span class="n">ODataPackage</span><span class="p">&gt;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="nf">ODataPackageDefaultStreamAwareEntityTypeSerializer</span><span class="p">(</span>
</span><span class='line'>      <span class="n">ODataSerializerProvider</span> <span class="n">serializerProvider</span><span class="p">)</span>
</span><span class='line'>      <span class="p">:</span> <span class="k">base</span><span class="p">(</span><span class="n">serializerProvider</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">protected</span> <span class="k">override</span> <span class="kt">string</span> <span class="nf">BuildLinkForStreamProperty</span><span class="p">(</span>
</span><span class='line'>      <span class="n">ODataPackage</span> <span class="n">package</span><span class="p">,</span>
</span><span class='line'>      <span class="n">EntityInstanceContext</span> <span class="n">context</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">url</span> <span class="p">=</span> <span class="k">new</span> <span class="n">UrlHelper</span><span class="p">(</span><span class="n">context</span><span class="p">.</span><span class="n">Request</span><span class="p">);</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">routeParams</span> <span class="p">=</span> <span class="k">new</span> <span class="p">{</span> <span class="n">package</span><span class="p">.</span><span class="n">Id</span><span class="p">,</span> <span class="n">package</span><span class="p">.</span><span class="n">Version</span> <span class="p">};</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">url</span><span class="p">.</span><span class="n">Link</span><span class="p">(</span><span class="n">RouteNames</span><span class="p">.</span><span class="n">Packages</span><span class="p">.</span><span class="n">Download</span><span class="p">,</span> <span class="n">routeParams</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">protected</span> <span class="k">override</span> <span class="kt">string</span> <span class="n">ContentType</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="s">&quot;application/zip&quot;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The most relevant part above is the override of <code>CreateEntry</code>
(line 33) which sets the <code>MediaResource</code> property on the
serialized <code>ODataEntry</code>.</p>

<p>Finally the custom serializer is wired into the configuration:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="n">config</span><span class="p">.</span><span class="n">Formatters</span><span class="p">.</span><span class="n">InsertRange</span><span class="p">(</span><span class="m">0</span><span class="p">,</span>
</span><span class='line'>    <span class="n">ODataMediaTypeFormatters</span><span class="p">.</span><span class="n">Create</span><span class="p">(</span>
</span><span class='line'>        <span class="k">new</span> <span class="nf">ODataPackageDefaultStreamAwareSerializerProvider</span><span class="p">(),</span>
</span><span class='line'>        <span class="k">new</span> <span class="nf">DefaultODataDeserializerProvider</span><span class="p">()));</span>
</span></code></pre></td></tr></table></div></figure>


<p>This whole mess of code nets us a modest customization in the Atom
output from WebApi OData:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;entry&gt;</span>
</span><span class='line'>  <span class="nt">&lt;id&gt;</span>http://example/api/odata/Packages(Id=&#39;Lucene.Net.Linq&#39;,Version=&#39;3.2.55&#39;)<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>  <span class="nt">&lt;content</span>
</span><span class='line'>    <span class="na">type=</span><span class="s">&quot;application/zip&quot;</span>
</span><span class='line'>    <span class="na">src=</span><span class="s">&quot;http://example/api/packages/Lucene.Net.Linq/3.2.55/content&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>  <span class="c">&lt;!-- snip --&gt;</span>
</span><span class='line'><span class="nt">&lt;/entry&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This enables the NuGet client to download packages.</p>

<p><nav>
  <h3>Series Index</h3>
  <ol>
  <li><a href="http://chris.eldredge.io/blog/2014/04/22/NuGet-Feed-with-WebApi-OData/">Introduction</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/23/Basic-WebApi-OData/">Basic WebApi OData</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/24/Composite-Keys/">Composite Keys</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/29/Default-Streams/">Default Streams</a></li>
  </ol>
</nav></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Composite Keys with WebApi OData]]></title>
    <link href="http://chris.eldredge.io/blog/2014/04/24/Composite-Keys/"/>
    <updated>2014-04-24T11:28:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2014/04/24/Composite-Keys</id>
    <content type="html"><![CDATA[<p>In our basic configuration we told the model builder that
our entity has a composite key comprised of an ID and a
version:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">MapDataServiceRoutes</span><span class="p">(</span><span class="n">HttpConfiguration</span> <span class="n">config</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">var</span> <span class="n">builder</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ODataConventionModelBuilder</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">var</span> <span class="n">entity</span> <span class="p">=</span> <span class="n">builder</span><span class="p">.</span><span class="n">EntitySet</span><span class="p">&lt;</span><span class="n">ODataPackage</span><span class="p">&gt;(</span><span class="s">&quot;Packages&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">entity</span><span class="p">.</span><span class="n">EntityType</span><span class="p">.</span><span class="n">HasKey</span><span class="p">(</span><span class="n">pkg</span> <span class="p">=&gt;</span> <span class="n">pkg</span><span class="p">.</span><span class="n">Id</span><span class="p">);</span>
</span><span class='line'>    <span class="n">entity</span><span class="p">.</span><span class="n">EntityType</span><span class="p">.</span><span class="n">HasKey</span><span class="p">(</span><span class="n">pkg</span> <span class="p">=&gt;</span> <span class="n">pkg</span><span class="p">.</span><span class="n">Version</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// snip</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is enough for our OData feed to render <code>edit</code> and <code>self</code>
links for each individual entity in a form like:</p>

<pre><code>http://localhost/odata/Packages(Id='Sample',Version='1.0.0')
</code></pre>

<p>But if we navigate to this URL, instead of getting just this one
entity by key, we get back the entire entity set.</p>

<p>To get the correct behavior, first we need an override on our
PackagesODataController that gets an individual entity instance
by key:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">PackagesODataController</span> <span class="p">:</span> <span class="n">ODataController</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">IMirroringPackageRepository</span> <span class="n">Repository</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="n">IQueryable</span><span class="p">&lt;</span><span class="n">ODataPackage</span><span class="p">&gt;</span> <span class="n">Get</span><span class="p">()</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">Repository</span><span class="p">.</span><span class="n">GetPackages</span><span class="p">().</span><span class="n">Select</span><span class="p">(</span><span class="n">p</span> <span class="p">=&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">ToODataPackage</span><span class="p">()).</span><span class="n">AsQueryable</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="n">IHttpActionResult</span> <span class="nf">Get</span><span class="p">(</span>
</span><span class='line'><span class="na">        [FromODataUri]</span> <span class="kt">string</span> <span class="n">id</span><span class="p">,</span>
</span><span class='line'><span class="na">        [FromODataUri]</span> <span class="kt">string</span> <span class="n">version</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">package</span> <span class="p">=</span> <span class="n">Repository</span><span class="p">.</span><span class="n">FindPackage</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">version</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">package</span> <span class="p">==</span> <span class="k">null</span>
</span><span class='line'>          <span class="p">?</span> <span class="p">(</span><span class="n">IHttpActionResult</span><span class="p">)</span><span class="n">NotFound</span><span class="p">()</span>
</span><span class='line'>          <span class="p">:</span> <span class="n">Ok</span><span class="p">(</span><span class="n">package</span><span class="p">.</span><span class="n">ToODataPackage</span><span class="p">());</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>However, out of the box WebApi OData doesn&#8217;t know how to bind
composite key parameters to an action such as this, since
the key is comprised of multiple values.</p>

<p>We can fix this by creating a new routing convention that
binds the stuff inside the parenthesis to our route data map:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">CompositeKeyRoutingConvention</span> <span class="p">:</span> <span class="n">IODataRoutingConvention</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">private</span> <span class="k">readonly</span> <span class="n">EntityRoutingConvention</span> <span class="n">entityRoutingConvention</span> <span class="p">=</span>
</span><span class='line'>        <span class="k">new</span> <span class="nf">EntityRoutingConvention</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">virtual</span> <span class="kt">string</span> <span class="nf">SelectController</span><span class="p">(</span>
</span><span class='line'>        <span class="n">ODataPath</span> <span class="n">odataPath</span><span class="p">,</span>
</span><span class='line'>        <span class="n">HttpRequestMessage</span> <span class="n">request</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">entityRoutingConvention</span>
</span><span class='line'>          <span class="p">.</span><span class="n">SelectController</span><span class="p">(</span><span class="n">odataPath</span><span class="p">,</span> <span class="n">request</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">virtual</span> <span class="kt">string</span> <span class="nf">SelectAction</span><span class="p">(</span>
</span><span class='line'>        <span class="n">ODataPath</span> <span class="n">odataPath</span><span class="p">,</span>
</span><span class='line'>        <span class="n">HttpControllerContext</span> <span class="n">controllerContext</span><span class="p">,</span>
</span><span class='line'>        <span class="n">ILookup</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="n">HttpActionDescriptor</span><span class="p">&gt;</span> <span class="n">actionMap</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">action</span> <span class="p">=</span> <span class="n">entityRoutingConvention</span>
</span><span class='line'>            <span class="p">.</span><span class="n">SelectAction</span><span class="p">(</span><span class="n">odataPath</span><span class="p">,</span> <span class="n">controllerContext</span><span class="p">,</span> <span class="n">actionMap</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">action</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="kt">var</span> <span class="n">routeValues</span> <span class="p">=</span> <span class="n">controllerContext</span><span class="p">.</span><span class="n">RouteData</span><span class="p">.</span><span class="n">Values</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="kt">object</span> <span class="k">value</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(!</span><span class="n">routeValues</span><span class="p">.</span><span class="n">TryGetValue</span><span class="p">(</span><span class="n">ODataRouteConstants</span><span class="p">.</span><span class="n">Key</span><span class="p">,</span>
</span><span class='line'>          <span class="k">out</span> <span class="k">value</span><span class="p">))</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>              <span class="k">return</span> <span class="n">action</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="kt">var</span> <span class="n">compoundKeyPairs</span> <span class="p">=</span> <span class="p">((</span><span class="kt">string</span><span class="p">)</span><span class="k">value</span><span class="p">).</span><span class="n">Split</span><span class="p">(</span><span class="sc">&#39;,&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">if</span> <span class="p">(!</span><span class="n">compoundKeyPairs</span><span class="p">.</span><span class="n">Any</span><span class="p">())</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="kt">var</span> <span class="n">keyValues</span> <span class="p">=</span> <span class="n">compoundKeyPairs</span>
</span><span class='line'>            <span class="p">.</span><span class="n">Select</span><span class="p">(</span><span class="n">kv</span> <span class="p">=&gt;</span> <span class="n">kv</span><span class="p">.</span><span class="n">Split</span><span class="p">(</span><span class="sc">&#39;=&#39;</span><span class="p">))</span>
</span><span class='line'>            <span class="p">.</span><span class="n">Select</span><span class="p">(</span><span class="n">kv</span> <span class="p">=&gt;</span>
</span><span class='line'>              <span class="k">new</span> <span class="n">KeyValuePair</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="kt">object</span><span class="p">&gt;(</span><span class="n">kv</span><span class="p">[</span><span class="m">0</span><span class="p">],</span> <span class="n">kv</span><span class="p">[</span><span class="m">1</span><span class="p">]));</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">routeValues</span><span class="p">.</span><span class="n">AddRange</span><span class="p">(</span><span class="n">keyValues</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">action</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This class decorates a standard <code>EntityRoutingConvention</code>
and splits the raw key portion of the URI into key/value pairs
and adds them all to the routeValues dictionary.</p>

<p>Once this is done the standard action resolution kicks in
and finds the correct action overload to invoke.</p>

<p>This routing convention was adapted from the WebApi
<a href="http://aspnet.codeplex.com/SourceControl/changeset/view/9cb7243bd9fe3b2df484bf2409af943f39533588#Samples/WebApi/ODataCompositeKeySample/ODataCompositeKeySample/Extensions/CompositeKeyRoutingConvention.cs">ODataCompositeKeySample</a>
project.</p>

<p>Here we see another difference between WebApi OData and WCF
Data Services. In WCF Data Services, the framework handles
generating a query that selects a single instance from
an <code>IQueryable</code>. This limits our ability to customize
how finding an instance by key is done. In WebApi OData,
we have to explicitly define an overload that gets an
entity instance by key, giving us more control over
how the query is executed.</p>

<p>This distinction might not matter for most projects, but
in the case of <a href="https://github.com/themotleyfool/NuGet.Lucene/tree/master/source/NuGet.Lucene.Web">NuGet.Lucene.Web</a>,
it enables a mirror-on-demand
capability where a local feed can fetch a package from another
server on the fly, add it to the local repository, then
send it back to the client as if it was always there in the
first place.</p>

<p>To customize this in WCF Data Services required
significant <a href="https://github.com/themotleyfool/NuGet.Lucene/blob/v2.9.4/source/NuGet.Lucene.Web/DataServices/PackageDataSource.cs#L17">back</a>
<a href="https://github.com/themotleyfool/NuGet.Lucene/blob/v2.9.4/source/NuGet.Lucene.Web/DataServices/PackageDataService.cs#L171">flips</a>.</p>

<p><nav>
  <h3>Series Index</h3>
  <ol>
  <li><a href="http://chris.eldredge.io/blog/2014/04/22/NuGet-Feed-with-WebApi-OData/">Introduction</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/23/Basic-WebApi-OData/">Basic WebApi OData</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/24/Composite-Keys/">Composite Keys</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/29/Default-Streams/">Default Streams</a></li>
  </ol>
</nav></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Basic WebApi OData]]></title>
    <link href="http://chris.eldredge.io/blog/2014/04/23/Basic-WebApi-OData/"/>
    <updated>2014-04-23T11:28:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2014/04/23/Basic-WebApi-OData</id>
    <content type="html"><![CDATA[<p>Getting started on making a NuGet compatible OData feed with WebApi OData,
we&#8217;ll start with the simplest parts to get on our feet.</p>

<h2>OData Controller</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">PackagesODataController</span> <span class="p">:</span> <span class="n">ODataController</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">IMirroringPackageRepository</span> <span class="n">Repository</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="na">    [Queryable(PageSize = 100, HandleNullPropagation = HandleNullPropagationOption.False)]</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">IQueryable</span><span class="p">&lt;</span><span class="n">ODataPackage</span><span class="p">&gt;</span> <span class="n">Get</span><span class="p">()</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">Repository</span><span class="p">.</span><span class="n">GetPackages</span><span class="p">().</span><span class="n">Select</span><span class="p">(</span><span class="n">p</span> <span class="p">=&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">ToODataPackage</span><span class="p">()).</span><span class="n">AsQueryable</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This controller exposes an entity set of package metadata. The underlying
entity type <code>IPackage</code> has some complex types that OData doesn&#8217;t play well
with, so the types are decorated with <code>ToODataPackage</code> which flattens
and simplifies the metadata into primitive types like strings, bools
and ints.</p>

<p>The <code>QueryableAttribute</code> exposes some very useful settings that allow us to
enable or disable advanced querying options like <code>$select</code>, <code>$expand</code>,
<code>$orderby</code> and others that can be used to lock down the endpoint to avoid
overly expensive or invalid queries from being executed.</p>

<p><code>HandleNullPropagation</code> is a much welcomed offering that wasn&#8217;t easily
tweakable before. It tells the engine whether or not the underlying query
execution engine can handle null values in expressions. The default is
to modify query expressions dynamically to put null-check conditions around
all comparisons and operations like <code>ToLowerCase()</code>, <code>Contains()</code> and such.
This is necessary for LINQ to Collections, but generally not necessary for
other LINQ implementations.</p>

<p>Null Propagation seems like a prudent default,
but it can cause performance problems. David Ebbo <a href="http://blog.davidebbo.com/2011/08/how-odata-quirk-killed-nuget-server.html">wrote</a>
about an issue the NuGet Gallery team encountered. If your LINQ provider
doesn&#8217;t need it, you should definitely turn it off.</p>

<h2>Configuration</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">MapDataServiceRoutes</span><span class="p">(</span><span class="n">HttpConfiguration</span> <span class="n">config</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">var</span> <span class="n">builder</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ODataConventionModelBuilder</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">var</span> <span class="n">entity</span> <span class="p">=</span> <span class="n">builder</span><span class="p">.</span><span class="n">EntitySet</span><span class="p">&lt;</span><span class="n">ODataPackage</span><span class="p">&gt;(</span><span class="s">&quot;Packages&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">entity</span><span class="p">.</span><span class="n">EntityType</span><span class="p">.</span><span class="n">HasKey</span><span class="p">(</span><span class="n">pkg</span> <span class="p">=&gt;</span> <span class="n">pkg</span><span class="p">.</span><span class="n">Id</span><span class="p">);</span>
</span><span class='line'>    <span class="n">entity</span><span class="p">.</span><span class="n">EntityType</span><span class="p">.</span><span class="n">HasKey</span><span class="p">(</span><span class="n">pkg</span> <span class="p">=&gt;</span> <span class="n">pkg</span><span class="p">.</span><span class="n">Version</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">var</span> <span class="n">conventions</span> <span class="p">=</span> <span class="n">ODataRoutingConventions</span><span class="p">.</span><span class="n">CreateDefault</span><span class="p">()</span>
</span><span class='line'>        <span class="p">.</span><span class="n">Select</span><span class="p">(</span><span class="n">c</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="n">IODataRoutingConvention</span><span class="p">)</span>
</span><span class='line'>          <span class="k">new</span> <span class="nf">ControllerAliasingODataRoutingConvention</span><span class="p">(</span>
</span><span class='line'>            <span class="n">c</span><span class="p">,</span> <span class="s">&quot;Packages&quot;</span><span class="p">,</span> <span class="s">&quot;PackagesOData&quot;</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">config</span><span class="p">.</span><span class="n">Routes</span><span class="p">.</span><span class="n">MapODataRoute</span><span class="p">(</span>
</span><span class='line'>        <span class="n">RouteNames</span><span class="p">.</span><span class="n">Packages</span><span class="p">.</span><span class="n">Feed</span><span class="p">,</span>
</span><span class='line'>        <span class="n">ODataRoutePath</span><span class="p">,</span>
</span><span class='line'>        <span class="n">builder</span><span class="p">.</span><span class="n">GetEdmModel</span><span class="p">(),</span>
</span><span class='line'>        <span class="k">new</span> <span class="nf">DefaultODataPathHandler</span><span class="p">(),</span>
</span><span class='line'>        <span class="n">conventions</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is mostly a vanilla configuration but already there are two modifications.</p>

<p>First, the <code>Packages</code> entity set has a composite key that uniquely identifies
each entity instance, comprised of a package ID and version.</p>

<p>The next tweak is that we&#8217;re customizing the default list of OData routing
conventions, wrapping each one with <code>ControllerAliasingODataRoutingConvention</code>.</p>

<p>My project already has a <code>PackagesController</code> that inherits from <code>ApiController</code>.
I wanted to put OData related methods in a separate controller and name it
<code>PackagesODataController</code>, but still have my entity set be named <code>Packages</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">ControllerAliasingODataRoutingConvention</span> <span class="p">:</span> <span class="n">IODataRoutingConvention</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">private</span> <span class="k">readonly</span> <span class="n">IODataRoutingConvention</span> <span class="n">delegateRoutingConvention</span><span class="p">;</span>
</span><span class='line'>    <span class="k">private</span> <span class="k">readonly</span> <span class="kt">string</span> <span class="n">controllerAlias</span><span class="p">;</span>
</span><span class='line'>    <span class="k">private</span> <span class="k">readonly</span> <span class="kt">string</span> <span class="n">targetControllerName</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="nf">ControllerAliasingODataRoutingConvention</span><span class="p">(</span>
</span><span class='line'>        <span class="n">IODataRoutingConvention</span> <span class="n">delegateRoutingConvention</span><span class="p">,</span>
</span><span class='line'>        <span class="kt">string</span> <span class="n">controllerAlias</span><span class="p">,</span>
</span><span class='line'>        <span class="kt">string</span> <span class="n">targetControllerName</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">delegateRoutingConvention</span> <span class="p">=</span> <span class="n">delegateRoutingConvention</span><span class="p">;</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">controllerAlias</span> <span class="p">=</span> <span class="n">controllerAlias</span><span class="p">;</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">targetControllerName</span> <span class="p">=</span> <span class="n">targetControllerName</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="kt">string</span> <span class="nf">SelectController</span><span class="p">(</span><span class="n">ODataPath</span> <span class="n">odataPath</span><span class="p">,</span> <span class="n">HttpRequestMessage</span> <span class="n">request</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">controller</span> <span class="p">=</span> <span class="n">delegateRoutingConvention</span><span class="p">.</span><span class="n">SelectController</span><span class="p">(</span><span class="n">odataPath</span><span class="p">,</span> <span class="n">request</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="kt">string</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="n">controller</span><span class="p">,</span> <span class="n">controllerAlias</span><span class="p">,</span>
</span><span class='line'>                <span class="n">StringComparison</span><span class="p">.</span><span class="n">OrdinalIgnoreCase</span><span class="p">)</span>
</span><span class='line'>            <span class="p">?</span> <span class="n">targetControllerName</span>
</span><span class='line'>            <span class="p">:</span> <span class="n">controller</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="kt">string</span> <span class="nf">SelectAction</span><span class="p">(</span>
</span><span class='line'>        <span class="n">ODataPath</span> <span class="n">odataPath</span><span class="p">,</span>
</span><span class='line'>        <span class="n">HttpControllerContext</span> <span class="n">controllerContext</span><span class="p">,</span>
</span><span class='line'>        <span class="n">ILookup</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="n">HttpActionDescriptor</span><span class="p">&gt;</span> <span class="n">actionMap</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">delegateRoutingConvention</span><span class="p">.</span><span class="n">SelectAction</span><span class="p">(</span>
</span><span class='line'>          <span class="n">odataPath</span><span class="p">,</span> <span class="n">controllerContext</span><span class="p">,</span> <span class="n">actionMap</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is a basic decorator that renames a standard controller name with a desired
target name.</p>

<h2>Summary</h2>

<p>At this point we have a WebApi endpoint that speaks OData. We can enumerate
packages, filter, order and page. We&#8217;re still pretty far from something that
a NuGet client can speak to though.</p>

<p><nav>
  <h3>Series Index</h3>
  <ol>
  <li><a href="http://chris.eldredge.io/blog/2014/04/22/NuGet-Feed-with-WebApi-OData/">Introduction</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/23/Basic-WebApi-OData/">Basic WebApi OData</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/24/Composite-Keys/">Composite Keys</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/29/Default-Streams/">Default Streams</a></li>
  </ol>
</nav></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[NuGet Feed with WebApi OData]]></title>
    <link href="http://chris.eldredge.io/blog/2014/04/22/NuGet-Feed-with-WebApi-OData/"/>
    <updated>2014-04-22T10:25:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2014/04/22/NuGet-Feed-with-WebApi-OData</id>
    <content type="html"><![CDATA[<p>NuGet uses OData to provide package data to its clients. In
<a href="http://chris.eldredge.io/blog/2012/03/29/Getting-Started-With-Relinq/">previous posts</a>
I&#8217;ve written about implementing Lucene.Net.Linq and the difficulty
of implementing <code>IQueryable&lt;T&gt;</code> and leaky abstractions and such.</p>

<p>The NuGet core team has more or less acknowledged that OData is overkill
for the types of operations the client needs (list, search, find updates),
and they&#8217;re even <a href="https://github.com/NuGet/NuGetGallery/issues/595">planning</a>
on migrating away from OData in v3 of their HTTP api.</p>

<p>Unfortunately (or fortunately?) NuGet has achieved wide adoption using
the existing api, so it will take years for everyone to update their clients
once this new api has shipped.</p>

<p>In the mean time, we&#8217;re stuck with OData.</p>

<p>To make the most of the situation, I wanted to try out the new WebApi
integrated OData packages. These packages allow us to use the same base classes
and infrastructure as regular WebApi controllers. They also enable us
to build and deploy self-hosted applications to decouple us from IIS.</p>

<p>WebApi OData has seen lots of features get implemented and adds supports
for newer protocol versions of OData. However, there are a few things that
the NuGet clients require that are not built in. This series will
go over configuring WebApi OData to create a NuGet compatible package feed.</p>

<h2>Required Features</h2>

<p>OData is a huge standard and NuGet uses only a subset of capabilities.
Here&#8217;s a list of what we&#8217;ll need to support:</p>

<ul>
<li>Entity Sets</li>
<li>Composite Keys</li>
<li>Actions</li>
<li>Default Streams</li>
<li>$count meta-action</li>
<li>$filter</li>
<li>$orderby</li>
<li>Paging with $top and $skip</li>
</ul>


<p>Most of these capabilities are built into WebApi OData.
The ones that aren&#8217;t will be covered in the following articles.</p>

<p><nav>
  <h3>Series Index</h3>
  <ol>
  <li><a href="http://chris.eldredge.io/blog/2014/04/22/NuGet-Feed-with-WebApi-OData/">Introduction</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/23/Basic-WebApi-OData/">Basic WebApi OData</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/24/Composite-Keys/">Composite Keys</a></li>
  <li><a href="http://chris.eldredge.io/blog/2014/04/29/Default-Streams/">Default Streams</a></li>
  </ol>
</nav></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[WinDbg: Dump entries in array]]></title>
    <link href="http://chris.eldredge.io/blog/2014/03/05/windbg-dump-entries-in-array/"/>
    <updated>2014-03-05T11:47:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2014/03/05/windbg-dump-entries-in-array</id>
    <content type="html"><![CDATA[<p>I was debugging a stack overflow exception in some c# code
today and used this recipe to dump the request headers
associated with the offending thread.</p>

<p>I&#8217;m leaving it here for my own reference.</p>

<p>This recipe dumps the key and value fields in an array of
NameObjectCollectionBase+NameObjectEntry, though it would
probably work with similar key/value tuples.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>.foreach /pS 16 /ps 1 (addr {!da 3ffc0c460}) {
</span><span class='line'>  .if ($sicmp("${addr}", "null") != 0) {
</span><span class='line'>    !do poi(${addr}+8); !do poi(${addr}+10)
</span><span class='line'>  }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p><em>Note: the sample code above is formatted for readability. Remove
line breaks before using it in windbg, which doesn&#8217;t seem to handle
line breaks in commands well.</em></p>

<p>The DumpArray command in SOS does not have a <code>-short</code> flag like
DumpHeap does, so the foreach skips the first 16 tokens, then
skips a single token for each item processed. This effectively
selects array item addresses from the output.</p>

<p>Inside the foreach block, I check that the address is not <code>null</code>,
then dump the fields at offsets 8 and 16 (0x10 in hex).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The newer new NuGet Package Restore]]></title>
    <link href="http://chris.eldredge.io/blog/2014/01/29/the-newer-new-nuget-package-restore/"/>
    <updated>2014-01-29T13:01:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2014/01/29/the-newer-new-nuget-package-restore</id>
    <content type="html"><![CDATA[<p>When NuGet 2.7 was released, the topic of how to manage packages in your source
repository was <a href="http://docs.nuget.org/docs/reference/package-restore">revisited</a> and the waters were muddied.</p>

<p>The new guidance is to not use the &#8220;Enable NuGet Package Restore&#8221; option in
Visual Studio, but instead to let it happen automatically.</p>

<p>Unfortunately, many developers will probably miss this guidance if they&#8217;re already
used to restoring packages as part of their workflow.</p>

<p>The option offered when right-clicking the Solution in Visual Studio gives no
indication that the option is deprecated, and the text implies that if you don&#8217;t
activate the option, packge restore will not be enabled.</p>

<p>These are minor annoyances that will hopefully be addressed as more users
adopt NuGet 2.7 and later clients.</p>

<hr />

<p>One thing the guidance fails to address completely is how an automated build
system, like a Continuous Integration server, should approach restoring packages.</p>

<p>The section that covers this topic explains how packages can be restored using
the NuGet comand line client prior to building the solution, but where are
you supposed to get nuget.exe from?</p>

<p>There are 3 approaches you can take to address this:</p>

<ol>
<li>Assume the build server is configured to have a recent nuget.exe on the PATH</li>
<li>Check nuget.exe into your source repository</li>
<li>Fetch the latest nuget.exe from nuget.org on the fly.</li>
</ol>


<p>The now obsolete &#8220;Enable NuGet Package Restore&#8221; option did a mix of (2) and (3).
It would look for nuget.exe in the .nuget folder, and if it isn&#8217;t found and some
options are enabled, it will download it from the web.</p>

<p>How can we continue using this feature while moving towards the new One True Way
of Package Restore?</p>

<p>We can do it by co-opting parts of <a href="http://nuget.codeplex.com/SourceControl/latest#src/Build/NuGet.targets">NuGet.targets</a> in our own build script.</p>

<p>First, layout:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>project/
</span><span class='line'>project/IntegratedBuild.proj
</span><span class='line'>project/NuGet.targets
</span><span class='line'>project/source/
</span><span class='line'>project/source/Foo.sln</span></code></pre></td></tr></table></div></figure>


<h2>IntegratedBuild.proj</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
</span><span class='line'><span class="nt">&lt;Project</span> <span class="na">ToolsVersion=</span><span class="s">&quot;12.0&quot;</span> <span class="na">DefaultTargets=</span><span class="s">&quot;Build&quot;</span> <span class="na">xmlns=</span><span class="s">&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;PropertyGroup&gt;</span>
</span><span class='line'>    <span class="nt">&lt;SolutionDir&gt;</span>$(MSBuildProjectDirectory)\source\<span class="nt">&lt;/SolutionDir&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/PropertyGroup&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;ItemGroup&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Solution</span> <span class="na">Include=</span><span class="s">&quot;$(SolutionDir)*.sln&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/ItemGroup&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;Target</span> <span class="na">Name=</span><span class="s">&quot;Build&quot;</span> <span class="na">DependsOnTargets=</span><span class="s">&quot;RestoreSolutionPackages;BuildSolution&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;Target</span> <span class="na">Name=</span><span class="s">&quot;RestoreSolutionPackages&quot;</span> <span class="na">DependsOnTargets=</span><span class="s">&quot;DownloadNuGetCommandLineClient&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Exec</span> <span class="na">Command=</span><span class="s">&quot;$(NuGetCommand) restore $(SolutionDir) -NonInteractive -Source http://www.nuget.org/api/v2/&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/Target&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;Target</span> <span class="na">Name=</span><span class="s">&quot;BuildSolution&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;MSBuild</span> <span class="na">Projects=</span><span class="s">&quot;@(Solution)&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/Target&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;Import</span> <span class="na">Project=</span><span class="s">&quot;NuGet.targets&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;/Project&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>NuGet.targets</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
</span><span class='line'><span class="nt">&lt;Project</span> <span class="na">ToolsVersion=</span><span class="s">&quot;4.0&quot;</span> <span class="na">xmlns=</span><span class="s">&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;PropertyGroup&gt;</span>
</span><span class='line'>    <span class="nt">&lt;NuGetToolsPath&gt;</span>$(MSBuildThisFileDirectory)<span class="nt">&lt;/NuGetToolsPath&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/PropertyGroup&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;PropertyGroup&gt;</span>
</span><span class='line'>    <span class="nt">&lt;NuGetExePath</span> <span class="na">Condition=</span><span class="s">&quot; &#39;$(NuGetExePath)&#39; == &#39;&#39; &quot;</span><span class="nt">&gt;</span>$(NuGetToolsPath)\NuGet.exe<span class="nt">&lt;/NuGetExePath&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nt">&lt;NuGetCommand</span> <span class="na">Condition=</span><span class="s">&quot; &#39;$(OS)&#39; == &#39;Windows_NT&#39;&quot;</span><span class="nt">&gt;</span>&quot;$(NuGetExePath)&quot;<span class="nt">&lt;/NuGetCommand&gt;</span>
</span><span class='line'>    <span class="nt">&lt;NuGetCommand</span> <span class="na">Condition=</span><span class="s">&quot; &#39;$(OS)&#39; != &#39;Windows_NT&#39; &quot;</span><span class="nt">&gt;</span>mono --runtime=v4.0.30319 $(NuGetExePath)<span class="nt">&lt;/NuGetCommand&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/PropertyGroup&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;Target</span> <span class="na">Name=</span><span class="s">&quot;DownloadNuGetCommandLineClient&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;DownloadNuGet</span> <span class="na">OutputFilename=</span><span class="s">&quot;$(NuGetExePath)&quot;</span> <span class="na">Condition=</span><span class="s">&quot; !Exists(&#39;$(NuGetExePath)&#39;)&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/Target&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;UsingTask</span> <span class="na">TaskName=</span><span class="s">&quot;DownloadNuGet&quot;</span> <span class="na">TaskFactory=</span><span class="s">&quot;CodeTaskFactory&quot;</span> <span class="na">AssemblyFile=</span><span class="s">&quot;$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;ParameterGroup&gt;</span>
</span><span class='line'>      <span class="nt">&lt;OutputFilename</span> <span class="na">ParameterType=</span><span class="s">&quot;System.String&quot;</span> <span class="na">Required=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/ParameterGroup&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Task&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Reference</span> <span class="na">Include=</span><span class="s">&quot;System.Core&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Using</span> <span class="na">Namespace=</span><span class="s">&quot;System&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Using</span> <span class="na">Namespace=</span><span class="s">&quot;System.IO&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Using</span> <span class="na">Namespace=</span><span class="s">&quot;System.Net&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Using</span> <span class="na">Namespace=</span><span class="s">&quot;Microsoft.Build.Framework&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Using</span> <span class="na">Namespace=</span><span class="s">&quot;Microsoft.Build.Utilities&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Code</span> <span class="na">Type=</span><span class="s">&quot;Fragment&quot;</span> <span class="na">Language=</span><span class="s">&quot;cs&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>          <span class="cp">&lt;![CDATA[</span>
</span><span class='line'><span class="cp">          try {</span>
</span><span class='line'><span class="cp">              OutputFilename = Path.GetFullPath(OutputFilename);</span>
</span><span class='line'>
</span><span class='line'><span class="cp">              Log.LogMessage(&quot;Downloading latest version of NuGet.exe...&quot;);</span>
</span><span class='line'><span class="cp">              WebClient webClient = new WebClient();</span>
</span><span class='line'><span class="cp">              webClient.DownloadFile(&quot;https://www.nuget.org/nuget.exe&quot;, OutputFilename);</span>
</span><span class='line'>
</span><span class='line'><span class="cp">              return true;</span>
</span><span class='line'><span class="cp">          }</span>
</span><span class='line'><span class="cp">          catch (Exception ex) {</span>
</span><span class='line'><span class="cp">              Log.LogErrorFromException(ex);</span>
</span><span class='line'><span class="cp">              return false;</span>
</span><span class='line'><span class="cp">          }</span>
</span><span class='line'><span class="cp">      ]]&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/Code&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/Task&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/UsingTask&gt;</span>
</span><span class='line'><span class="nt">&lt;/Project&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<hr />

<p>Make sure to add NuGet.exe to your .gitignore or equivalent scm configuration.</p>

<p>It&#8217;s a little unfortunate that this boilerplate has to be copied from one project to another.
However, since we&#8217;re bootstrapping NuGet we have a chicken and egg problem that prevents
the targets from being shared in a package.</p>

<p>I hope this helps developers get the most out of NuGet&#8217;s latest approach to restoring
packages while avoiding needing to check NuGet.exe into source control and keep it up to
date.</p>

<p>This won&#8217;t work with xbuild on Mono since it does not support CodeTaskFactory, but if
you are using mono you could add an alternate target that uses curl or wget to perform
the download. Assuming curl or wget are already on your PATH. Sigh.</p>

<hr />

<p>A simpler approach if you know curl is on the system is to use a different scripting
language, that effectively does</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'>curl -o nuget.exe https://www.nuget.org/nuget.exe
</span><span class='line'>./nuget.exe restore source -NonInteractive
</span><span class='line'>msbuild source\*.sln
</span></code></pre></td></tr></table></div></figure>


<p>But why use 3 lines of script when you can have a 100 lines of XML?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Cross-NuGet Development With Slimjim]]></title>
    <link href="http://chris.eldredge.io/blog/2014/01/12/cross-nuget-development-with-slimjim/"/>
    <updated>2014-01-12T16:00:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2014/01/12/cross-nuget-development-with-slimjim</id>
    <content type="html"><![CDATA[<p>Last week Phil Haack observed:</p>

<div class='embed tweet'><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Submodules and NuGet don&#39;t play well together. :(</p>&mdash; Haack the planet (@haacked) <a href="https://twitter.com/haacked/status/421160899856969728?ref_src=twsrc%5Etfw">January 9, 2014</a></blockquote>
<script async src="http://chris.eldredge.io//platform.twitter.com/widgets.js" charset="utf-8"></script></div>


<p>I think Phil is trying to solve the same problem lots of .NET developers
run into. Let&#8217;s say you have a web project that is using the wonderful
<a href="https://github.com/themotleyfool/Lucene.Net.Linq/">Lucene.Net.Linq package</a>
and you want to fix a bug or add a feature to the library, and test
it in your web project without needing to manually copy DLLs around
from one solution to another.</p>

<p>This is a workflow I use constantly, and the tool I use to minimize
friction during development is <a href="https://github.com/themotleyfool/Slimjim">Slimjim</a>.</p>

<p>Slimjim, in a nut, is a command line tool that generates Visual Studio solution
files. The killer feature is that it will also modify csproj files
to replace assembly references with project references. This way
you can have a solution with all the projects you want to work with,
and when you hit &lt;ctrl>+&lt;shift>+B to build the solution, everything
builds in the right order and your top level project gets the
newly compiled code without you needing to do any extra work.</p>

<h2>An Example</h2>

<p>Most of my open source work recently has been on <a href="https://github.com/themotleyfool/Klondike">Klondike</a>,
a fast NuGet package server you can host on your private network.</p>

<p>This project has actually exploded into lots of sub-projects,
each of which correlates to one or more NuGet packages available
on nuget.org.</p>

<h3>Getting the Source</h3>

<p>First, we need to clone all of the repositories that have code
we want to work on.</p>

<pre><code>mkdir workspace
cd workspace
git clone https://github.com/themotleyfool/Klondike
git clone https://github.com/themotleyfool/NuGet.Lucene
git clone https://github.com/themotleyfool/Lucene.Net.Linq
git clone https://github.com/themotleyfool/AspNet.WebApi.HtmlMicrodataFormatter
</code></pre>

<p>I said there were a lot of projects right? For fun let&#8217;s pull in some 3rd party
open source code too. That way we can get debug builds and browse the code
to better understand it.</p>

<pre><code>git clone https://git01.codeplex.com/nuget
svn checkout https://svn.apache.org/repos/asf/lucene.net/tags/Lucene.Net_3_0_3_RC2_final/ Lucene.Net
</code></pre>

<p>And note in some cases you may want to checkout a tag or branch other
than master. For nuget:</p>

<pre><code>cd nuget
git checkout Release-2.7.2
cd ..
</code></pre>

<h3>Getting Slimjim</h3>

<p>Slimjim is on nuget.org, so you can install it locally by doing:</p>

<pre><code>nuget install slimjim
</code></pre>

<p>And now we have our utility in ./Slimjim.1.0.3/tools/Slimjim.exe</p>

<h3>Generating a Solution</h3>

<p>Running Slimjim without any flags will create a Solution that includes
all csproj projects found under the current directory.</p>

<p>There may be projects you don&#8217;t care about that you don&#8217;t want
cluttering your workspace. For example, Nuget has lots of projects and
I only depend on Nuget.Core.</p>

<p>Since I&#8217;m working on Klondike, I&#8217;ll tell Slimjim to target that project
and include anything it depends on, recursively.</p>

<pre><code>./Slimjim.1.0.3/tools/Slimjim.exe -t Klondike -a -c
</code></pre>

<p>The <code>-a</code> switch says to include efferent dependencies, and the <code>-c</code> switch
says to modify the csproj files to convert assembly references to project
references.</p>

<p>If we look at one of the csproj files, we can see an example of this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gh">diff --git a/source/Klondike/Klondike.csproj b/source/Klondike/Klondike.csproj</span>
</span><span class='line'><span class="gh">index 049d8eb..df61e4b 100644</span>
</span><span class='line'><span class="gd">--- a/source/Klondike/Klondike.csproj</span>
</span><span class='line'><span class="gi">+++ b/source/Klondike/Klondike.csproj</span>
</span><span class='line'><span class="gu">@@ -45,10 +45,16 @@</span>
</span><span class='line'>       &lt;SpecificVersion&gt;False&lt;/SpecificVersion&gt;
</span><span class='line'>       &lt;HintPath&gt;..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll&lt;/HintPath&gt;
</span><span class='line'>     &lt;/Reference&gt;
</span><span class='line'><span class="gd">-    &lt;Reference Include=&quot;AspNet.WebApi.HtmlMicrodataFormatter, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL&quot;&gt;</span>
</span><span class='line'><span class="gd">-      &lt;SpecificVersion&gt;False&lt;/SpecificVersion&gt;</span>
</span><span class='line'><span class="gd">-      &lt;HintPath&gt;..\packages\AspNet.WebApi.HtmlMicrodataFormatter.2.0.0\lib\net40\AspNet.WebApi.HtmlMicrodataFormatter.dll&lt;/HintPath&gt;</span>
</span><span class='line'><span class="gd">-    &lt;/Reference&gt;</span>
</span><span class='line'><span class="gi">+    &lt;ProjectReference Include=&quot;C:\Projects\workspace\AspNet.WebApi.HtmlMicrodataFormatter\source\AspNet.WebApi.HtmlMicrodataFormatter\AspNet.WebApi.HtmlMicrodataFormatt+      &lt;Project&gt;{794ACAF9-D25C-4571-B801-9FC2CF86C1B4}&lt;/Project&gt;</span>
</span><span class='line'><span class="gi">+      &lt;Name&gt;AspNet.WebApi.HtmlMicrodataFormatter&lt;/Name&gt;</span>
</span><span class='line'><span class="gi">+      &lt;SlimJimReplacedReference&gt;</span>
</span><span class='line'><span class="gi">+        &lt;Reference Include=&quot;AspNet.WebApi.HtmlMicrodataFormatter, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL&quot;&gt;</span>
</span><span class='line'><span class="gi">+          &lt;SpecificVersion&gt;False&lt;/SpecificVersion&gt;</span>
</span><span class='line'><span class="gi">+          &lt;HintPath&gt;..\packages\AspNet.WebApi.HtmlMicrodataFormatter.2.0.0\lib\net40\AspNet.WebApi.HtmlMicrodataFormatter.dll&lt;/HintPath&gt;</span>
</span><span class='line'><span class="gi">+        &lt;/Reference&gt;</span>
</span><span class='line'><span class="gi">+      &lt;/SlimJimReplacedReference&gt;</span>
</span><span class='line'><span class="gi">+    &lt;/ProjectReference&gt;</span>
</span><span class='line'>     &lt;Reference Include=&quot;Common.Logging, Version=2.1.2.0, Culture=neutral, PublicKeyToken=af08829b84f0328e, processorArchitecture=MSIL&quot;&gt;
</span></code></pre></td></tr></table></div></figure>


<p>Remember not to commit this or you&#8217;ll have a bad time!</p>

<h3>Fixing some NuGet things</h3>

<p>This is where we&#8217;ll hit some friction. I&#8217;d like to improve Slimjim to handle
some of these problems, but the good news is you only have to do this once.</p>

<p>If any of your projects are using NuGet&#8217;s package restore feature, your newly
generated solution probably won&#8217;t build. This is because NuGet expects to have
some resources available relative to the <code>$(SolutionDir)</code> property, and
our Solution file is in a directory that doesn&#8217;t have these tools.</p>

<p>I usually copy them from one of the projects:</p>

<pre><code>cp -R Klondike/source/.nuget .
</code></pre>

<p>Additionally, assembly hint paths are hard-coded in the csproj files, usually like:</p>

<pre><code>&lt;HintPath&gt;..\packages\SomeLib.1.0\lib\net40\SomeLib.dll&lt;/HintPath&gt;
</code></pre>

<p>However, when you build from the solution file in workspace, NuGet will restore packages
relative to this directory, so the csproj files won&#8217;t be able to see them.</p>

<p>The simple fix is to build each project individually so it will restore packages
to the right place. After each individual repo&#8217;s solution builds, we&#8217;ll be able
to build from our Slimjim solution.</p>

<p>The more complex solution is to use NTFS junctions to make sure each repo is
using the same package directory.</p>

<pre><code>mkdir packages
cd Lucene.Net.Linq/source
mklink /j packages ..\..\packages
</code></pre>

<h3>Doing actual work</h3>

<p>Now we have a Solution with the projects we want to work on and it should
build successfully from the command line using msbuild.exe.</p>

<p>We can open the Solution in Visual Studio, write code, build, test with IIS
or IIS Express, run unit tests, write more unit tests, and all the other good
stuff we like doing.</p>

<h3>Releasing</h3>

<p>Once we&#8217;ve made changes we&#8217;re happy with, we have to undo the changes Slimjim
made to our csproj files before we can commit:</p>

<pre><code>./Slimjim.1.0.3/tools/Slimjim.exe -t Klondike -a -u
</code></pre>

<p>The <code>-u</code> switch is the correlary to <code>-c</code>, restoring assembly references that
we had turned into project references before.</p>

<p>Now we can commit/push/pull request, push packages to nuget.org, then
update packages in the projects that need them.</p>

<h3>Looking ahead</h3>

<p>This workflow is not perfect. It requires some manual setup and upkeep
whenever we want to pull changes and keep everything in sync. It introduces
a danger in that you might accidentally commit stuff to your csproj. If
you update any nuget packages while working in your generated Solution,
the hint paths will point to the wrong packages folder.</p>

<p>I&#8217;d like to explore how Slimjim can address some of these problems.
It would also be nice if nuget was a little more dynamic about hint paths.</p>

<p>In the mean time, Slimjim makes it possible to write features across
disparate projects without needing to push new binaries or manually
copy DLL files around.</p>

<h3>Git submodules</h3>

<p>Coming back to what @haacked wanted to do, it would be possible to
treat your workspace folder as a new git repo and include each repo
within as a submodule. This could reduce some friction for teams
that want to work using a shared pattern.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Putting the web into WebApi]]></title>
    <link href="http://chris.eldredge.io/blog/2013/07/30/putting-the-web-into-webapi/"/>
    <updated>2013-07-30T00:00:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2013/07/30/putting-the-web-into-webapi</id>
    <content type="html"><![CDATA[<p>For .net api developers, the WebApi framework offers a compelling alternative
to asp.net mvc for slinging json or (gasp) xml over http. One great feature
you get out of the box is content negotiation, where WebApi will look at
request headers to decide which format to use when processing a request
body or sending back a response.</p>

<p>WebApi also includes the concept of an <a href="http://msdn.microsoft.com/en-us/library/system.web.http.description.apiexplorer(v=vs.108).aspx">ApiExplorer</a>,
a built in service that knows about all the routes, templates and parameters
an application is configured to handle. It even supports attaching human friendly
documentation.</p>

<p>With these built in perks, WebApi gets you 95% of the way there. What it
doesn&#8217;t do out of the box, unfortunately, is something that it says right
on the box. It doesn&#8217;t do web.</p>

<h2>HTTP, ReST and the Web</h2>

<p>Writing an application that speaks json over http does not automatically give
you something that can be called ReST. To get to ReST nirvana your api needs
to speak using hypermedia, providing the client with not just data, but
links and forms that can do stuff with the data.</p>

<p>If you aren&#8217;t familiar with this distinction, here are some great resources:</p>

<ul>
<li><a href="http://martinfowler.com/articles/richardsonMaturityModel.html">Richardson Maturity Model</a></li>
<li><a href="http://www.infoq.com/presentations/web-api-html">Building Hypermedia APIs with HTML</a> (talk by Jon Moore)</li>
<li><a href="https://speakerdeck.com/stilkov">Slide decks by Stefan Tilkov</a></li>
<li><a href="https://speakerdeck.com/ammeep/exist-in-the-web-not-on-it">Exist In the Web - Not on it</a> slide deck by Amy Palamountain</li>
</ul>


<h2>Microdata</h2>

<p>Jon Moore&#8217;s work is particularly intriguing because he shows what
you can already do with <a href="http://en.wikipedia.org/wiki/Microdata_(HTML)">Microdata</a>.</p>

<p>Microdata boils down to 3 attributes that you stick on elements in your
html5 markup, and they&#8217;re all you need to give semantic information
to a client. You can nest properties into a scope, describe the type of data
being represented, and even nest scopes with scopes recursively.</p>

<p>Jon&#8217;s talks show how a web client that speaks Microdata can already start
on sites like <a href="http://ebay.com/">ebay.com</a>, submit a form and find and manipulate
resources without knowing anything ahead of time about what resources are there and
what URLs are used to access them.</p>

<hr />

<p><strong>Update:</strong> In the (long) time between drafting this post and publishing it, Microdata <a href="http://manu.sporny.org/2013/microdata-downward-spiral/">has died</a>. The spirit of this post remains intact, but I&#8217;ll probably be looking into
switching to <a href="http://www.w3.org/TR/rdfa-lite/">RDFa Lite</a>.</p>

<hr />

<h2>WebApi + Microdata</h2>

<p>On the one hand we have a .net framework for writing HTTP apis that
has pluggable support for different content types. On the other hand we
have html5 and Microdata. Think they could be friends?</p>

<p>I&#8217;m excited to announce HtmlMicrodataFormatter,
a new open source (Apache Public License) project available
on <a href="http://www.nuget.org/packages/AspNet.WebApi.HtmlMicrodataFormatter.WebActivator/">nuget.org</a>
and hosted on <a href="https://github.com/themotleyfool/AspNet.WebApi.HtmlMicrodataFormatter">GitHub</a>.</p>

<p>When you install this package into your WebApi project, it adds two
features.</p>

<p>First, if you enter the URL for one of your api methods into a web
browser, you get (relatively) nice, human friendly html5 instead
of the wall of xml you would otherwise be greeted with.</p>

<p>Second, and perhaps more importantly, if you browse to ~/api,
you will be greeted by an html5 page that includes links and
forms for all the routes that are registered with ApiExplorer.</p>

<p>You can fill in the inputs and submit forms to test them out
right in the browser. If your routes are templated, a javascript
event handler will process the URI template and update the form
action just before the form is submitted.</p>

<p>Turn on xml documentation for your project, rebuild, and now
all the documentation comments you attach to your controllers
and actions appear on the forms.</p>

<h2>Why it Matters</h2>

<p>Obviously, getting a free html form generated for
each action can be a productivity boon for developers who
are tired of writing</p>

<pre><code>curl -X POST -H 'Accept: application/json' \
  --data 'param1=value1&amp;param2=value2' \
  http://localhost:49497/api/users/fred'
</code></pre>

<p>But it&#8217;s more than that. Make your client project use html5
and instead of hard-coding URLs for each thing the client
wants to do, the client starts at /api, finds the form it wants,
fills it in and submits it. The Microdata attributes in
the response, along with links and forms, give the client
the pieces it needs to drive state, just like Roy T. Fielding
intended when ReST was first described.</p>

<p>Do you have third party developers who consume your api? Now you
don&#8217;t have to give them a separate document or website
that describes (out of band) how to use your api. Just
link them to <code>yourwebsite/api</code>, and they can read the
documentation and discover what they can do without
guessing or following brittle conventions.</p>

<p>Putting the web into WebApi removes the tight coupling
between client and server. Now you can change your routes,
rename parameters, add parameters, and the client will
automatically see those changes reflected in the forms
and links they get when they enter your api. No more <code>/api/v1/users</code>
through <code>/api/v23/users</code>. No more api version headers.</p>

<h2>Next Steps</h2>

<p>HtmlMicrodataFormatter is pretty young and there are
many ideas left to flesh out. For example, making it easy to add
links and forms to the output of controller actions,
or improving how xml documentation is collected and
converted to html, or making it easier to link from
resources to related resources with appropriate rel
attributes. The list goes on.</p>

<p>I hope you like HtmlMicrodataFormatter, and if you
do, maybe get involved and help improve it by
submitting feedback, bug reports, enhancements or pull
requests to the GitHub project.</p>

<p>Similar to Jon Moore&#8217;s python based microdata
client, work has started on a .net dynamic
client which I hope to share soon.</p>

<hr />

<p>Get the source and see examples at <a href="https://github.com/themotleyfool/AspNet.WebApi.HtmlMicrodataFormatter">https://github.com/themotleyfool/AspNet.WebApi.HtmlMicrodataFormatter</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fun with NuGet Web Api]]></title>
    <link href="http://chris.eldredge.io/blog/2013/02/25/fun-with-nuget-rest-api/"/>
    <updated>2013-02-25T10:57:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2013/02/25/fun-with-nuget-rest-api</id>
    <content type="html"><![CDATA[<p>NuGet is a package management system for .net. Like most things these days, NuGet uses HTTP
for client/server communication to enable search, download, upload and other operations.</p>

<p>Since I&#8217;ve been working on writing a NuGet web application, I have had the opportunity to
become intimately familiar with the web api and its wrinkles.</p>

<p>I was going to title this post &#8220;Fun with the NuGet REST Api&#8221;, but then I had to change it
because what NuGet does is pretty far from RESTful. The documentation for
<a href="https://github.com/NuGet/NuGetGallery/wiki/Tab-Completion-API-Endpoints">Tab Completion Endpoints</a>
openly acknowledges this, stating, &#8220;We currently don&#8217;t look at the Accept header or do lots of other
proper HTTP API stuff&#8221;. Caveat emptor.</p>

<p>There have been plenty of well written posts about what REST is and why most things that
speak json or xml over HTTP are not Restful.</p>

<ol>
<li><a href="http://kellabyte.com/2011/09/04/clarifying-rest/">Clarifying REST</a> from @kellabyte</li>
<li><a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">Representational State Transfer (REST)</a> Roy Fielding&#8217;s doctoral thesis</li>
<li><a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">REST APIs must be hypertext-driven</a></li>
</ol>


<h2>WCF Data Services and REST</h2>

<p>NuGet has used WCF Data Services (OData) since inception to do the heavy lifting.
OData kind of sort of does a decent job of adhering to RESTful constraints and
using hyperlinks that give hints to clients about collections, entities and
functions that can be invoked on them.</p>

<p>Query the API Root:</p>

<pre><code>curl http://nuget.org/api/v2/
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;</span>
</span><span class='line'><span class="nt">&lt;service</span> <span class="na">xml:base=</span><span class="s">&quot;http://nuget.org/api/v2/&quot;</span> <span class="na">xmlns:atom=</span><span class="s">&quot;http://www.w3.org/2005/Atom&quot;</span> <span class="na">xmlns:app=</span><span class="s">&quot;http://www.w3.org/2007/app&quot;</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.w3.org/2007/app&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;workspace&gt;</span>
</span><span class='line'>    <span class="nt">&lt;atom:title&gt;</span>Default<span class="nt">&lt;/atom:title&gt;</span>
</span><span class='line'>    <span class="nt">&lt;collection</span> <span class="na">href=</span><span class="s">&quot;Packages&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;atom:title&gt;</span>Packages<span class="nt">&lt;/atom:title&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/collection&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/workspace&gt;</span>
</span><span class='line'><span class="nt">&lt;/service&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can see there&#8217;s a collection of Packages, and you even get an href that tells you where it is.</p>

<p>Unfortunately it does not tell you about the magic $metadata RPC call that gets you more
information about the entities contained in the Packages collection, and what other functions
are available:</p>

<pre><code>curl 'http://nuget.org/api/v2/$metadata'
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;</span>
</span><span class='line'><span class="nt">&lt;edmx:Edmx</span> <span class="na">Version=</span><span class="s">&quot;1.0&quot;</span> <span class="na">xmlns:edmx=</span><span class="s">&quot;http://schemas.microsoft.com/ado/2007/06/edmx&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;edmx:DataServices</span> <span class="na">xmlns:m=</span><span class="s">&quot;http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&quot;</span> <span class="na">m:DataServiceVersion=</span><span class="s">&quot;2.0&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Schema</span> <span class="na">Namespace=</span><span class="s">&quot;NuGetGallery&quot;</span> <span class="na">xmlns:d=</span><span class="s">&quot;http://schemas.microsoft.com/ado/2007/08/dataservices&quot;</span> <span class="na">xmlns:m=</span><span class="s">&quot;http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&quot;</span> <span class="na">xmlns=</span><span class="s">&quot;http://schemas.microsoft.com/ado/2006/04/edm&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;EntityType</span> <span class="na">Name=</span><span class="s">&quot;V2FeedPackage&quot;</span> <span class="na">m:HasStream=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;Key&gt;</span>
</span><span class='line'>          <span class="nt">&lt;PropertyRef</span> <span class="na">Name=</span><span class="s">&quot;Id&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>          <span class="nt">&lt;PropertyRef</span> <span class="na">Name=</span><span class="s">&quot;Version&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;/Key&gt;</span>
</span><span class='line'>        <span class="nt">&lt;Property</span> <span class="na">Name=</span><span class="s">&quot;Id&quot;</span> <span class="na">Type=</span><span class="s">&quot;Edm.String&quot;</span> <span class="na">Nullable=</span><span class="s">&quot;false&quot;</span> <span class="na">m:FC_TargetPath=</span><span class="s">&quot;SyndicationTitle&quot;</span> <span class="na">m:FC_ContentKind=</span><span class="s">&quot;text&quot;</span> <span class="na">m:FC_KeepInContent=</span><span class="s">&quot;false&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;Property</span> <span class="na">Name=</span><span class="s">&quot;Version&quot;</span> <span class="na">Type=</span><span class="s">&quot;Edm.String&quot;</span> <span class="na">Nullable=</span><span class="s">&quot;false&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;Property</span> <span class="na">Name=</span><span class="s">&quot;Authors&quot;</span> <span class="na">Type=</span><span class="s">&quot;Edm.String&quot;</span> <span class="na">Nullable=</span><span class="s">&quot;true&quot;</span> <span class="na">m:FC_TargetPath=</span><span class="s">&quot;SyndicationAuthorName&quot;</span> <span class="na">m:FC_ContentKind=</span><span class="s">&quot;text&quot;</span> <span class="na">m:FC_KeepInContent=</span><span class="s">&quot;false&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;snip/&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/EntityType&gt;</span>
</span><span class='line'>      <span class="nt">&lt;EntityContainer</span> <span class="na">Name=</span><span class="s">&quot;FeedContext_x0060_1&quot;</span> <span class="na">m:IsDefaultEntityContainer=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;EntitySet</span> <span class="na">Name=</span><span class="s">&quot;Packages&quot;</span> <span class="na">EntityType=</span><span class="s">&quot;NuGetGallery.V2FeedPackage&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;FunctionImport</span> <span class="na">Name=</span><span class="s">&quot;Search&quot;</span> <span class="na">EntitySet=</span><span class="s">&quot;Packages&quot;</span> <span class="na">ReturnType=</span><span class="s">&quot;Collection(NuGetGallery.V2FeedPackage)&quot;</span> <span class="na">m:HttpMethod=</span><span class="s">&quot;GET&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>          <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span class="s">&quot;searchTerm&quot;</span> <span class="na">Type=</span><span class="s">&quot;Edm.String&quot;</span> <span class="na">Mode=</span><span class="s">&quot;In&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>          <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span class="s">&quot;includePrerelease&quot;</span> <span class="na">Type=</span><span class="s">&quot;Edm.Boolean&quot;</span> <span class="na">Mode=</span><span class="s">&quot;In&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;/FunctionImport&gt;</span>
</span><span class='line'>        <span class="nt">&lt;FunctionImport</span> <span class="na">Name=</span><span class="s">&quot;FindPackagesById&quot;</span> <span class="na">EntitySet=</span><span class="s">&quot;Packages&quot;</span> <span class="na">ReturnType=</span><span class="s">&quot;Collection(NuGetGallery.V2FeedPackage)&quot;</span> <span class="na">m:HttpMethod=</span><span class="s">&quot;GET&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>          <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span class="s">&quot;id&quot;</span> <span class="na">Type=</span><span class="s">&quot;Edm.String&quot;</span> <span class="na">Mode=</span><span class="s">&quot;In&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;/FunctionImport&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/EntityContainer&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/Schema&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/edmx:DataServices&gt;</span>
</span><span class='line'><span class="nt">&lt;/edmx:Edmx&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This xml vomit says that in addition to the hard-coded, out-of-band RPC API that is OData, you
can also invoke the Search and FindPackagesById functions, how to invoke them
and what parameters they take.</p>

<p>At some point the NuGet developers must have gotten sick of using WCF Data Services, because the endpoints for
uploading a package, deleting a package, and the tab completion endpoints all are implemented
without integration with WCF Data Services. That means that these operations are not discoverable
by a client, so if the client wants to invoke them it has to know their locations.</p>

<h2>The Evolution of a Public API</h2>

<p>When the client has no way of discovering available resources, that means the server can never
change the namespace of those resources, or risk breaking older clients.</p>

<p>SalesForce has at least 26 namespaced versions of some services which causes some problems
that @kellabyte discusses on a <a href="https://twitter.com/kellabyte/status/276661580257701889">twitter thread</a>.</p>

<p>NuGet in its current form uses /api/v2 for most HTTP API calls, and has managed to stay on v2 for a while
now. We&#8217;ve seen some new features get added without forcing everyone to move over to v3 yet.
The v1/v2 crutch should never have been introduced, but since it is we&#8217;re stuck with it.</p>

<h2>Dumb Servers and Dumber Clients</h2>

<p>Since the server won&#8217;t tell the client how to invoke certain operations, the client
must make assumptions and NuGet does exactly this. Badly.</p>

<p>The tab completion endpoints are predictably dumb. If you deploy a NuGet feed at
http://example.com/ and point Visual Studio to it, the PowerShell console will
try to go to http://example.com/api/v2/package-ids. If you deploy the same feed at
http://example.com/nuget, and point Visual Studio to that, the PowerShell console will
still try to go to http://example.com/api/v2/package-ids. Note how the /nuget/ part of
the namespace vanished. This will generally result in a 404.</p>

<p>Try to push or delete a package and things get more confusing. If you do
&#8220;nuget push Foo.nupkg -source http://example.com/&#8221;, instead of blindly appending
api/v2 to the URI, the client first does a GET request on the root URI.
If that GET request results in a 301/302 Redirect, the client will follow the redirect
and use that location to push the package. However, if the root URI returns some other
response code, the client reverts to dumbly hard-coding the path to api/v2/package.</p>

<p>But if you push to a URI that is not the root URI, the client listens to you
and pushes to whatever URI you told it.</p>

<p>What all of this means is that it is surprisingly hard to write a web application
that complies with all the weird shit that the NuGet client does. If you tell
Visual Studio that the package feed is at http://example.com/api/v2, then NuGet will
push to http://example.com/api/v2. But if you tell NuGet to publish to
http://example.com/ then it will publish to http://example.com/api/v2/package.</p>

<p>That means you need redundant routes to catch both cases.</p>

<h2>Example Routes</h2>

<p>For my application, here are the routes I came up with that seem to keep
the NuGet client happy, as long as you don&#8217;t deploy it as a child application:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">MapApiRoutes</span><span class="p">(</span><span class="n">HttpRouteCollection</span> <span class="n">routes</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="c1">// Serves up HTML to browsers that accept text/html</span>
</span><span class='line'>    <span class="n">routes</span><span class="p">.</span><span class="n">MapHttpRoute</span><span class="p">(</span><span class="n">RouteNames</span><span class="p">.</span><span class="n">Home</span><span class="p">,</span>
</span><span class='line'>                        <span class="s">&quot;&quot;</span><span class="p">,</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span> <span class="n">controller</span> <span class="p">=</span> <span class="s">&quot;Home&quot;</span> <span class="p">},</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span> <span class="n">acceptHeader</span> <span class="p">=</span> <span class="k">new</span> <span class="n">AcceptHtmlConstraint</span><span class="p">()</span> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">routes</span><span class="p">.</span><span class="n">MapHttpRoute</span><span class="p">(</span><span class="n">RouteNames</span><span class="p">.</span><span class="n">PackageDownload</span><span class="p">,</span>
</span><span class='line'>                        <span class="s">&quot;api/v2/package/{id}/{version}/content&quot;</span><span class="p">,</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span> <span class="n">controller</span> <span class="p">=</span> <span class="s">&quot;Packages&quot;</span><span class="p">,</span> <span class="n">action</span> <span class="p">=</span> <span class="s">&quot;DownloadPackage&quot;</span> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">routes</span><span class="p">.</span><span class="n">MapHttpRoute</span><span class="p">(</span><span class="n">RouteNames</span><span class="p">.</span><span class="n">PackageInfo</span><span class="p">,</span>
</span><span class='line'>                        <span class="s">&quot;api/v2/package/{id}/{version}&quot;</span><span class="p">,</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span><span class="n">controller</span> <span class="p">=</span> <span class="s">&quot;Packages&quot;</span><span class="p">,</span> <span class="n">action</span> <span class="p">=</span> <span class="s">&quot;GetPackageInfo&quot;</span><span class="p">,</span> <span class="n">version</span> <span class="p">=</span> <span class="s">&quot;&quot;</span><span class="p">},</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span> <span class="n">httpMethod</span> <span class="p">=</span> <span class="k">new</span> <span class="n">HttpMethodConstraint</span><span class="p">(</span><span class="n">HttpMethod</span><span class="p">.</span><span class="n">Get</span><span class="p">)</span> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">routes</span><span class="p">.</span><span class="n">MapHttpRoute</span><span class="p">(</span><span class="n">RouteNames</span><span class="p">.</span><span class="n">PackageApi</span><span class="p">,</span>
</span><span class='line'>                        <span class="s">&quot;api/v2/package/{id}/{version}&quot;</span><span class="p">,</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span> <span class="n">controller</span> <span class="p">=</span> <span class="s">&quot;Packages&quot;</span><span class="p">,</span> <span class="n">id</span> <span class="p">=</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">version</span> <span class="p">=</span> <span class="s">&quot;&quot;</span> <span class="p">},</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span> <span class="n">httpMethod</span> <span class="p">=</span> <span class="k">new</span> <span class="n">HttpMethodConstraint</span><span class="p">(</span><span class="n">HttpMethod</span><span class="p">.</span><span class="n">Put</span><span class="p">,</span> <span class="n">HttpMethod</span><span class="p">.</span><span class="n">Post</span><span class="p">,</span> <span class="n">HttpMethod</span><span class="p">.</span><span class="n">Delete</span><span class="p">)</span> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">routes</span><span class="p">.</span><span class="n">MapHttpRoute</span><span class="p">(</span><span class="n">RouteNames</span><span class="p">.</span><span class="n">TabCompletionPackageIds</span><span class="p">,</span>
</span><span class='line'>                        <span class="s">&quot;api/v2/package-ids&quot;</span><span class="p">,</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span> <span class="n">controller</span> <span class="p">=</span> <span class="s">&quot;TabCompletion&quot;</span><span class="p">,</span> <span class="n">action</span> <span class="p">=</span> <span class="s">&quot;GetMatchingPackages&quot;</span><span class="p">,</span> <span class="n">maxResults</span> <span class="p">=</span> <span class="m">30</span><span class="p">,</span> <span class="n">includePrerelease</span> <span class="p">=</span> <span class="k">false</span> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">routes</span><span class="p">.</span><span class="n">MapHttpRoute</span><span class="p">(</span><span class="n">RouteNames</span><span class="p">.</span><span class="n">TabCompletionPackageVersions</span><span class="p">,</span>
</span><span class='line'>                        <span class="s">&quot;api/v2/package-versions/{packageId}&quot;</span><span class="p">,</span>
</span><span class='line'>                        <span class="k">new</span> <span class="p">{</span><span class="n">controller</span> <span class="p">=</span> <span class="s">&quot;TabCompletion&quot;</span><span class="p">,</span> <span class="n">action</span> <span class="p">=</span> <span class="s">&quot;GetPackageVersions&quot;</span><span class="p">,</span> <span class="n">includePrerelease</span> <span class="p">=</span> <span class="k">false</span><span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">MapDataServiceRoutes</span><span class="p">(</span><span class="n">RouteCollection</span> <span class="n">routes</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">var</span> <span class="n">dataServiceHostFactory</span> <span class="p">=</span> <span class="k">new</span> <span class="n">DataServiceHostFactory</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Maps OData to root of application (NOT /api/v2)</span>
</span><span class='line'>    <span class="kt">var</span> <span class="n">serviceRoute</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ServiceRoute</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">dataServiceHostFactory</span><span class="p">,</span> <span class="k">typeof</span><span class="p">(</span><span class="n">PackageDataService</span><span class="p">))</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">Defaults</span> <span class="p">=</span> <span class="n">RouteNames</span><span class="p">.</span><span class="n">PackageFeedRouteValues</span><span class="p">,</span>
</span><span class='line'>            <span class="n">Constraints</span> <span class="p">=</span> <span class="n">RouteNames</span><span class="p">.</span><span class="n">PackageFeedRouteValues</span>
</span><span class='line'>        <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">routes</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">RouteNames</span><span class="p">.</span><span class="n">PackageFeed</span><span class="p">,</span> <span class="n">serviceRoute</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Next</h2>

<p>I would love to see NuGet adopt more RESTful practices with regards to
its HTTP API, but having had one pull request declined already, I&#8217;m not sure
how eager I&#8217;ll be in trying to bring about this change.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Sitting at Your Desk is Killing You]]></title>
    <link href="http://chris.eldredge.io/blog/2013/01/04/sitting-at-your-desk-is-killing-you/"/>
    <updated>2013-01-04T10:44:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2013/01/04/sitting-at-your-desk-is-killing-you</id>
    <content type="html"><![CDATA[<p>Since we&#8217;re starting a new year and health &amp; fitness are on the mind, here&#8217;s how I attempt
to combat the negative affects of the sedentary lifestyle of the professional programmer.</p>

<p>I came across the <a href="http://ergo.human.cornell.edu/">Cornell University Ergonomics Department</a>&#8217;s
research summarization on <a href="http://ergo.human.cornell.edu/CUESitStand.html">Sitting and Standing at Work</a>
a few years ago. The article starts off by describing some scary correlations between
glucose metabolism, heart disease and kidney disease with sitting for prolonged periods of time,
then goes to say that regular aerobic exercise does not seem to counteract some of the negative
affects.</p>

<p>The recommended activity is to take a short, 2 minute break every 20-30 minutes and move around.
The theory is that taking a short walk or doing other light exercise increases circulation and
encourages the metabolism to burn blood sugar instead of storing it as fat.</p>

<h2>Workrave</h2>

<p>Since I work in a c#/.net shop, my workstation is a Windows PC, so I found a program called
<a href="http://www.workrave.org/">Workrave</a>. It also runs on Linux, but if you&#8217;re a Mac user there
are programs that do similar things too.</p>

<p>Workrave is designed primarily to prevent a different ailment: Repetitive Strain Injury (RSI).
To that end, the program aims to remind the user to take &#8220;micro breaks&#8221; every 10-15 minutes
to let the wrists and fingers rest or give them a nice stretch. Workrave also has an optional
daily limit feature that will tell you when you&#8217;ve been at the keyboard for too many hours
in a day, and politely ask you to drop what you&#8217;re doing until tomorrow.</p>

<p>Personally, I haven&#8217;t had much trouble with wrist pain, so I don&#8217;t use the micro-break and
daily limit features. But Workrave also has a &#8220;Rest break&#8221; timer that you can customize to
remind you to take a break.</p>

<p>For my purposes, Workrave is really just a glorified countdown timer, but it has a pretty
friendly notification system that gets your attention but doesn&#8217;t completely interrupt
your work when the time comes due. It also has a nice option to postpone or skip a rest
break when it comes due.</p>

<p>One important caveat about Workrave: since it was created to prevent RSI, the program
only runs the timer by default when it detects keyboard and mouse activity. So if you
spend lots of time reading code, browsing, reading e-mail and the like, Workrave will
go significantly longer than the time limit you set before asking you to take a break.
This is easily fixed however by enabling the &#8220;Reading mode&#8221; option, which causes the
timer to run continuously regardless of whether you are reading or typing and mousing.</p>

<p>Workrave also has built-in suggested exercises you can try during breaks that help
relax your eyes, stretch the neck and things like that. These are pretty useful, but
it&#8217;s paramount to get out of the chair and get your blood flowing. I largely ignore
the built in exercises and just go for a short walk.</p>

<h2>Breaks</h2>

<p>The trouble you inevitably run into is that getting little reminders to take breaks
can be distracting. Programmers, like anybody else, are most productive when they
achieve that state of mind known as <a href="http://en.wikipedia.org/wiki/Flow_(psychology)">flow</a>,
where attention to the task at hand is so focused that even the passing of time
fades away. The notification UI is subtle enough that I find I can often postpone
a rest break without losing much focus, but the trouble is that the whole point
is to get up and move away from the computer at least every 30 minutes.</p>

<p>When I really get into the zone, I still struggle sometimes with tearing myself
away, and I end up hitting postpone repeatedly. But whenever I do take a break
I find that I can come back and settle back into my work quickly without having to
warm up again. Plenty has been written about the negative affects of
&#8220;context switching&#8221; between various tasks, but taking a short break actually
lets you keep noodling on the same task while you take a brief walk around.
Sometimes taking your eyes off the code lets you think about a problem from
a different angle. I&#8217;ve actually found it beneficial to take these breaks
while debugging or troubleshooting a tough problem that I&#8217;ve been stuck on.</p>

<h2>Conclusion</h2>

<p>Sitting all day is bad for you. Working out after work doesn&#8217;t change that.
Twice an hour, get up and move around. It&#8217;s good for your health and productivity.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RavenDB NuGet Review]]></title>
    <link href="http://chris.eldredge.io/blog/2012/09/21/ravendb-nuget-review/"/>
    <updated>2012-09-21T15:25:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2012/09/21/ravendb-nuget-review</id>
    <content type="html"><![CDATA[<p><a href="http://ayende.com/blog">Ayende</a> has been doing a series of posts about how simple and fast RavenDB is, using NuGet
as an example and pointing out some <a href="http://blog.nuget.org/20120824/nuget-feed-performance-update.html">complex, poorly performing queries</a>
that have been bogging down nuget.org recently.</p>

<p>Series 1</p>

<ol>
<li><a href="http://ayende.com/blog/158145/nuget-perf-problems-part-i">NuGet Perf Problems, part I</a></li>
<li><a href="http://ayende.com/blog/158177/nuget-perf-problem-part-iindash-importing-to-ravendb">Nuget Perf Problem, Part II-Importing To RavenDB</a></li>
<li><a href="http://ayende.com/blog/158209/nuget-perf-part-iiindash-displaying-the-packages-page">NuGet Perf, Part III-Displaying the Packages page</a></li>
<li><a href="http://ayende.com/blog/158210/nuget-perf-part-ivndash-modeling-the-packages">NuGet Perf, Part IV-Modeling the packages</a></li>
<li><a href="http://ayende.com/blog/158211/nugget-perf-part-vndash-searching-packages">NugGet Perf, Part V-Searching Packages</a></li>
<li><a href="http://ayende.com/blog/158241/nuget-perf-part-vi-aka-how-to-be-the-most-popular-dev-around">NuGet Perf, Part VI AKA how to be the most popular dev around</a></li>
<li><a href="http://ayende.com/blog/158242/nuget-perf-part-vii-aka-getting-results-is-only-half-the-work">NuGet Perf, Part VII AKA getting results is only half the work</a></li>
<li><a href="http://ayende.com/blog/158465/nuget-perf-part-viii-correcting-a-mistake-and-doing-aggregations">NuGet Perf, Part VIII: Correcting a mistake and doing aggregations</a></li>
</ol>


<p>Series 2</p>

<ol>
<li><a href="http://ayende.com/blog/158529/nuget-perf-the-final-part-ndash-load-testing-ndash-setup">NuGet Perf, The Final Part - Load Testing - Setup</a></li>
<li><a href="http://ayende.com/blog/158530/nuget-perf-the-final-part-ndash-load-testing-ndash-the-tests">NuGet Perf, The Final Part - Load Testing - The Tests</a></li>
<li><a href="http://ayende.com/blog/158561/nuget-perf-the-final-part-ndash-loading-testing-ndash-results">NuGet Perf, The Final Part - Load Testing - The Results</a></li>
<li><a href="http://ayende.com/blog/158593/nuget-perf-the-final-part-ndash-load-testing-ndash-results-2">NuGet Perf, The Final Part - Load Testing - Results ^ 2</a></li>
<li><a href="http://ayende.com/blog/158625/nuget-perf-the-final-part-ndash-load-testing-ndash-source-code">NuGet Perf, The Final Part - Load Testing - Source Code</a></li>
</ol>


<p>This series piqued my interest given that I&#8217;ve been working on Lucene.Net.Linq and integrating it with NuGet.Server. I haven&#8217;t worked
directly with RavenDB, but I have used some products like Octopus Deploy which uses RavenDB. It seems like a pretty cool product and
I don&#8217;t have anything against it. However, there are some problems with the blog series that might lead the casual reader
to be misled about what has been accomplished, especially with regards to declarations of victory and some misleading
performance numbers.</p>

<p>I know the blog series is only meant to show off RavenDB and give potential users an idea of what their code might look like,
but nonetheless some hefty claims are made about performance in comparison to the Entity Framework / SQL Server solution in
use at <a href="http://nuget.org/">nuget.org</a>. Let&#8217;s take a look.</p>

<h2>Pick a Schema, Any Schema Will Do</h2>

<p>Of course if you&#8217;re going to model data in a new persistence layer, it makes perfect sense to simplify or improve the
way your data is stored and indexed for later retrieval. Ayende points out some problems with the dense, non-semantic
way some fields are stored in nuget, such as dependency versions and tags. He uses these as examples that illustrate
how RavenDB can handle nested collections of strings and complex objects.</p>

<p>That&#8217;s great and all, but if we&#8217;re redesigning the schema, we&#8217;ve already changed the rules. Nuget.org is having some
trouble specifically because of a poorly designed schema that requires too many joins and some other complex hoop-jumping
to execute some frequently used queries.</p>

<p>Furthermore, regardless of how the data is stored behind the server, NuGet uses an OData API to expose its packages
to clients. If you change the schema, you have to do it in a way that remains compatible with that client API, or
the millions of installed instances suddenly stop working.</p>

<h2>Semantic Version Sort vs. Lexical Sort</h2>

<p>One of the primary ways that packages are sorted in NuGet is by version. Unfortunately, the complex nature of
semantic versions, such as 0.9-alpha or 1.0.5, makes it impossible to sort them correctly using a basic lexical sort.
For example, 1.0-alpha should get sorted before 1.0, and 1.2 should get sorted before 1.10. With lexical sort
they do not.</p>

<p>This problem was pointed out in a comment on <a href="http://ayende.com/blog/158210/nuget-perf-part-ivndash-modeling-the-packages">Part IV</a>
but left unresolved.</p>

<h2>Review</h2>

<p>In using NuGet as an example for RavenDB, the following features are not addressed:</p>

<ol>
<li>Providing a backwards-compatible OData endpoint</li>
<li>Sorting correctly by package version</li>
<li>Storing and retrieving package contents (only package metadata is addressed)</li>
<li>Adding new packages into the index</li>
<li>Keeping track of download counters (per-package and total)</li>
</ol>


<p>Without addressing adding new packages and tracking downloads, the data store is effectively read-only,
meaning that caches never get invalidated and there are no writes to disk. Based on this criteria, is
it really fair to compare performance benchmarks between this sample and a real, production system?</p>

<h2>The Load Tests</h2>

<p>In the next part of the series, the sample system is put under some load to see what kind of performance
RavenDB can provide when there are concurrent users. <a href="http://ayende.com/blog/158530/nuget-perf-the-final-part-ndash-load-testing-ndash-the-tests">The Tests</a>
goes into some detail about the load testing plan.</p>

<p>Reviewing the load test, we have another obvious problem: only a handful of sample queries are being used.
When the number of search queries is low, say, under 10, the system under load can simply cache the results
from the previous time the query was executed and return that to the user. Since there isn&#8217;t any variance
in which columns are used to sort, what page is retrieved, etc., the system under load doesn&#8217;t have to think
very hard at all.</p>

<p>Combine the simplicity of the test plan with the fact that the system under test is not doing any writes at all,
and you might as well be slinging static html at that point. I guess it does validate, if nothing else, that
the caching built into RavenDB works.</p>

<p>One indicator that the load test isn&#8217;t really hitting any critical thresholds is that Pages/Sec grows pretty
linearly as User Load ramps up. If the system hit such a threshold, one would expect Pages/Sec to peak at
a certain rate and (ideally) sustain that rate as concurrency continues to grow.</p>

<h2>Summary</h2>

<p>To reiterate, I&#8217;m not trying to bash RavenDB, which I&#8217;m sure is an awesome product and probably really would
perform very effectively under load similar to that experienced by <a href="http://nuget.org/">nuget.org</a>. However,
casual observers may come away with unrealistic expectations after reading the performance results offered
up on <a href="http://ayende.com">ayende.com</a>.</p>

<h2>Why Do I Care</h2>

<p>If Ayende had picked virtually any example other than NuGet packages to do a blog series on, I probably would have
read along and not thought much about any of it. But having worked on NuGet.Server + Lucene.Net.Linq for
several months earlier this year, the subject matter is near and dear to my heart.</p>

<p>In future posts I&#8217;ll get into some more compare and contrast on RavenDB vs. <a href="https://github.com/themotleyfool/Lucene.Net.Linq">Lucene.Net.Linq</a>
and maybe do a load test of my own of our <a href="https://github.com/themotleyfool/NuGet/downloads">custom NuGet.Server builds</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How The Motley Fool Uses Octopus Deploy]]></title>
    <link href="http://chris.eldredge.io/blog/2012/09/06/how-the-motley-fool-uses-octopus-deploy/"/>
    <updated>2012-09-06T11:23:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2012/09/06/how-the-motley-fool-uses-octopus-deploy</id>
    <content type="html"><![CDATA[<p>I&#8217;ve mentioned a few times that my team has been using <a href="http://octopusdeploy.com/">Octopus Deploy</a> in a few of my posts.
Now I&#8217;ll describe in more detail some of the ways we&#8217;ve integrated with Octopus that may help others.</p>

<h2>The Before Times</h2>

<p>Octopus started a beta phase in late 2011, so what were we doing before? Since I started working in an asp.net shop
in 2006, I&#8217;ve been surprised by the lack of robust deployment tools for the ecosystem.</p>

<p>The Web Deployment Projects system provided by Microsoft has always seemed like a non-starter for me. When you
have mature processes like version control, continuous integration, automated testing, and quality assurance,
how does it make sense to hand the keys over to a developer running Visual Studio to click &#8220;Deploy&#8221;
on their desktop? What guarantee do you have that the code has been checked in, that it builds, that
the tests pass, that QA signed off?</p>

<p>Even if you only give trusted users permission to deploy, I&#8217;ve never understood how it makes sense that you
would need Visual Studio to deploy your projects. I mean, Visual Studio is for development. It isn&#8217;t even
needed by a build server to compile your code. But now QA (or whoever is allowed to perform deployments) needs
to have Visual Studio installed somewhere and checkout the code and build it themselves? So much for automation.
So much for predictability. So much for repeatability.</p>

<p>So it was with a lack of viable alternatives that I started writing a deployment tool in 2007. The tool was
named Bazooka (because it &#8220;shoots&#8221; software onto servers), and we used it for 5 years. We never released it as
open source because it made several assumptions particular to us and we didn&#8217;t take the time to clean it up.</p>

<p>Bazooka was a web application that watched a directory for release candidates to show up as they were
prepared by our build server. Each release candidate contained a deployment descriptor that had some
meta data and a list of components that could be deployed to servers that matched certain roles like
WebServer or AppServer.</p>

<p>Bazooka used xml configuration for everything. The deployment descriptor was xml, the server and environment
configuration was xml, the permissions were xml, and the log files that recorded what had been deployed where
were also xml. This made Bazooka pretty slow as deployment logs piled up, but it beat the heck out of
doing anything more heavy-weight with sql.</p>

<p>Bazooka was, in reality, just a web interface to MSBuild. When you went through the deployment wizard,
Bazooka simply executed MSBuild in the directory specified by each component with some properties saying
which server to deploy to, which target to execute, what the environment was, etc.</p>

<p>We could have easily kept improving Bazooka, but we had actual code to write for our business, so Bazooka
had some weaknesses that we never really addressed. For example, managing servers and environments was
done by hand-editing the xml files. We didn&#8217;t build a UI for that. Also, it was pretty tough to answer
simple questions like, &#8220;What was the most recent deployment of my project to the staging environment?&#8221;</p>

<p>But it worked as a fine stand-in for 5 years until someone built something better.</p>

<h2>Octopus Trial</h2>

<p>It was fun playing with Octopus during the beta period and seeing another approach to a web based
deployment tool. In the beginning there were plenty of things Bazooka had that Octopus didn&#8217;t (yet),
but development has been pretty rapid with Octopus delivering frequent releases.</p>

<p>The one time where we asked if using Octopus was right was when Paul Stovell, the creator/developer
of Octopus Deploy, took a few months to rewrite the persistence layer, converting it from Entity
Framework to RavenDB. It was the right decision to make and we&#8217;re happy in the long run, but we
found ourselves in a lurch waiting for some important features and bugfixes. We came out fine on
the other side though.</p>

<p>We also found that using a local file-based NuGet feed with Octopus doesn&#8217;t scale very well, and
switching to NuGet Server provided no benefit either. This inspired us to create a
<a href="https://github.com/themotleyfool/NuGet">custom fork</a> of NuGet Server that uses
<a href="http://incubator.apache.org/lucene.net/">Lucene.Net</a> and
<a href="https://github.com/themotleyfool/Lucene.Net.Linq">Lucene.Net.Linq</a> to provide a scalable, lightning fast internal feed for Octopus.</p>

<h2>The Switch</h2>

<p>As we integrated some pilot projects with Octopus, we slowly stopped using Bazooka and
eventually turned off Bazooka integration. Some quick stats of our Octopus configuration today:</p>

<ul>
<li>48 projects</li>
<li>18,080 release candidates</li>
<li>1,405 deployments</li>
</ul>


<p>Octopus has done a decent job managing our high demands. We have experienced some slow page
loads here and there, but Paul has been very responsive about troubleshooting and optimizing
these.</p>

<h2>Reusing Deployment Scripts</h2>

<p>Since we already had a highly automated deployment system, we wanted to preserve our exising
capabilities while finding ways to improve the system.</p>

<p>One problem that Octopus doesn&#8217;t solve for you is how to share deployment scripts across
projects. By default, Octopus will execute deployment scripts contained in each project,
but there isn&#8217;t a built-in or standard way to reuse common functionality.</p>

<p>One of the first projects we set up in Octopus we named OctopusScripts. This project
consists of a collection of PowerShell modules that we want to be available everywhere.
When we deploy the project, the deployment scripts install the modules into a
standard location where PowerShell will probe for them. Then from other projects,
we can simply start a script with:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Import-Module SmokeTest</span></code></pre></td></tr></table></div></figure>


<h2>Reuse Moar</h2>

<p>Moving most of our scripts into PowerShell modules was working great, but we started
to notice that our Deploy.ps1 scripts still looked awfully repetitious.</p>

<p>All of our web projects follow the same basic deployment recipe:</p>

<ol>
<li>PreDeploy

<ol>
<li>Disable machine in load balancer</li>
<li>Create IIS site and app pool definitions if missing</li>
<li>Update site host-header bindings as needed</li>
</ol>
</li>
<li>Let Octopus update the document root to point to the new application</li>
<li>PostDeploy

<ol>
<li>Execute smoke tests against the server and abort if any URLs return a non-200 response</li>
<li>Enable machine in load balancer</li>
</ol>
</li>
</ol>


<p>Of course we have different configurations and different URLs to use for smoke tests
for each project. We ended up creating a configuration based, modular script collection
so that each project simply needs to include a stub:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Import-Module Fool-Octopus
</span><span class='line'>Invoke-OctopusDeploymentTasks</span></code></pre></td></tr></table></div></figure>


<p>The Invoke-OctopusDeploymentTasks function looks at whatever variable and configuration
are present and figure out which steps to execute. The same scripts are used for Windows
Service type projects and others too, and they figure out based on conventions if they
need to run web steps, create services, etc.</p>

<p>If the stub is missing from a project (because why duplicate the stub?) our build scripts
automatically insert a stub Deploy.ps1, PreDeploy.ps1 and PostDeploy.ps1.</p>

<p>We think we&#8217;re about as DRY as we can get with regards to our deployment scripts.</p>

<h2>Ad-hoc PowerShell</h2>

<p>One thing we&#8217;d like to see that hasn&#8217;t made it into Octopus yet is the concept of ad-hoc
powershell scripts. Basically, we want to be able to run some arbitrary scripts during a
deployment, only once. It doesn&#8217;t need to run once on each machine being deployed to, just
once and then done. There&#8217;s a <a href="https://trello.com/card/new-deployment-step-ad-hoc-powershell/4e907de70880ba000079b75c/8">story card</a>
on Paul&#8217;s Trello board that we&#8217;re looking forward to. In the mean time, we&#8217;ve been emulating
this behavior by deploying a small package to a dummy server and letting the script run there.</p>

<p>We mostly want this feature to simplify tasks such as sending email/other notifications when
deployments are beginning or completed. It might also be useful for a green/blue style
deployment model where the load balancer needs to toggle just once after the servers
have been updated.</p>

<p>Without the Ad-hoc feature, one of the stumbling points we run into is sometimes forgetting
to check the &#8220;Force redeployment&#8221; checkbox that Octopus leaves unchecked. When we forget,
some steps get skipped leading to confusing results.</p>

<h2>Looking Ahead</h2>

<p>Because of the level of automation we integrated with Octopus, our business is able to
deploy software more frequently and more reliably than ever before. In the coming
months and years, we look forward to seeing improvements in Octopus features that will
help us with cloud deployments to AWS or Azure. Octopus has definitely filled a gap
in our deployment capabilities, allowing us to deliver value to our business quickly,
iteratively and predictably.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How The Motley Fool Uses NuGet (Part 2)]]></title>
    <link href="http://chris.eldredge.io/blog/2012/08/20/how-the-motley-fool-uses-nuget-part-2/"/>
    <updated>2012-08-20T13:56:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2012/08/20/how-the-motley-fool-uses-nuget-part-2</id>
    <content type="html"><![CDATA[<p><a href="http://chris.eldredge.io/blog/2012/08/07/how-the-motley-fool-uses-nuget/">Last time</a>
I talked about how my development team progressed from having all
of our .net code in a single repository with a single solution to using a more
modular architecture complete with encapsulated domains.</p>

<p>When we started using this appraoch, we were still limited in a few ways:</p>

<ul>
<li>Everyone needs to integrate with the newest code</li>
<li>Difficult to patch an old version of a dependency</li>
<li>Cascading failures on the build server</li>
</ul>


<p>Even though we broke the ProjectReference rats nest, we still had an
implicit dependency on various shared code. It all had to be checked out
and built in the right order.</p>

<h2>Binary Package Management</h2>

<p>The next logical step was to further decouple our shared code by
packaging it up and publishing those packages. If we could do that,
we could decide when to upgrade dependencies on a product by product
basis.</p>

<p>There are two package managers in the .net ecosystem: OpenWrap and NuGet.</p>

<p>When we started shopping around, OpenWrap had been around longer and seemed
to be a better choice. There&#8217;s a <a href="http://stackoverflow.com/questions/4256994/openwrap-vs-nuget">comparison of the products</a>
on stackoverflow.</p>

<p>We worked with OpenWrap for over 6 months and during that time started
to find some problems around integration with Visual Studio and ReSharper.
OpenWrap wants to manage dependencies per solution, and we have many cases
where we want to control dependencies at a per project level. We also
started to notice that NuGet was getting new versions released on a fairly
regular schedule, while OpenWrap 2.0 was in unstable beta limbo for over
a year.</p>

<p>Around the same time we started playing with <a href="http://octopusdeploy.com/">Octopus Deploy</a>
for deploying our code. Since Octopus uses NuGet packages for deployment, we
figured it would make sense to standardize on one package management system
for both deployments and dependency management. It&#8217;s true that those are
separate problem spaces, but having less build scripts is always a good thing.</p>

<h2>Thoughts on NuGet</h2>

<h3>Conventions</h3>

<p>NuGet has several conventions that make it easy to create simple packages
that others can reference. You can share assemblies and content easily,
and when you want to customize anything there are some powershell extension
points you can hook into.</p>

<p>One problem we run into is that when building packages, sometimes there&#8217;s
a NuGet convention we want to customize or suppress, and often we can&#8217;t.</p>

<p>For example, if you create a <code>nuspec</code> and place it adjacent to a <code>csproj</code>
file, NuGet will look at the project and automatically inject metadata
and content into the package. For some things, you can override this
behavior with explicit specifications in the nuspec, but the behavior
can be surprising and confusing.</p>

<h3>Dependency Scoping</h3>

<p>NuGet supports the concept of transitive dependencies&#8230; sort of. If you
install package A, and A depends on package B, NuGet will go find a version
of B and install it while installing A. However, NuGet doesn&#8217;t do any record
keeping to remember that B is a transitive dependency. To your project, A and
B appear simply as direct dependencies.</p>

<p>There may be cases where A depends on B at runtime, but consumers of A
shouldn&#8217;t need to code against B at design time.</p>

<p>There may be other cases where B is an optional dependency for A, and
A can be used without it.</p>

<p>Since NuGet doesn&#8217;t have a concept of scope, it only has one simplistic
approach to dealing with transitive dependencies: treat them just like
direct dependencies.</p>

<h3>Upgrade Behavior</h3>

<p>When you ask NuGet to update a specific package, it will first look for
updates to transitive dependencies that the package depends on. This may
seem obvious or desirable to some, but personally I find it confusing.
You can control this behavior with the <code>-IgnoreDependencies</code> flag in
the Package Management Console, but oddly you don&#8217;t get that option
in the command line <code>nuget.exe</code> or from the Visual Studio GUI Package
Manager.</p>

<h3>Package Feed Performance</h3>

<p>We use continuous integration, and every successful build produces
&#8220;release candidate&#8221; versions of packages. We generate 50 to 100 packages
a day.</p>

<p>Using the simple NuGet UNC share quickly failed to scale, so next we tried
NuGet.Server and found that it doesn&#8217;t perform well either.</p>

<p>NuGet Gallery seemed like overkill with its SQL Server requirement, so
I started optimizing NuGet.Server. This project ended up taking quite
a while, but the good news is that the fruits of the labor are now
open source on GitHub at <a href="https://github.com/themotleyfool/NuGet">https://github.com/themotleyfool/NuGet</a>.</p>

<p>For more information about that project, see my <a href="http://chris.eldredge.io/blog/2012/07/03/Speeding-Up-NuGet-Server/">previous post</a>.</p>

<h3>Refactoring Applications and Shared Code</h3>

<p>We try to use <a href="http://semver.org/">Semantic Versioning</a> to communicate
breaking changes in the packages we publish, so sometimes when
we want to use a refactoring tool like Change Method Signature
or Use Base Class it would be nice to have application and shared
code loaded into a single instance of Visual Studio.</p>

<p>We created a tool called <a href="https://github.com/TheMotleyFool/SlimJim">SlimJim</a>
that generates these Solution files on the fly.</p>

<p>If you create a Solution with application code and shared library code,
ReSharper will be smart enough to apply refactoring tools across the projects
even though ProjectReference style references are not being used.</p>

<p>However, Visual Studio won&#8217;t know the correct order to build projects in,
and won&#8217;t automatically copy outputs from shared libraries over to applications.</p>

<p>We extended SlimJim to convert assembly references to project references and back
to address this limitation.</p>

<h2>Conclusion</h2>

<p>In terms of capability and maturity, we&#8217;re in a much better place than
we were a few years ago. However, we still have a ways to go in terms of
productivity and workflow.</p>

<p>NuGet has helped us move in the right direction and we hope to see
further enhancements and even contribute some more of our own as we
develop them.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How The Motley Fool uses NuGet (part 1)]]></title>
    <link href="http://chris.eldredge.io/blog/2012/08/07/how-the-motley-fool-uses-nuget/"/>
    <updated>2012-08-07T14:25:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2012/08/07/how-the-motley-fool-uses-nuget</id>
    <content type="html"><![CDATA[<p>This post describes how we came to using binary package management. In the next part I&#8217;ll get into NuGet.</p>

<p>In the beginning, there was one repository and it held all the projects for The Motley Fool, and it was good.
There were around a dozen asp.net web projects, a smattering of service and console apps, and a bunch of class libraries
to hold shared code. There was one Solution (sln) to rule them all.</p>

<p>As time went on, we found that there are downsides to the one-giant-solution approach to .net development:</p>

<ul>
<li><a href="http://www.laputan.org/mud/">Big Ball of Mud</a></li>
<li>Slow builds</li>
<li>Tight coupling</li>
<li>Configuration hell</li>
<li>Hard to release different applications on different schedules</li>
</ul>


<p>Typically our larger applications would be split into several projects following a typical N-tier layered architecture:</p>

<ul>
<li>Web</li>
<li>Service</li>
<li>Domain</li>
<li>Data Access</li>
</ul>


<p>Despite our attempts to encapsulate data access and domain logic behind the service project, code ended up leaking out
to the point where domain projects were using types and methods from unrelated domain projects. Cats and dogs were
sleeping together.</p>

<p>Around this time Steven Bohlen presented a <a href="http://unhandled-exceptions.com/blog/index.php/2010/11/27/dc-altnet-presentationthats-a-wrap/">talk</a>
to the Washington DC Alt.NET User Group titled &#8220;Domain Driven Design Implementation Patterns in .NET&#8221;. While some of us
were already familiar with concepts of DDD, this talk lit a spark for us to try fixing our big ball of mud.</p>

<p>In late 2010 we started to make some changes. Instead of having one giant repository, shared code would be split out
into separate repositories. We also took this opportunity to introduce a new project organization and architecture.</p>

<p>We established one repository to hold utility code, broken into specific class libraries:</p>

<ul>
<li><tt>Fool.Abstractions</tt> - similar in spirit to System.Web.Abstractions; adds interfaces and wrappers to various FCL types that lack them</li>
<li><tt>Fool.Lang</tt> - similar in spirit to <a href="http://commons.apache.org/lang/">Jakarta Commons Lang</a>; adds general utility classes and methods not found elsewhere</li>
<li>Other projects that extend 3rd party class libraries to make them easier for us to work with in standardized ways.</li>
</ul>


<p>Then we established another repository to hold Domain Driven, er, Domains. For example, many of our applications and web sites deal with
stock market data, so one of our business domains is Quotes. In the Quotes Domain we have these projects:</p>

<ul>
<li><tt>Fool.Quotes</tt> - contains service interfaces and value types; serves as an API to the domain</li>
<li><tt>Fool.Quotes.Core</tt> - contains domain logic, models, and entities; serves as a private implementation</li>
<li><tt>Fool.Quotes.Web.Api</tt> - exposes Fool.Quotes interfaces over a RESTful web API</li>
</ul>


<p>The key to keeping our domains distinct and decoupled is to keep Core projects private. While Core is required at runtime,
it should never be referenced at compile time. To bridge the gap, we use Dependency Injection to provide concrete implementations.</p>

<p>Domains may depend on other domains provided that they consume each other through the API project. That way entities and business logic
are kept focused on their own concerns and don&#8217;t leak out to other problem areas where they don&#8217;t fit.</p>

<h2>Gluing It Together</h2>

<p>Having projects split into different repositories and different solutions meant that we couldn&#8217;t simply have one mega Solution
that includes everything. That&#8217;s by design, so good on us. But this introduces a problem in that we still need to reference code
from our utility projects and DDD projects in our applications. The first solution we came up with to handle this problem was
to use the <a href="http://msdn.microsoft.com/en-us/library/wkze6zky.aspx">AssemblyFolders</a> registry to have our libraries
appear in the <tt>Add Reference</tt> dialog. Then to solve the runtime dependency on our private Core assemblies, we install
those to the GAC so they can be loaded using reflection by our IoC container.</p>

<p>This approach worked fine, mostly. But we encountered some downsides after using it for a while:</p>

<ul>
<li>Need to have all library code checked out and built on each development machine</li>
<li>No built-in way to manage different versions of the same dependency</li>
<li><a href="http://www.sellsbrothers.com/Posts/Details/12503">GAC considered harmful</a></li>
<li>Hard to debug build errors and runtime errors</li>
</ul>


<p>Using Continuous Integration means we&#8217;re producing new builds dozens of times a day, so it isn&#8217;t practical for us to
manage different assembly versions for each build. Like most shops, we leave our assembly versions at 1.0.0.0 despite
injecting actual version information into the AssemblyInformationalVersion attribute.</p>

<p>In order to support parallel development, we needed to find a more flexible way of managing dependencies, and
at this point we started to look at binary package management.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[MSBuild, Visual Studio & NuGet Hackery]]></title>
    <link href="http://chris.eldredge.io/blog/2012/07/26/MSBuild-NuGet-Visual-Studio-Hackery/"/>
    <updated>2012-07-26T00:00:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2012/07/26/MSBuild-NuGet-Visual-Studio-Hackery</id>
    <content type="html"><![CDATA[<p>My team at work recently switched to using NuGet. We have a fair amount of shared code that used to be in a
monolithic code base with all the problems that came with it. Slow builds, no concept of versions, tight coupling, etc.
To address these issues we started migrating to a new layout where we split Framework Projects out into seperate
repositories and publish NuGet packages for those projects. Then our Application Projects use NuGet to depend on
the Framework Projects and we get better control of when dependencies are upgraded, faster builds and everyone is happy.</p>

<p>One drawback to this migration is that we no longer have all projects in one Visual Studio solution, making it hard to
work on writing a new feature or fixing a bug in a Framework Project and testing that change in an Application Project.
Where we used to be able to do this seemlessly, we now have to jump through some hoops:</p>

<ol>
<li>Change Framework Project</li>
<li>Build Framework Project</li>
<li>Manually copy the dll to the Application Project</li>
<li>Change Application Project to use new code (if necessary)</li>
<li>Build Application Project</li>
</ol>


<p>Once the code changes are deemed acceptable, additional work is necessary to commit/push changes to other developers:</p>

<ol>
<li>Commit/Push Framework Project</li>
<li>Wait for build server to publish a NuGet package</li>
<li>Use NuGet to update Framwork project dependency in Application Project</li>
<li>Commit/Push Application Project</li>
</ol>


<p>This multistep process obviously slows down development significantly. My mission is to find a way to cut out some
of these manual steps so our developers can get back to writing and refactoring code instead of wrestling with tools.</p>

<p><strong> SlimJim </strong></p>

<p>A colleague of mine, Aaron Togerson, started a project a while back called SlimJim.
<a href="https://github.com/AaronTorgerson/SlimJim/commits/master">SlimJim</a> is a Visual Studio Solution Generator.
I&#8217;ve always liked the phrase &#8220;Solution Generator&#8221; despite the fact that Visual Studio solution files have
little to do with solving actual problems.</p>

<p>Anyway, SlimJim is a command-line tool that analyzes c# projects and generates a <code>.sln</code> file
that includes a target project (such as a Framework Project) and all projects that depend on it. This
tool enables us to quickly generate Solutions that allow us to have Framework Projects and Application
projects open in a single instance of Visual Studio. Since SlimJim generates these files pretty quickly,
we never check them into source control.</p>

<p>Using SlimJim in conjunction with ReSharper we gain the ability to navigate through the code and apply
refactoring tools to rename types and methods, change method signatures, introduce parameters, and all
the other fun stuff.</p>

<p><strong> The Pitfall </strong></p>

<p>It&#8217;s great that ReSharper knows how to do this, but the problem is when you hit F6 or click Build Solution,
and you get a bunch of compilation errors. What&#8217;s going on? First, NuGet injects assembly references into
the Application Project instead of injecting project references. Visual Studio uses project references to determine
the build order. So because there is no project reference from Application Project pointing to Framework Project,
the order in which the projects are built will be undefined. The second problem is that even if the build order
could be corrected, there is nothing in place that copies the build output from Framework Project over to
where Application Project will find it.</p>

<p>We could solve both problems by converting the c# project files for Application Projects to replace
&lt;Reference/&gt; items with &lt;ProjectReference/&gt; items. This is how Visual Studio decides what
order projects are built in and how outputs from one project get copied to another.</p>

<p>The problem is that we don&#8217;t want to accidentally commit changes like this. We only want them to apply
to local development. Accidentally checking such changes in will certainly break the build and take us
back to the bad old days of slow builds.</p>

<p><strong> Attempt 1 </strong></p>

<p>To avoid changing c# project files, the first approach I took was to try to do some MSBuild magic and
hope Visual Studio would get in on the game. MSBuild provides some hooks that enable us to manipulate
Item Groups dynamically. First, the <a href="http://msdn.microsoft.com/en-us/library/bcxfsh87.aspx">InitialTargets</a>
attribute can be used to execute some targets before the requested targets are executed. Second, we
can do some analysis of the solution file being built and the project references to try to remove
&lt;Reference/&gt; items and add &lt;ProjectReference/&gt; items dynamically.</p>

<p>Note: this example uses tasks from the <a href="https://github.com/loresoft/msbuildtasks">MSBuild Community Tasks</a> project.</p>

<div><script src='https://gist.github.com/chriseldredge/3177148.js?file='></script>
<noscript><pre><code></code></pre></noscript></div>


<p>This implementation works great in MSBuild on the command line when invoked on a c# project.
If you specify a SolutionPath and BuildingInsideVisualStudio,
MSBuild will faithfully build the Framework Projects before building the Application Project.</p>

<p>However, it doesn&#8217;t work in Visual Studio. Evidently when Visual Studio loads a solution, it
either doesn&#8217;t execute InitialTargets or it uses some other mechanism to extract &lt;ProjectReference/&gt;
items from each project.</p>

<p><strong> Attempt 2 </strong></p>

<p>If we can&#8217;t dynamically tell Visual Studio about project references, I thought maybe we could just build
the projects in the right order ourselves. MSBuild already does this when building outside Visual Studio
provided the BuildProjectReferences property is not false.</p>

<p>So I modified my MSBuild script to try to do that:</p>

<div><script src='https://gist.github.com/chriseldredge/3177381.js?file='></script>
<noscript><pre><code></code></pre></noscript></div>


<p>Once again, this works great in MSBuild outside of Visual Studio. When you load up the solution in VS
and hit build, the Output pane says encouraging things like &#8220;MyApp is building C:\Projects\MyFramework\src\MyFramework\MyFramework.csproj&#8221;.</p>

<p>Except it doesn&#8217;t. I couldn&#8217;t figure out why, but somehow Visual Studio seems to know that we&#8217;re trying to trick it, and it refuses
to actually build the project. It pretends to, but it doesn&#8217;t. I thought this might have to do with In-Process Compilers and
other optimizations described in the <a href="http://msdn.microsoft.com/en-us/library/ms171468.aspx">Visual Studio MSBuild Integration</a> article,
but attempting to disable <code>UseHostCompilerIfAvailable</code> has no effect.</p>

<p>I gave up on this strategy becuase even if it helped to build projects in the right order, it doesn&#8217;t copy build outputs from one
project to the other.</p>

<p><strong> Attempt 3 </strong></p>

<p>Once again, Visual Studio proved to be too enterprisey for us to customize. The only proof of concept I was able to make work
was the dumb one: converting c# projects and risking that the converted versions get checked in. We can solve the accidental commit
issue with a pre-commit hook, so maybe it isn&#8217;t all bad as long as we can seemlessly convert back and forth.</p>

<p>Since we already have a tool that analyzes c# project references, it makes sense to extend SlimJim to mangle c# projects while analyzing them.</p>

<p>My <a href="https://github.com/chriseldredge/SlimJim">fork</a> of SlimJim now includes two new switches: <code>--convert</code> and <code>--unconvert</code>.</p>

<p>Suppose SlimJim finds two projects, MyApp and MyFramework, and MyApp.csproj looks like this:</p>

<figure class='code'><figcaption><span>MyApp.csproj</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;Project</span> <span class="na">ToolsVersion=</span><span class="s">&quot;4.0&quot;</span> <span class="na">DefaultTargets=</span><span class="s">&quot;Build&quot;</span> <span class="na">xmlns=</span><span class="s">&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;ItemGroup&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Reference</span> <span class="na">Include=</span><span class="s">&quot;MyFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3c369c070579152a, processorArchitecture=MSIL&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;HintPath&gt;</span>..\packages\MyFramework\lib\net40\MyFramework.dll<span class="nt">&lt;/HintPath&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/Reference&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/ItemGroup&gt;</span>
</span><span class='line'><span class="nt">&lt;/Project&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Using <code>--convert</code>, SlimJim will change MyApp.csproj to look like this:</p>

<figure class='code'><figcaption><span>MyApp.csproj after SlimJim</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;Project</span> <span class="na">ToolsVersion=</span><span class="s">&quot;4.0&quot;</span> <span class="na">DefaultTargets=</span><span class="s">&quot;Build&quot;</span> <span class="na">xmlns=</span><span class="s">&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;ItemGroup&gt;</span>
</span><span class='line'>    <span class="nt">&lt;ProjectReference</span> <span class="na">Include=</span><span class="s">&quot;C:\projects\MyFramework\src\MyFramework\MyFramework.csproj&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Project&gt;</span>{673A97DA-4302-48C9-BFF0-A57FD7DBA93F}<span class="nt">&lt;/Project&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Name&gt;</span>MyFramework<span class="nt">&lt;/Name&gt;</span>
</span><span class='line'>      <span class="nt">&lt;SlimJimReplacedReference&gt;</span>
</span><span class='line'>        <span class="nt">&lt;Reference</span> <span class="na">Include=</span><span class="s">&quot;MyFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3c369c070579152a, processorArchitecture=MSIL&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>          <span class="nt">&lt;HintPath&gt;</span>..\packages\MyFramework\lib\net40\MyFramework.dll<span class="nt">&lt;/HintPath&gt;</span>
</span><span class='line'>        <span class="nt">&lt;/Reference&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/SlimJimReplacedReference&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/ProjectReference&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/ItemGroup&gt;</span>
</span><span class='line'><span class="nt">&lt;/Project&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>And using <code>--uncovert</code> will put it back. The original assembly reference is preserved in the markup, moved out of the
way so MSBuild and Visual Studio will ignore it, but making it easy for us to restore it without losing metadata like HintPath
and SpecificVersion.</p>

<p>As long as we remember to <code>--unconvert</code> before committing, this new feature should provide a great benefit.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Unit of Work & Eventual Consistency]]></title>
    <link href="http://chris.eldredge.io/blog/2012/07/24/Unit-of-Work-and-Eventual-Consistency/"/>
    <updated>2012-07-24T00:00:00+00:00</updated>
    <id>http://chris.eldredge.io/blog/2012/07/24/Unit-of-Work-and-Eventual-Consistency</id>
    <content type="html"><![CDATA[<p><em>Lucene.Net.Linq is available on the NuGet Gallery at <a href="http://nuget.org/packages/Lucene.Net.Linq">http://nuget.org/packages/Lucene.Net.Linq</a>.</em></p>

<p>Recent versions of Lucene.Net.Linq added support for the <a href="http://martinfowler.com/eaaCatalog/unitOfWork.html">Unit of Work</a> pattern.</p>

<p>The standard Unit of Work has methods like <code>registerNew</code> and <code>registerDeleted</code>, but I decided to use more generic
names that make the interface appear more like a simple collection of documents.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">ISession</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IDisposable</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">IQueryable</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">Query</span><span class="p">();</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">Add</span><span class="p">(</span><span class="k">params</span> <span class="n">T</span><span class="p">[]</span> <span class="n">items</span><span class="p">);</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">Delete</span><span class="p">(</span><span class="k">params</span> <span class="n">T</span><span class="p">[]</span> <span class="n">items</span><span class="p">);</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">Delete</span><span class="p">(</span><span class="k">params</span> <span class="n">Query</span><span class="p">[]</span> <span class="n">items</span><span class="p">);</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">DeleteAll</span><span class="p">();</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">Commit</span><span class="p">();</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">Rollback</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>Delete</code> method that takes one or more <code>Query</code> objects is a case special to Lucene.Net. This is an escape hatch
for when you want to delete one or more documents without first retrieving them. For example, you may want to delete all documents that
match a query like <code>type:person</code>. I have mixed feelings about this escape hatch, because it smells like a
<a href="http://c2.com/cgi/wiki?LeakyAbstraction">Leaky Abstraction</a>. On the other hand, since it is an overload to a more abstract method,
I think it makes sense from a performance standpoint.</p>

<p>Anyway, one notable method pair is missing from the interface: <code>registerDirty</code> and <code>registerClean</code>. That&#8217;s because
the session does some book keeping behind the scenes to automatically detect dirty documents when the session is committed.</p>

<p>This makes using Lucene.Net.Linq as a <a href="http://martinfowler.com/eaaCatalog/repository.html">Repository</a> dead simple, and makes the code
look nice and clean in the client:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">ChangeMailingAddress</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="kt">string</span> <span class="n">newAddress</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">var</span> <span class="n">session</span> <span class="p">=</span> <span class="n">provider</span><span class="p">.</span><span class="n">OpenSession</span><span class="p">&lt;</span><span class="n">SampleDocument</span><span class="p">&gt;();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">using</span> <span class="p">(</span><span class="n">session</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>      <span class="kt">var</span> <span class="n">person</span> <span class="p">=</span> <span class="n">session</span><span class="p">.</span><span class="n">Query</span><span class="p">().</span><span class="n">Single</span><span class="p">(</span><span class="n">p</span> <span class="p">=&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">Name</span> <span class="p">==</span> <span class="n">name</span><span class="p">);</span>
</span><span class='line'>      <span class="n">person</span><span class="p">.</span><span class="n">MailingAddress</span> <span class="p">=</span> <span class="n">newAddress</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Document Tracking</h2>

<p>So how does it work?</p>

<p>When you ask for an IQueryable from session, the session attaches an instance of IRetrievedDocumentTracker to the queryable before
returning it. That internal interface has only one method call:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">void</span> <span class="nf">TrackDocument</span><span class="p">(</span><span class="n">T</span> <span class="n">item</span><span class="p">,</span> <span class="n">T</span> <span class="n">hiddenCopy</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>When the LuceneQueryExecutor starts returning results one item at a time, if it detects that a document tracker has been attached,
it makes two copies of each result. One is returned to the client and the other is passed only to the tracker as a hidden copy.
This gives the library the ability to compare pristine objects that came from the index unmodified with ones that may have been
modified with the client.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">for</span> <span class="p">(</span><span class="kt">var</span> <span class="n">i</span> <span class="p">=</span> <span class="n">skipResults</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">hits</span><span class="p">.</span><span class="n">ScoreDocs</span><span class="p">.</span><span class="n">Length</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">var</span> <span class="n">doc</span> <span class="p">=</span> <span class="n">hits</span><span class="p">.</span><span class="n">ScoreDocs</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">doc</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">var</span> <span class="n">score</span> <span class="p">=</span> <span class="n">hits</span><span class="p">.</span><span class="n">ScoreDocs</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">score</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'>  <span class="kt">var</span> <span class="n">item</span> <span class="p">=</span> <span class="n">ConvertDocument</span><span class="p">(</span><span class="n">searcher</span><span class="p">.</span><span class="n">Doc</span><span class="p">(</span><span class="n">doc</span><span class="p">),</span> <span class="n">score</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">tracker</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="kt">var</span> <span class="n">copy</span> <span class="p">=</span> <span class="n">ConvertDocument</span><span class="p">(</span><span class="n">searcher</span><span class="p">.</span><span class="n">Doc</span><span class="p">(</span><span class="n">doc</span><span class="p">),</span> <span class="n">score</span><span class="p">);</span>
</span><span class='line'>      <span class="n">tracker</span><span class="p">.</span><span class="n">TrackDocument</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">copy</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">itemHolder</span><span class="p">.</span><span class="n">Current</span> <span class="p">=</span> <span class="n">item</span><span class="p">;</span>
</span><span class='line'>  <span class="k">yield</span> <span class="k">return</span> <span class="nf">projector</span><span class="p">(</span><span class="n">itemHolder</span><span class="p">.</span><span class="n">Current</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Finally, when the session is committed, all tracked documents are compared with their hidden copies (using reflection) to detect
which documents were modified. Modified documents are written back to the index.</p>

<h2>Eventual Consistency</h2>

<p>The concepts of eventual consitency describe what expectations a client may have about the ordering and visibility of writes in
a distributed asynchronous persistence system. Werner Vogels has written about different
<a href="http://www.allthingsdistributed.com/2008/12/eventually_consistent.html">consistency definitions</a>.</p>

<p>Since the unit of work in Lucene.Net.Linq is implemented by an interface named ISession, it would have been nice to provide
Session Consistency. It&#8217;s open to some interpretation if this behavior is achieved or not. Since the underlying Lucene engine
will not make changes visible to an IndexReader until a commit happens and the IndexReader is reopened, it is difficult or
impossible to allow a client to see the effects of adding, deleting or modifying a document in subsequent queries within the same
session. However, this problem can be side-stepped by simply calling <code>Commit</code> between making changes and subsequent queries.
Calling <code>Commit</code> explicitly may have drawbacks if the client will make further changes and wishes for those changes to
appear atomically. Knowing the details of when staged changes become visible will help clients to make changes smartly.</p>
]]></content>
  </entry>
  
</feed>
