PageRenderTime 120ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/atom.xml

https://github.com/efvincent/efvincent.github.io
XML | 3407 lines | 2953 code | 441 blank | 13 comment | 0 complexity | c1da7adda36d3fc8816553280e9e26fc MD5 | raw file
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <feed xmlns="http://www.w3.org/2005/Atom">
  3. <title><![CDATA[Curried Functions]]></title>
  4. <link href="http://efvincent.github.io/atom.xml" rel="self"/>
  5. <link href="http://efvincent.github.io/"/>
  6. <updated>2014-08-18T13:03:44-04:00</updated>
  7. <id>http://efvincent.github.io/</id>
  8. <author>
  9. <name><![CDATA[Eric F. Vincent]]></name>
  10. </author>
  11. <generator uri="http://octopress.org/">Octopress</generator>
  12. <entry>
  13. <title type="html"><![CDATA[Debounce as a Directive]]></title>
  14. <link href="http://efvincent.github.io/blog/2014/08/18/debounce-as-a-directive/"/>
  15. <updated>2014-08-18T01:28:33-04:00</updated>
  16. <id>http://efvincent.github.io/blog/2014/08/18/debounce-as-a-directive</id>
  17. <content type="html"><![CDATA[<p>Some months ago a co-worker asked if there were a way to buffer the input on a text box
  18. so that the handler would not be called more than every X milliseconds. His app was doing
  19. the fairly typical chore of searching through a long list as the user types into a
  20. search box. Firing a <code>digest</code> (thats Angulars re-bind and re-render loop) for each
  21. keystroke causes a jumpy, jittery refresh storm.</p>
  22. <p>What he was looking for is commonly referred to as to <em>debounce</em> or <em>throttle</em> a
  23. function. There are many implementations around, but his question was specifically
  24. about debounce in the context of Angular, preferably as a directive.</p>
  25. <!-- more -->
  26. <p>I found a snippet authored by <a href="http://tommaitland.net">Tom Maitland</a> that does just
  27. what we need. I tweaked it slightly (also as a <a href="https://gist.github.com/efvincent/9784923">Gist</a>
  28. and <a href="http://jsfiddle.net/efvincent/vkphp2fa/">JSFiddle</a>):</p>
  29. <div><table class="CodeRay"><tr>
  30. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  31. <a href="#n2" name="n2">2</a>
  32. <a href="#n3" name="n3">3</a>
  33. <a href="#n4" name="n4">4</a>
  34. <a href="#n5" name="n5">5</a>
  35. <a href="#n6" name="n6">6</a>
  36. <a href="#n7" name="n7">7</a>
  37. <a href="#n8" name="n8">8</a>
  38. <a href="#n9" name="n9">9</a>
  39. <strong><a href="#n10" name="n10">10</a></strong>
  40. <a href="#n11" name="n11">11</a>
  41. <a href="#n12" name="n12">12</a>
  42. <a href="#n13" name="n13">13</a>
  43. <a href="#n14" name="n14">14</a>
  44. <a href="#n15" name="n15">15</a>
  45. <a href="#n16" name="n16">16</a>
  46. <a href="#n17" name="n17">17</a>
  47. <a href="#n18" name="n18">18</a>
  48. <a href="#n19" name="n19">19</a>
  49. <strong><a href="#n20" name="n20">20</a></strong>
  50. <a href="#n21" name="n21">21</a>
  51. <a href="#n22" name="n22">22</a>
  52. <a href="#n23" name="n23">23</a>
  53. <a href="#n24" name="n24">24</a>
  54. <a href="#n25" name="n25">25</a>
  55. <a href="#n26" name="n26">26</a>
  56. </pre></td>
  57. <td class="code"><pre><span class="comment">// Defines the module as &quot;app&quot;, this is not best practice for module</span>
  58. <span class="comment">// definition or project structure, focus on the directive</span>
  59. angular.module(<span class="string"><span class="delimiter">'</span><span class="content">app</span><span class="delimiter">'</span></span>, []).directive(<span class="string"><span class="delimiter">'</span><span class="content">tlDebounce</span><span class="delimiter">'</span></span>, <span class="keyword">function</span>(<span class="predefined">$timeout</span>) {
  60. <span class="keyword">return</span> {
  61. <span class="key">restrict</span>: <span class="string"><span class="delimiter">'</span><span class="content">A</span><span class="delimiter">'</span></span>,
  62. <span class="key">require</span>: <span class="string"><span class="delimiter">'</span><span class="content">ngModel</span><span class="delimiter">'</span></span>,
  63. <span class="key">priority</span>: <span class="integer">99</span>,
  64. <span class="function">link</span>: <span class="keyword">function</span>(scope, elm, attr, ngModelCtrl) {
  65. <span class="keyword">if</span> (attr.type === <span class="string"><span class="delimiter">'</span><span class="content">radio</span><span class="delimiter">'</span></span> || attr.type === <span class="string"><span class="delimiter">'</span><span class="content">checkbox</span><span class="delimiter">'</span></span>) <span class="keyword">return</span>;
  66. elm.unbind(<span class="string"><span class="delimiter">'</span><span class="content">input</span><span class="delimiter">'</span></span>);
  67. <span class="keyword">var</span> debounce;
  68. elm.bind(<span class="string"><span class="delimiter">'</span><span class="content">input</span><span class="delimiter">'</span></span>, <span class="keyword">function</span>() {
  69. <span class="predefined">$timeout</span>.cancel(debounce);
  70. ngModelCtrl.<span class="predefined">$setViewValue</span>(elm.val());
  71. }, attr.tlDebounce || <span class="integer">1000</span>);
  72. });
  73. elm.bind(<span class="string"><span class="delimiter">'</span><span class="content">blur</span><span class="delimiter">'</span></span>, <span class="keyword">function</span>() {
  74. scope.<span class="predefined">$apply</span>(<span class="keyword">function</span>() {
  75. ngModelCtrl.<span class="predefined">$setViewValue</span>(elm.val());
  76. });
  77. });
  78. }
  79. }
  80. });
  81. </pre></td>
  82. </tr></table>
  83. </div>
  84. <h2 id="examining-the-directive">Examining the directive</h2>
  85. <p>The directive starts at line 3 by defining a module and calling the <code>directive</code> function
  86. which causes Angular to register a directive in that module. This directive is called <code>tlBounce</code>.
  87. To define a directive we pass a function and our function returns a directive definition object.</p>
  88. <h3 id="injecting-angulars-timer-service">Injecting Angulars Timer service</h3>
  89. <p>The debounce directive will use a timer to assure that when attached to a text box, the underlying
  90. model will only be updated every X milliseconds. Well see the algorithm in a bit.</p>
  91. <p>When Angular needs an instance of our directive, it will call the function weve provided. Angular
  92. will inspect the function and detect that it has a dependency; to call the function Angular must
  93. provide, or <em>inject</em> something called <code>$timeout</code>, which is one of Angulars services. Angular offers
  94. many <em>services</em> to you as the application developer to use in creating a directive (or factory,
  95. filter, controller, or the other Angular things). These services are objects or functions provided by the framework.</p>
  96. <p>The tip-off that <code>$timeout</code> is a service is the leading dollar sign. Angular will use its
  97. <a href="https://docs.angularjs.org/api/auto/service/$injector#!">Injector</a> service to find a <code>$timeout</code> and pass it
  98. to us. Well then use the <code>$timeout</code> in our <em>link function</em>.</p>
  99. <h3 id="the-link-function">The link function</h3>
  100. <p>Without getting into the guts of directive development, suffice it to say that in most
  101. cases when writing a directive youll want to focus on the <code>link</code> function. For more information
  102. on the link function, theres the <a href="http://angularjs.org/">Angular Docs</a>, and another good source of information is
  103. <a href="http://www.angularjshub.com/examples/customdirectives/compilelinkfunctions/">AngularJS Hub</a>.</p>
  104. <p>The <code>link</code> function sets up each instance of the directive. You supply the function that can have
  105. up to four parameters. <code>link: function(scope, elm, attr, ngModelCtrl)</code>.</p>
  106. <h4 id="link-function-parameters">Link function parameters</h4>
  107. <p>The first is the directives local scope, which is usually used like you use scope in a controller
  108. to maintain and bind to the internal state of the directive. Well see how <code>scope</code> is used here in a second.</p>
  109. <p>Second is the <code>elm</code> or <em>element</em> parameter. This is the DOM element that the directive to which the
  110. directive is attached. For debounce, the directive is attached to an input, usually a text box. You can do the
  111. usual DOM-stuff to the element, attach event handlers, change content, add children, etc. AAMOF you actually
  112. have an Angular wrapper around the element, so you get some additional JQuery like functions on the element.</p>
  113. <p>Third is <code>attr</code>, the attributes. This is a map of the attributes on the element to which our directive is
  114. attached. In our case, were using the <code>attr</code> to detect if were attached to a radio button or check box; our
  115. deBounce doesnt have a meaning for those controllers, so we bail if we see that were attached to one (line 9).</p>
  116. <p>Lastly is the <code>ngModelCtrl</code>, which is the least intuitive. This is a controller requirement of our directive,
  117. it says that any directive were attached to needs to have an <code>ngModelCtrl</code> controller. This sort of limits
  118. our deBouncer, but the target use case is to put this directive on a text box thats using AngularJSs binding.</p>
  119. <h3 id="debounce-algorithm">DeBounce Algorithm</h3>
  120. <p>The strategy is as follows:</p>
  121. <ol>
  122. <li>Detach the input handler (line 11) that usually updates the model</li>
  123. <li>Bind a new input handler
  124. <ol>
  125. <li>Cancel any pending debounce timer (line 15)</li>
  126. <li>Set up a new debounce timer
  127. <ol>
  128. <li>It should go off in the time specified by the <code>tl-debounce</code> attribute, or 1,000ms if the attribute is
  129. not specified (line 18).</li>
  130. </ol>
  131. </li>
  132. <li>When it goes off, it should tell the model controller <code>ngModelCtrl</code> to set its value <code>.$setViewValue(elm.val())</code></li>
  133. </ol>
  134. </li>
  135. <li>Bind a new blur handler, so when th user leaves the field the model is always updated.
  136. <ol>
  137. <li>Put the call to <code>$setNewValue()</code> inside a <code>scope.apply()</code> so the change causes a digest (Angular rebinds everything).</li>
  138. </ol>
  139. </li>
  140. </ol>
  141. <h3 id="the-digest">The Digest</h3>
  142. <p>One important point - you may be thinking that you could have used the standard JavaScript timer. Why
  143. use Angulars <code>$timer</code> service? Its because Angular needs to know when the model changes so that it
  144. can perform its two way binding / model-view synchronization. By using Angulars timer, you can be assured
  145. that Angular will know when the timer goes off and will do all the right Angular binding stuff at that time.</p>
  146. <h3 id="but-eric-youre-wrong-and-oh-so-stupid">But Eric, youre wrong and oh so stupid!</h3>
  147. <blockquote>
  148. <p>You <strong>could</strong> use the normal timer, because when you call <code>.$setViewValue()</code>
  149. youre letting Angular know something needs to change, right? I mean, it starts in a dollar sign,
  150. so its all Angulary, right? </p>
  151. </blockquote>
  152. <p>Heh. Youd think so, but youd be wrong. This is the kind of thing that makes you scratch your head, then waste
  153. fifteen minutes, then look up the docs, then unleash a stream of profanities. It happens that <code>.$setViewValue()</code> does
  154. <strong>not</strong> cause a digest, probably because of performance or some other really good reason. Doesnt make it fun though, and
  155. its the kind of undiscoverable crap that qualifies as a legit complaint about AngularJS. Take your medicine.</p>
  156. <p>So thats DeBounce - it actually works pretty well for things like text boxes that do searches and stuff like that.
  157. I use it in production, but theres no warrentee so YMMV. Have a good one</p>
  158. <p>-e</p>
  159. ]]></content>
  160. </entry>
  161. <entry>
  162. <title type="html"><![CDATA[GitHubify(Blog)]]></title>
  163. <link href="http://efvincent.github.io/blog/2014/08/15/Octopress-github-ruby-windows/"/>
  164. <updated>2014-08-15T12:00:11-04:00</updated>
  165. <id>http://efvincent.github.io/blog/2014/08/15/Octopress-github-ruby-windows</id>
  166. <content type="html"><![CDATA[<p>For my shiney new blog I decided to go full hipster and host on GitHub. This means that
  167. the entire site, source code as well as the blog website itself, can be seen at
  168. <a href="https://github.com/efvincent/efvincent.github.io">my blogs repository</a>. Of course all of this will be painfully
  169. uncool by this time next year. But for the time being its fun and the tech is relevant.</p>
  170. <p>Dig in if you want to see the ins and outs of setting all this up on a Windows workstation,
  171. because Windows is so far out of fashion stuff is starting to not work on it by default. Karma.
  172. <!--more -->
  173. ## Static Site Generation
  174. The way GitHub hosted web sites work is that the entire web site is pure static HTML,
  175. JavaScript, and CSS. If you work in the industry you realize that all the web site
  176. frameworks (server side) like JSP, ASP.NET, Rails, PHP, etc. all <em>generate</em> pages on
  177. the fly as the requests come in. This requires a server be running somewhere that can
  178. run .NET, Java, Ruby, or whatever.</p>
  179. <p>A static site everything is pre-generated, so any server that can respond to requests
  180. by serving up a file can host a static site. But no one wants to hand craft HTML pages
  181. for every blog post. So what you have is a generator; some kind of program that can take
  182. blog posts written in plain text and <strong>poof!</strong> Generate a static website.</p>
  183. <p>The basic idea is that you have a <em>source</em> directory that has your blog posts written
  184. in (typically) <a href="https://en.wikipedia.org/wiki/Markdown">markdown</a>, CSS, templates for HTML,
  185. and the Ruby / JavaScript / whatever that the generator is written in.</p>
  186. <p>Theres typically a command line interface; so you issue the proper command the
  187. generator takes your markdown and creates a complete, static web site.</p>
  188. <h2 id="github">GitHub</h2>
  189. <p>Thats where <a href="www.github.com">GitHub</a> comes in. If you dont know what GitHub is, or
  190. if youre completely lost at this point, then you probably need to hit up this
  191. <a href="https://www.youtube.com/watch?v=oHg5SJYRHA0">everything you need to know to become a modern developer</a>
  192. tutorial.</p>
  193. <p>Think about it for two seconds, it makes perfect sense. GitHub hosts files in a repository and is a web site.
  194. So if you put a static web sites worth of files <em>in a repository</em>, and GitHub does a tiny bit of magic, it
  195. can serve those web pages up. And thats all a GitHub hosted static site is. You write posts in
  196. markdown, you use a generator to create a static site, and you check it into GitHub.</p>
  197. <h2 id="octopress">OctoPress</h2>
  198. <p>I admittedly dont have a ton of experience with static site generators. I played with
  199. a couple before committing to <a href="www.octopress.org">Octopress</a>. At first I wanted to
  200. use a <a href="http://nodejs.org">Node.js</a> based static site generator. I googled around a bit
  201. and ended up playing with <a href="https://github.com/jnordberg/wintersmith">Wintersmith</a> for
  202. a night. It worked, but GitHub makes it easiest to use a Ruby based generator called <a href="http://jekyllrb.com">Jekyll</a>.
  203. A bit more poking around and I ended up with <a href="www.octopress.org">Octopress</a>, which is
  204. built on top of Jekyll, offers additional features, and incredibly well written, well
  205. documented, and easy to use.</p>
  206. <p>When you go to their site youll get walked through the installation step by step,
  207. and there are some nice Ruby build tools available to get things moving, including
  208. configuring your new Octopress generator to work with GitHub web sites. <strong>Highly recommended</strong></p>
  209. <h2 id="ruby">Ruby</h2>
  210. <p>Ok so <a href="https://www.youtube.com/watch?v=gBkDvqIGSaE">Ruby hates Windows</a>. It might be passive,
  211. but the ill feelings are there. Which is fine, everyone cant love everyone, and Microsoft
  212. has kinda earned it by being a dick until very recently. But whatever, Im not with starting
  213. flame war. It happens that I still use Windows for all kinds of reasons, so I needed to
  214. get Ruby on my workstation.</p>
  215. <p>Actually I had installed Ruby using <a href="http://chocolatey.org/">Chocolately</a> because I
  216. love playing with all the languages, but to run Jekyll youll need the
  217. <a href="http://rubyinstaller.org/downloads/">Ruby Development Kit</a>. The RDK is platform
  218. specific, and is needed to build <em>gems</em> (Ruby packages) that are platform specific,
  219. which Jekyll either is or depends on indirectly (I didnt check).</p>
  220. <p>There are <a href="https://github.com/oneclick/rubyinstaller/wiki/Development-Kit">very clear instructions</a>
  221. that you can follow for getting this set up. Once thats done you can play along with
  222. the <a href="www.octopress.org">Octopress</a> setup instructions, which are great. Just follow the
  223. track that has you deploy to GitHub.</p>
  224. ]]></content>
  225. </entry>
  226. <entry>
  227. <title type="html"><![CDATA[Abandonment Issues]]></title>
  228. <link href="http://efvincent.github.io/blog/2014/08/15/abandonment-issues/"/>
  229. <updated>2014-08-15T11:52:11-04:00</updated>
  230. <id>http://efvincent.github.io/blog/2014/08/15/abandonment-issues</id>
  231. <content type="html"><![CDATA[<p>Ive moved my blog from WordPress on my own personal site to GitHub, because GitHub of course. <em>No One</em> is going
  232. to miss my other blog. It had a couple of what I thought were interesting posts on F# and dependency injection in C#. But its time
  233. for a fresh start.</p>
  234. <p>Expect posts on JavaScript and front end development for a little while. After a career spent designing relational
  235. databases for finance, insurance and other LOB domains, Ive been working on SPA style front end enterprise applications for
  236. a couple of years. And its fun. I may actually have a couple of interesting things to say. Well see.</p>
  237. ]]></content>
  238. </entry>
  239. <entry>
  240. <title type="html"><![CDATA[DI Constructor Injection, Bootstrapping]]></title>
  241. <link href="http://efvincent.github.io/blog/2011/06/24/di-bootstrap/"/>
  242. <updated>2011-06-24T02:07:31-04:00</updated>
  243. <id>http://efvincent.github.io/blog/2011/06/24/di-bootstrap</id>
  244. <content type="html"><![CDATA[<h2 id="constructor-injection">Constructor Injection</h2>
  245. <p>The idea of dependency injection is that classes are defined such that any dependencies on other classes or services, are <em>injected</em> into the class by some external mechanism, as opposed to being newed up directly. The most common form of DI is constructor injection, where a class defines a constructor that has as its parameters the external dependencies required by the class.
  246. <!-- more -->
  247. There are several benefits to this particular method of injection; the most obvious is that in a well designed system the dependencies of a class are clearly visible in the constructor. In the <a href="http://blog.efvincent.com/practical-di-101">DI 101</a> post a data provider was defined like this:</p>
  248. <div><table class="CodeRay"><tr>
  249. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  250. <a href="#n2" name="n2">2</a>
  251. <a href="#n3" name="n3">3</a>
  252. <a href="#n4" name="n4">4</a>
  253. <a href="#n5" name="n5">5</a>
  254. <a href="#n6" name="n6">6</a>
  255. <a href="#n7" name="n7">7</a>
  256. <a href="#n8" name="n8">8</a>
  257. <a href="#n9" name="n9">9</a>
  258. <strong><a href="#n10" name="n10">10</a></strong>
  259. <a href="#n11" name="n11">11</a>
  260. <a href="#n12" name="n12">12</a>
  261. <a href="#n13" name="n13">13</a>
  262. <a href="#n14" name="n14">14</a>
  263. </pre></td>
  264. <td class="code"><pre><span class="directive">public</span> <span class="type">class</span> <span class="class">DevDataProvider</span> : IDataProvider {
  265. <span class="directive">private</span> readonly IIdentService _identService;
  266. <span class="directive">private</span> readonly ILogService _logSvc;
  267. <span class="directive">private</span> <span class="directive">static</span> readonly <span class="predefined-type">List</span>&lt;Employee&gt; EmployeeStore = <span class="keyword">new</span> <span class="predefined-type">List</span>&lt;Employee&gt;();
  268. <span class="directive">public</span> DevDataProvider(IIdentService identService, ILogService logSvc) {
  269. <span class="keyword">if</span> (identService == <span class="predefined-constant">null</span>) <span class="keyword">throw</span> <span class="keyword">new</span> ArgumentNullException(<span class="string"><span class="delimiter">&quot;</span><span class="content">identService</span><span class="delimiter">&quot;</span></span>);
  270. <span class="keyword">if</span> (logSvc == <span class="predefined-constant">null</span>) <span class="keyword">throw</span> <span class="keyword">new</span> ArgumentNullException(<span class="string"><span class="delimiter">&quot;</span><span class="content">logSvc</span><span class="delimiter">&quot;</span></span>);
  271. _identService = identService;
  272. _logSvc = logSvc;
  273. }
  274. <span class="comment">// Remaining implementation omitted for brevity</span>
  275. }
  276. </pre></td>
  277. </tr></table>
  278. </div>
  279. <p>The constructor is on line 6. From this constructor we can see that the DevDataProvider has dependencies on an IIdentityService and an ILogService. There should be no other dependencies in the class other than to well known, stable libraries like the <a href="http://msdn.microsoft.com/en-us/library/hfa3fa08.aspx">BCL</a>.</p>
  280. <p>There are other advantages to using constructor injection. Should the list of dependencies get too long, say longer than four parameters, youve got a code smell that perhaps the class is doing too much, violating the single responsibility principal.</p>
  281. <h2 id="bootstrapping">Bootstrapping</h2>
  282. <p>In order to be able to resolve dependencies, the DI container must be configured. This set up is done during the <strong>bootstrapping</strong> phase. Typically this only needs to be done once, but changes to the container make sense in some scenarios like when a DI container is being used to support extensions or plug-ins. In that case components might be added or removed from the DI container while the app is running. These scenarios are out of scope for this post.</p>
  283. <p>The container may be configured in several ways Auto configuring, configuration in code, and configuration files (typically XML / app or web.config files). My current favorite DI framework is AutoFac, and I typically configure in code, but different projects will have different demands, so familiarize yourself with the specifics of your selected framework and understand the tradeoffs involved in the different types of configuration. You can even configure the DI container using more than one method perhaps Auto configuring for the bulk of the registrations, then code or XML for more specific configuration needs.</p>
  284. <h2 id="bootstrapping-a-console-application">Bootstrapping a Console Application</h2>
  285. <p>Depending on the type of application youre working on, there are specific places for bootstrapping to take place. The <em>place</em> to do configuration and bootstrapping is sometimes referred to as the <strong>composition root</strong> <em>(you can read about these concepts in more detail in <a href="http://www.manning.com/seemann/">Mark Seemans Dependency Injection</a> book, published by Manning)</em>.</p>
  286. <p>In a console application, the static Main() method is a typical place to configure the container. While we rarely write console apps in production (at least I rarely do), the simplicity makes it easy to see the implications of the bootstrapping procedure.</p>
  287. <p>In the following sequence diagram, in step one [1] the Main() entry point is called on the console application. Main() is serving as the composition root. From there a private Bootstrap() methods is called [2] and the DI container is configured. The exact mechanism varies by framework.</p>
  288. <p><a href="http://blog.efvincent.com/wp-content/uploads/2011/06/Capture.png"><img src="http://blog.efvincent.com/wp-content/uploads/2011/06/Capture_thumb.png" alt="Capture" /></a></p>
  289. <p>Once the container is configured, the main entry point requests that the DI container resolve the App type [3]. The DI container creates whatever dependencies are required by the App [4]. This happens hierarchically; dependencies may themselves have dependencies and so on. The DI container sorts all this out and is also responsible for lifetimes of create objects etc. The DI container can create and return the instance off the App [5]. The Main() function can then pass control to the app [6] which will leverage the injected dependencies [7] to do the real work.</p>
  290. <h2 id="only-directly-reference-the-di-container-in-the-bootstrapper">Only Directly Reference the DI Container in the Bootstrapper</h2>
  291. <p>This is an important point, and if you get nothing else from this post, understand this.</p>
  292. <ul>
  293. <li>The DI container is configured in the composition root (Main() in this case)</li>
  294. <li>The DI container is used to resolve or build the App</li>
  295. <li>The app is then run to do the work</li>
  296. </ul>
  297. <p>Once the app is instantiated, it should have all of its dependencies injected. <strong>The app should not have a reference to the DI container!</strong> If we allow the app or any of its dependencies to have access to the container, then several bad things happen:</p>
  298. <h4 id="weve-taken-on-a-dependency-to-the-di-container-itself">Weve taken on a dependency to the DI Container itself</h4>
  299. <p>Yes its true that the assembly has a dependency on the DI container. But for purposes of this discussion the assembly is not the application. The App class and the services (other classes) it depends on is the application. We dont want to take a dependency on the DI container in those classes; rather, we should be able to switch to a different DI container if needed and not effect the App and the dependent services.</p>
  300. <p>In any kind of a significant application the apps classes would be in a different assembly, and services might be scattered across even more assemblies, and those should not have a dependency on a DI container. They should however be designed and built with the DI pattern in mind with the dependencies specified in the constructor, with references to abstract types or interfaces, rather than to concrete implementations.</p>
  301. <h4 id="were-hiding-a-dependency-inside-the-app">Were hiding a dependency inside the App</h4>
  302. <p>Earlier I mentioned that a benefit of constructor injection is that the dependencies are clearly visible (even <em>documented</em> if you will) in the signature of the constructor. We really dont want to see lines like this buried in the methods of the classes:</p>
  303. <div><table class="CodeRay"><tr>
  304. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  305. <a href="#n2" name="n2">2</a>
  306. <a href="#n3" name="n3">3</a>
  307. <a href="#n4" name="n4">4</a>
  308. <a href="#n5" name="n5">5</a>
  309. <a href="#n6" name="n6">6</a>
  310. <a href="#n7" name="n7">7</a>
  311. <a href="#n8" name="n8">8</a>
  312. </pre></td>
  313. <td class="code"><pre><span class="comment">// Anti-pattern - don't use DI container except</span>
  314. <span class="comment">// in composition root</span>
  315. var dal = <span class="predefined-type">Container</span>.Resolve&lt;IDataAccessService&gt;();
  316. <span class="comment">// And defintely don't do this</span>
  317. var dal = <span class="keyword">new</span> SqlDataAccessService(connectString);
  318. </pre></td>
  319. </tr></table>
  320. </div>
  321. <p>A class that that has these lines buried inside somewhere has hidden dependencies on both the DI container and IDataAccessService (or worse, by using the new keyword directly, on the SqlDataAccessService). These hidden dependencies undermine the benefits of using DI containers at all.</p>
  322. <h3 id="bootstrapping-in-other-application-types">Bootstrapping in other Application Types</h3>
  323. <p>Other types of apps have different places for bootstrapping and application roots. Unlike a console app, an ASP.NET MVC 3 application isnt top-down linear, the application must respond to web requests. It does so by creating instances of controllers, and calling methods on those controllers to respond to web requests.</p>
  324. <p>A controller in MVC3 is like the app was in our console example above. It will be resolved, or created, by the DI container. Controllers are different in that there will likely be several different controllers in an MVC application. Also, we dont get to resolve a controller and tell it to run right from the composition root, the ASP.NET MVC framework will be receiving web requests and will need to resolve controllers later, after bootstrapping.</p>
  325. <p>In ASP.NET MVC 3 this is accomplished by providing a <em>hook</em>, or a place where we can supply a DI container for ASP.NET MVC 3 to use when creating controllers. The developer configures the DI container, and then wires that container into the MVC framework via an instance of IControllerActivator. In the case of AutoFac, theres a <a href="http://nuget.org/List/Packages/Autofac.Mvc3">NuGet package called AutoFac.Mvc3</a> that includes classes to integrate with MVC3. The implementation details are beyond the scope of this post just <a href="http://duckduckgo.com/">DuckDuckGo</a> AutoFac.Mvc and find a wealth of additional detail. Same goes for WCF, WPF, and Silverlight applications. There are best practices for configuring DI containers for each app type.</p>
  326. <h3 id="di-unfriendly-application-types">DI Unfriendly Application Types</h3>
  327. <p>Some application types just do not lend themselves very easily to dependency injection patterns. Classic ASP.NET pops into mind immediately. It was written before Microsoft was as willing to accept OSS, community driven concepts such as DI Containers. A big red flag with ASP.NET is that all subclasses to the Page class (which is what all your ASP.NET pages are) must have a parameterless default constructor. Well there goes parameter injection!</p>
  328. <p>There are other mechanisms for implementing DI patterns in this case, but theyre sub-optimal. Again Id refer you to <a href="http://www.manning.com/seemann/">Mark Seemans Dependency Injection</a> book, which is far and away the best DI book in the .NET space, for advice and examples in dealing with DI unfriendly application types.</p>
  329. <h3 id="in-summary">In Summary</h3>
  330. <p>Hopefully this was helpful in your understanding of a couple of key aspects of using DI containers. Practice a few console applications, and write some tests too. Once you get the idea, move on to more interesting application types. Before long youll be shocked you ever wrote applications <em>without</em> some degree of dependency injection. Yea its that good for you.</p>
  331. ]]></content>
  332. </entry>
  333. <entry>
  334. <title type="html"><![CDATA[A Taste of Dependency Injection, Testing, and Mocking]]></title>
  335. <link href="http://efvincent.github.io/blog/2011/05/27/di-mock/"/>
  336. <updated>2011-05-27T20:28:53-04:00</updated>
  337. <id>http://efvincent.github.io/blog/2011/05/27/di-mock</id>
  338. <content type="html"><![CDATA[<p><a href="http://blog.efvincent.com/practical-di-101">My last post</a> provided a brief introduction into dependency injection. To review, the example included a data provider for Employee objects, which included a feature to return the object corresponding to the currently logged in user. In the end the following interfaces were defined:</p>
  339. <p><strong>IDataProvider</strong> the function is obvious from the name. One implementation, the DevDataProvider, uses a static List<employee> as a data store.</employee></p>
  340. <p><strong>IIdentityService</strong> describes a service that supplies the <em>current</em> identity. What current is depends on the implementation of course. A concrete WindowsIdentService defines current as the currently logged in Windows user. The TestIdentService implementation always returned the same username, which is useful for testing as we will see.</p>
  341. <p><strong>ILogService</strong> describes a simple logging service. The ConsoleLogService implementation prints logs to the console.</p>
  342. <!-- more -->
  343. <p>### Dependency Injection &amp;Testing</p>
  344. <p>For this post Ive added a standard MSTest project and a couple of tests for the data provider. The use of dependency injection patterns in the design of this simple example allows us to easily isolate the code under test.</p>
  345. <div><table class="CodeRay"><tr>
  346. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  347. <a href="#n2" name="n2">2</a>
  348. <a href="#n3" name="n3">3</a>
  349. <a href="#n4" name="n4">4</a>
  350. <a href="#n5" name="n5">5</a>
  351. <a href="#n6" name="n6">6</a>
  352. <a href="#n7" name="n7">7</a>
  353. <a href="#n8" name="n8">8</a>
  354. <a href="#n9" name="n9">9</a>
  355. <strong><a href="#n10" name="n10">10</a></strong>
  356. <a href="#n11" name="n11">11</a>
  357. <a href="#n12" name="n12">12</a>
  358. <a href="#n13" name="n13">13</a>
  359. <a href="#n14" name="n14">14</a>
  360. </pre></td>
  361. <td class="code"><pre><span class="directive">static</span> IContainer afContainer;
  362. [ClassInitialize]
  363. <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> TestInit(TestContext ctx) {
  364. var idSvc = A.Fake&lt;IIdentService&gt;();
  365. A.CallTo(() =&gt; idSvc.GetCurrentUserName())
  366. .Returns(<span class="string"><span class="delimiter">&quot;</span><span class="content">FAKE-ID</span><span class="delimiter">&quot;</span></span>);
  367. var bldr = <span class="keyword">new</span> ContainerBuilder();
  368. bldr.RegisterInstance(idSvc);
  369. bldr.RegisterInstance(A.Fake&lt;ILogService&gt;());
  370. bldr.RegisterType&lt;DevDataProvider&gt;().As&lt;IDataProvider&gt;();
  371. afContainer = bldr.Build();
  372. }
  373. </pre></td>
  374. </tr></table>
  375. </div>
  376. <p>The test class has a static DI container instance, initialized in the class initializer. Im using <a href="http://code.google.com/p/fakeiteasy/">FakeItEasy</a> to create a fake IIdentService at line five. Like six tells the FakeItEasy framework what to return when the GetCurrentUserName() method is called on the fake ident service. Having a fixed response makes testing the data provider a piece of cake.</p>
  377. <p>I then register the fake ident service as well as a fake log service. For the log service, we dont need to specify any behavior for the methods. The FakeItEasy framework will effectively sink any calls to the methods of the fake log service, which is fine for this test.</p>
  378. <p>Lastly the data provider we want to test is registered with the DI container builder, and then container is built. The tests go on to use the DI container to resolve an instance of the data provider. The DI container will configure the data providers dependencies for a log service and an identity service with the fakes we built.</p>
  379. <div><table class="CodeRay"><tr>
  380. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  381. <a href="#n2" name="n2">2</a>
  382. <a href="#n3" name="n3">3</a>
  383. <a href="#n4" name="n4">4</a>
  384. <a href="#n5" name="n5">5</a>
  385. <a href="#n6" name="n6">6</a>
  386. <a href="#n7" name="n7">7</a>
  387. <a href="#n8" name="n8">8</a>
  388. </pre></td>
  389. <td class="code"><pre>[TestMethod()]
  390. <span class="directive">public</span> <span class="type">void</span> GetCurrentEmployeeTest() {
  391. var e = <span class="keyword">new</span> Employee { WindowsUsername = <span class="string"><span class="delimiter">&quot;</span><span class="content">FAKE-ID</span><span class="delimiter">&quot;</span></span> };
  392. var dal = afContainer.Resolve&lt;IDataProvider&gt;();
  393. dal.AddEmployee(e);
  394. var result = dal.GetCurrentEmployee();
  395. Assert.AreEqual(e.WindowsUsername, result.WindowsUsername);
  396. }
  397. </pre></td>
  398. </tr></table>
  399. </div>
  400. <p>This is just a small example of using a DI container in combination with a mock / fake framework for testing. The AutoFac DI container can handle much more complex scenarios than what weve thrown at it here. The same is true for the FakeItEasy component. Both of these components are well used, well maintained open source projects. You can find lots of documentation and examples for both. Or you can use any number of other DI containers and mocking frameworks to achieve equivalent results.</p>
  401. <p>The source code for the example is available <a href="https://bitbucket.org/efvincent/blog-post-dependency-injection-101">here</a>, and the blog entry the precedes this one is available <a href="http://blog.efvincent.com/practical-di-101/">here</a>.</p>
  402. ]]></content>
  403. </entry>
  404. <entry>
  405. <title type="html"><![CDATA[Practical Dependency Injection 101]]></title>
  406. <link href="http://efvincent.github.io/blog/2011/05/27/practical-di-101/"/>
  407. <updated>2011-05-27T13:08:27-04:00</updated>
  408. <id>http://efvincent.github.io/blog/2011/05/27/practical-di-101</id>
  409. <content type="html"><![CDATA[<p>In this post we take a look at dependency injection (DI). Target audience is competent .NET developers, C# specifically (but VBers who read C# can benefit just as much), whove heard of DI but havent gotten around to figuring out how it fits in their day to day.</p>
  410. <!-- more -->
  411. <p>### What is Dependency Injection</p>
  412. <p>The first question that we need to address is: What is it that DI does for us? What problem is being solved? DI is about coupling; the degree to which program unit refers to other units. In .NET the units were typically worried about are classes, interfaces, components, and assemblies. Dependency injection facilitates reduction these interdependencies. Are DI patterns a silver bullet? Of course not. You can always write bad code regardless of patterns. That being said, if youre already writing decent code and have good fundamentals, but are not using DI patterns, youve got the opportunity to take a leap forward.</p>
  413. <p>How does DI reduce help reduce coupling? The easiest way to describe it is by diving directly into an example.</p>
  414. <h3 id="example-scenario">Example Scenario</h3>
  415. <p>Well work on a hypothetical in-house app where the Windows AD authenticates employees, and their Windows username is used to index a database with Employee information. Its pretty common to see stuff like this happening in-house with line of business applications.</p>
  416. <p>The example uses a provider pattern all the data access will go through a data access provider, allowing us to build a simple provider that stores records in memory during this, our prototype phase. Theoretically wed replace this as development continued with a provider that leverages persistent storage later.</p>
  417. <p>Heres the base level example program with no consideration for dependency injection:</p>
  418. <div><table class="CodeRay"><tr>
  419. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  420. <a href="#n2" name="n2">2</a>
  421. <a href="#n3" name="n3">3</a>
  422. <a href="#n4" name="n4">4</a>
  423. <a href="#n5" name="n5">5</a>
  424. <a href="#n6" name="n6">6</a>
  425. <a href="#n7" name="n7">7</a>
  426. <a href="#n8" name="n8">8</a>
  427. <a href="#n9" name="n9">9</a>
  428. <strong><a href="#n10" name="n10">10</a></strong>
  429. <a href="#n11" name="n11">11</a>
  430. <a href="#n12" name="n12">12</a>
  431. <a href="#n13" name="n13">13</a>
  432. <a href="#n14" name="n14">14</a>
  433. <a href="#n15" name="n15">15</a>
  434. <a href="#n16" name="n16">16</a>
  435. <a href="#n17" name="n17">17</a>
  436. <a href="#n18" name="n18">18</a>
  437. <a href="#n19" name="n19">19</a>
  438. <strong><a href="#n20" name="n20">20</a></strong>
  439. <a href="#n21" name="n21">21</a>
  440. <a href="#n22" name="n22">22</a>
  441. <a href="#n23" name="n23">23</a>
  442. <a href="#n24" name="n24">24</a>
  443. <a href="#n25" name="n25">25</a>
  444. <a href="#n26" name="n26">26</a>
  445. <a href="#n27" name="n27">27</a>
  446. <a href="#n28" name="n28">28</a>
  447. <a href="#n29" name="n29">29</a>
  448. <strong><a href="#n30" name="n30">30</a></strong>
  449. <a href="#n31" name="n31">31</a>
  450. <a href="#n32" name="n32">32</a>
  451. <a href="#n33" name="n33">33</a>
  452. <a href="#n34" name="n34">34</a>
  453. <a href="#n35" name="n35">35</a>
  454. <a href="#n36" name="n36">36</a>
  455. <a href="#n37" name="n37">37</a>
  456. <a href="#n38" name="n38">38</a>
  457. <a href="#n39" name="n39">39</a>
  458. <strong><a href="#n40" name="n40">40</a></strong>
  459. <a href="#n41" name="n41">41</a>
  460. <a href="#n42" name="n42">42</a>
  461. <a href="#n43" name="n43">43</a>
  462. <a href="#n44" name="n44">44</a>
  463. <a href="#n45" name="n45">45</a>
  464. <a href="#n46" name="n46">46</a>
  465. <a href="#n47" name="n47">47</a>
  466. <a href="#n48" name="n48">48</a>
  467. <a href="#n49" name="n49">49</a>
  468. <strong><a href="#n50" name="n50">50</a></strong>
  469. <a href="#n51" name="n51">51</a>
  470. <a href="#n52" name="n52">52</a>
  471. <a href="#n53" name="n53">53</a>
  472. <a href="#n54" name="n54">54</a>
  473. <a href="#n55" name="n55">55</a>
  474. <a href="#n56" name="n56">56</a>
  475. <a href="#n57" name="n57">57</a>
  476. <a href="#n58" name="n58">58</a>
  477. <a href="#n59" name="n59">59</a>
  478. <strong><a href="#n60" name="n60">60</a></strong>
  479. <a href="#n61" name="n61">61</a>
  480. </pre></td>
  481. <td class="code"><pre><span class="type">class</span> <span class="class">Program</span> {
  482. <span class="directive">static</span> <span class="type">void</span> Main(string<span class="type">[]</span> args) {
  483. <span class="comment">// ** Without using an DI Container approach **</span>
  484. <span class="comment">// Create a new provider aka data access layer</span>
  485. var dal = <span class="keyword">new</span> DevDataProvider();
  486. <span class="comment">// New up an employee that's supposed to represent the currently logged in user</span>
  487. var e = <span class="keyword">new</span> Employee() {
  488. WindowsUsername = <span class="string"><span class="delimiter">&quot;</span><span class="content">thanos</span><span class="char">\\</span><span class="content">efvincent</span><span class="delimiter">&quot;</span></span>,
  489. EmployeeId = <span class="string"><span class="delimiter">&quot;</span><span class="content">0001</span><span class="delimiter">&quot;</span></span>,
  490. FName = <span class="string"><span class="delimiter">&quot;</span><span class="content">Eric</span><span class="delimiter">&quot;</span></span>,
  491. LName = <span class="string"><span class="delimiter">&quot;</span><span class="content">Vincent</span><span class="delimiter">&quot;</span></span>
  492. };
  493. <span class="comment">// Add it to the data access layer</span>
  494. dal.AddEmployee(e);
  495. <span class="comment">// See if the dal can find the current user</span>
  496. e = dal.GetCurrentEmployee();
  497. Console.WriteLine(
  498. <span class="string"><span class="delimiter">&quot;</span><span class="content">Current logged in person is: {0}</span><span class="delimiter">&quot;</span></span>, e == <span class="predefined-constant">null</span> ? <span class="string"><span class="delimiter">&quot;</span><span class="content">unknown</span><span class="delimiter">&quot;</span></span> : e.FName);
  499. <span class="comment">// End</span>
  500. Console.Write(<span class="string"><span class="delimiter">&quot;</span><span class="content">Press any key...</span><span class="delimiter">&quot;</span></span>);
  501. Console.ReadKey(<span class="predefined-constant">true</span>);
  502. }
  503. }
  504. <span class="directive">public</span> <span class="type">class</span> <span class="class">DevDataProvider</span> {
  505. <span class="directive">private</span> <span class="directive">static</span> readonly <span class="predefined-type">List</span>&lt;Employee&gt; EmployeeStore = <span class="keyword">new</span> <span class="predefined-type">List</span>&lt;Employee&gt;();
  506. <span class="directive">public</span> Employee GetCurrentEmployee() {
  507. var emp = EmployeeStore.FirstOrDefault(
  508. e =&gt; e.WindowsUsername.Equals(GetCurrentUserName(), StringComparison.OrdinalIgnoreCase));
  509. <span class="keyword">return</span> emp;
  510. }
  511. <span class="directive">public</span> <span class="type">void</span> AddEmployee(Employee e) {
  512. EmployeeStore.Add(e);
  513. }
  514. <span class="directive">public</span> IQueryable&lt;Employee&gt; Employees() {
  515. <span class="keyword">return</span> EmployeeStore.AsQueryable();
  516. }
  517. <span class="directive">private</span> <span class="directive">static</span> string GetCurrentUserName() {
  518. var wu = WindowsIdentity.GetCurrent();
  519. <span class="keyword">return</span> wu == <span class="predefined-constant">null</span> ? string.Empty : wu.Name;
  520. }
  521. }
  522. <span class="directive">public</span> <span class="type">class</span> <span class="class">Employee</span> {
  523. <span class="directive">public</span> string WindowsUsername { get; set; }
  524. <span class="directive">public</span> string EmployeeId { get; set; }
  525. <span class="directive">public</span> string FName { get; set; }
  526. <span class="directive">public</span> string LName { get; set; }
  527. }
  528. </pre></td>
  529. </tr></table>
  530. </div>
  531. <p>In Main() we new up the data access layer, create a new employee, and add it to our store using the data access layer. At line 21 we ask the data access layer to retrieve the employee record for the currently logged in user. Looks pretty typical, so how can IoC help? Lets look at the coupling here what classes are dependent on what other classes?</p>
  532. <p><a href="http://blog.efvincent.com/wp-content/uploads/2011/05/image.png"><img src="http://blog.efvincent.com/wp-content/uploads/2011/05/image_thumb.png" alt="image" /></a></p>
  533. <p>Our main program depends on the DevDataProvider class, and that depends on System.Security to find the Windows username of the currently logged in user. Asking the data access layer to determine the currently logged in user isnt the best idea, but this is blog post code created to check out dependency injection, so deal with that for the moment.</p>
  534. <p>Why are these dependencies undesirable? First consider how flexible this software is. Or rather, inflexible. We created a quick DevDataProvider that stores stuff in a static list. As we continue to build a system, wed have to refer to DevDataProvider from more and more classes, creating a brittle, tightly coupled system. Replacing DevDataProvider becomes more of a maintenance problem.</p>
  535. <p>Next think about testability. In real life there are unit tests (there should be anyway). One reason why people find excuses not to unit test is because their code is difficult to test. In this example, if we want to test DevDataProvider.GetCurrentEmployee() we have to consider that under the covers its calling the Windows API to get the current username. This makes that method harder to than it needs to be.</p>
  536. <h3 id="step-one--leveraging-interfaces">Step One Leveraging Interfaces</h3>
  537. <p>In this version, weve factored out an interface called IDataProvider, and one called IIdentService. The IDataProvider should be pretty obvious but IIdentService? The idea here is to decouple from the Windows API itself. A developer should understand <em>everywhere _that the application makes contact with _any</em> external modules, including the operating system, and then consider what the repercussions of that contact are. In this example, coupling to the Windows API to get then logged in username so directly is undesirable. We want to use a <em>service</em> that would supply us with credentials. That way if were testing, we can create a fake service that provides a predictable answer, and is therefore easier to test.</p>
  538. <p>Coding to an interface also allows us to radically change the behavior of the service without having to alter its dependencies. If we move to a ASP.NET environment for example, we wont want to use the current Windows Identity, we may want to use user information from the http context.</p>
  539. <div><table class="CodeRay"><tr>
  540. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  541. <a href="#n2" name="n2">2</a>
  542. <a href="#n3" name="n3">3</a>
  543. <a href="#n4" name="n4">4</a>
  544. <a href="#n5" name="n5">5</a>
  545. <a href="#n6" name="n6">6</a>
  546. <a href="#n7" name="n7">7</a>
  547. <a href="#n8" name="n8">8</a>
  548. <a href="#n9" name="n9">9</a>
  549. <strong><a href="#n10" name="n10">10</a></strong>
  550. <a href="#n11" name="n11">11</a>
  551. <a href="#n12" name="n12">12</a>
  552. <a href="#n13" name="n13">13</a>
  553. <a href="#n14" name="n14">14</a>
  554. <a href="#n15" name="n15">15</a>
  555. <a href="#n16" name="n16">16</a>
  556. <a href="#n17" name="n17">17</a>
  557. <a href="#n18" name="n18">18</a>
  558. <a href="#n19" name="n19">19</a>
  559. <strong><a href="#n20" name="n20">20</a></strong>
  560. <a href="#n21" name="n21">21</a>
  561. <a href="#n22" name="n22">22</a>
  562. <a href="#n23" name="n23">23</a>
  563. <a href="#n24" name="n24">24</a>
  564. <a href="#n25" name="n25">25</a>
  565. <a href="#n26" name="n26">26</a>
  566. <a href="#n27" name="n27">27</a>
  567. <a href="#n28" name="n28">28</a>
  568. <a href="#n29" name="n29">29</a>
  569. <strong><a href="#n30" name="n30">30</a></strong>
  570. <a href="#n31" name="n31">31</a>
  571. <a href="#n32" name="n32">32</a>
  572. <a href="#n33" name="n33">33</a>
  573. <a href="#n34" name="n34">34</a>
  574. <a href="#n35" name="n35">35</a>
  575. <a href="#n36" name="n36">36</a>
  576. <a href="#n37" name="n37">37</a>
  577. <a href="#n38" name="n38">38</a>
  578. <a href="#n39" name="n39">39</a>
  579. <strong><a href="#n40" name="n40">40</a></strong>
  580. <a href="#n41" name="n41">41</a>
  581. <a href="#n42" name="n42">42</a>
  582. <a href="#n43" name="n43">43</a>
  583. <a href="#n44" name="n44">44</a>
  584. <a href="#n45" name="n45">45</a>
  585. <a href="#n46" name="n46">46</a>
  586. <a href="#n47" name="n47">47</a>
  587. </pre></td>
  588. <td class="code"><pre><span class="comment">// Interface defining an identity service</span>
  589. <span class="directive">public</span> <span class="type">interface</span> <span class="class">IIdentService</span> {
  590. string GetCurrentUserName();
  591. }
  592. <span class="comment">// Implementation of an identity service that returns the current</span>
  593. <span class="comment">// logged in windows username</span>
  594. <span class="directive">public</span> <span class="type">class</span> <span class="class">WindowsIdentService</span> : IIdentService {
  595. <span class="directive">public</span> string GetCurrentUserName() {
  596. var wu = WindowsIdentity.GetCurrent();
  597. <span class="keyword">return</span> wu == <span class="predefined-constant">null</span> ? string.Empty : wu.Name;
  598. }
  599. }
  600. <span class="comment">// Interface defining a data provider service</span>
  601. <span class="directive">public</span> <span class="type">interface</span> <span class="class">IDataProvider</span> {
  602. Employee GetCurrentEmployee();
  603. <span class="type">void</span> AddEmployee(Employee e);
  604. IQueryable&lt;Employee&gt; Employees();
  605. }
  606. <span class="comment">// Our development data provider now implements the interface</span>
  607. <span class="directive">public</span> <span class="type">class</span> <span class="class">DevDataProvider</span> : IDataProvider {
  608. <span class="directive">private</span> readonly IIdentService _identService;
  609. <span class="directive">private</span> <span class="directive">static</span> readonly <span class="predefined-type">List</span>&lt;Employee&gt; EmployeeStore = <span class="keyword">new</span> <span class="predefined-type">List</span>&lt;Employee&gt;();
  610. <span class="directive">public</span> DevDataProvider(IIdentService identService) {
  611. <span class="keyword">if</span> (identService == <span class="predefined-constant">null</span>) <span class="keyword">throw</span> <span class="keyword">new</span> ArgumentNullException(<span class="string"><span class="delimiter">&quot;</span><span class="content">identService</span><span class="delimiter">&quot;</span></span>);
  612. _identService = identService;
  613. }
  614. <span class="directive">public</span> Employee GetCurrentEmployee() {
  615. var emp = EmployeeStore.FirstOrDefault(
  616. e =&gt; e.WindowsUsername.Equals(
  617. _identService.GetCurrentUserName(),
  618. StringComparison.OrdinalIgnoreCase));
  619. <span class="keyword">return</span> emp;
  620. }
  621. <span class="directive">public</span> <span class="type">void</span> AddEmployee(Employee e) {
  622. EmployeeStore.Add(e);
  623. }
  624. <span class="directive">public</span> IQueryable&lt;Employee&gt; Employees() {
  625. <span class="keyword">return</span> EmployeeStore.AsQueryable();
  626. }
  627. }
  628. </pre></td>
  629. </tr></table>
  630. </div>
  631. <p>Were part of the way to where we need to be. Altering DevDataProvider to depend on the IIdentService interface frees it from a hard dependency on a particular identity implementation. The downside is weve made creation of the DevDataProvider a bit more complex, as we need to supply the new instance with an IIdentityService instance.</p>
  632. <p>~~~C#
  633. // Create a new ident service, required for the DAL
  634. IIdentService identSvc = new WindowsIdentService();</p>
  635. <p>// Create a new DAL
  636. IDataProvider dal = new DevDataProvider(identSvc);
  637. ~~~</p>
  638. <p>The DevDataProvider now takes a constructor parameter of type IIdentService. This is where the <em>injection</em> in dependency injection comes from. DevDataProvider has a dependency, but instead of hard coding it into the definition of DevDataProvider, we inject it. There are different ways of injecting dependencies, but constructor injection is very popular and works well in many, or even most cases.</p>
  639. <p>The complexity of constructing instances increases when we add a simple logging service which logs information or errors messages.</p>
  640. <p>~~~C#
  641. // Interface defining a logging service
  642. public interface ILogService {
  643. void LogInfo(string msg, params object[] args);
  644. void LogError(string msg, params object[] args);
  645. }</p>
  646. <p>// Implementation of a console logging service
  647. public class ConsoleLogger : ILogService {
  648. public void LogInfo(string msg, params object[] args) {
  649. Console.WriteLine(
  650. {0} INFO: {1}, DateTime.Now,
  651. string.Format(msg, args));
  652. }</p>
  653. <pre><code>public void LogError(string msg, params object[] args) {
  654. Console.WriteLine(
  655. "{0} ERROR: {1}", DateTime.Now,
  656. string.Format(msg, args));
  657. } } ~~~
  658. </code></pre>
  659. <p>The ILogService is implemented by a simple console logger. Now both the WindowsIdentService and the DevDataProvider can leverage the logger. Theyre both modified to have ILogService instance injected via their respective constructors.</p>
  660. <div><table class="CodeRay"><tr>
  661. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  662. <a href="#n2" name="n2">2</a>
  663. <a href="#n3" name="n3">3</a>
  664. <a href="#n4" name="n4">4</a>
  665. <a href="#n5" name="n5">5</a>
  666. <a href="#n6" name="n6">6</a>
  667. <a href="#n7" name="n7">7</a>
  668. <a href="#n8" name="n8">8</a>
  669. <a href="#n9" name="n9">9</a>
  670. <strong><a href="#n10" name="n10">10</a></strong>
  671. <a href="#n11" name="n11">11</a>
  672. <a href="#n12" name="n12">12</a>
  673. <a href="#n13" name="n13">13</a>
  674. <a href="#n14" name="n14">14</a>
  675. <a href="#n15" name="n15">15</a>
  676. <a href="#n16" name="n16">16</a>
  677. <a href="#n17" name="n17">17</a>
  678. <a href="#n18" name="n18">18</a>
  679. <a href="#n19" name="n19">19</a>
  680. <strong><a href="#n20" name="n20">20</a></strong>
  681. <a href="#n21" name="n21">21</a>
  682. <a href="#n22" name="n22">22</a>
  683. <a href="#n23" name="n23">23</a>
  684. <a href="#n24" name="n24">24</a>
  685. <a href="#n25" name="n25">25</a>
  686. <a href="#n26" name="n26">26</a>
  687. <a href="#n27" name="n27">27</a>
  688. <a href="#n28" name="n28">28</a>
  689. <a href="#n29" name="n29">29</a>
  690. <strong><a href="#n30" name="n30">30</a></strong>
  691. <a href="#n31" name="n31">31</a>
  692. <a href="#n32" name="n32">32</a>
  693. <a href="#n33" name="n33">33</a>
  694. <a href="#n34" name="n34">34</a>
  695. <a href="#n35" name="n35">35</a>
  696. <a href="#n36" name="n36">36</a>
  697. <a href="#n37" name="n37">37</a>
  698. <a href="#n38" name="n38">38</a>
  699. <a href="#n39" name="n39">39</a>
  700. <strong><a href="#n40" name="n40">40</a></strong>
  701. <a href="#n41" name="n41">41</a>
  702. <a href="#n42" name="n42">42</a>
  703. <a href="#n43" name="n43">43</a>
  704. <a href="#n44" name="n44">44</a>
  705. <a href="#n45" name="n45">45</a>
  706. <a href="#n46" name="n46">46</a>
  707. <a href="#n47" name="n47">47</a>
  708. <a href="#n48" name="n48">48</a>
  709. <a href="#n49" name="n49">49</a>
  710. </pre></td>
  711. <td class="code"><pre><span class="comment">// Implementation of an identity service that returns the current</span>
  712. <span class="comment">// logged in windows username</span>
  713. <span class="directive">public</span> <span class="type">class</span> <span class="class">WindowsIdentService</span> : IIdentService {
  714. <span class="directive">private</span> readonly ILogService _logSvc;
  715. <span class="directive">public</span> WindowsIdentService(ILogService logSvc) {
  716. <span class="keyword">if</span> (logSvc == <span class="predefined-constant">null</span>) <span class="keyword">throw</span> <span class="keyword">new</span> ArgumentNullException(<span class="string"><span class="delimiter">&quot;</span><span class="content">logSvc</span><span class="delimiter">&quot;</span></span>);
  717. _logSvc = logSvc;
  718. }
  719. <span class="directive">public</span> string GetCurrentUserName() {
  720. var wu = WindowsIdentity.GetCurrent();
  721. var un = wu == <span class="predefined-constant">null</span> ? string.Empty : wu.Name;
  722. _logSvc.LogInfo(<span class="string"><span class="delimiter">&quot;</span><span class="content">Identified current user as: {0}</span><span class="delimiter">&quot;</span></span>, un);
  723. <span class="keyword">return</span> un;
  724. }
  725. }
  726. <span class="comment">// Our development data provider now implements the interface</span>
  727. <span class="directive">public</span> <span class="type">class</span> <span class="class">DevDataProvider</span> : IDataProvider {
  728. <span class="directive">private</span> readonly IIdentService _identService;
  729. <span class="directive">private</span> readonly ILogService _logSvc;
  730. <span class="directive">private</span> <span class="directive">static</span> readonly <span class="predefined-type">List</span>&lt;Employee&gt; EmployeeStore = <span class="keyword">new</span> <span class="predefined-type">List</span>&lt;Employee&gt;();
  731. <span class="directive">public</span> DevDataProvider(IIdentService identService, ILogService logSvc) {
  732. <span class="keyword">if</span> (identService == <span class="predefined-constant">null</span>) <span class="keyword">throw</span> <span class="keyword">new</span> ArgumentNullException(<span class="string"><span class="delimiter">&quot;</span><span class="content">identService</span><span class="delimiter">&quot;</span></span>);
  733. <span class="keyword">if</span> (logSvc == <span class="predefined-constant">null</span>) <span class="keyword">throw</span> <span class="keyword">new</span> ArgumentNullException(<span class="string"><span class="delimiter">&quot;</span><span class="content">logSvc</span><span class="delimiter">&quot;</span></span>);
  734. _identService = identService;
  735. _logSvc = logSvc;
  736. }
  737. <span class="directive">public</span> Employee GetCurrentEmployee() {
  738. var un = _identService.GetCurrentUserName();
  739. var emp = EmployeeStore.FirstOrDefault(
  740. e =&gt; e.WindowsUsername.Equals(un,
  741. StringComparison.OrdinalIgnoreCase));
  742. <span class="keyword">if</span> (emp == <span class="predefined-constant">null</span>) _logSvc.LogInfo(<span class="string"><span class="delimiter">&quot;</span><span class="content">Current employee {0} not found</span><span class="delimiter">&quot;</span></span>, un);
  743. <span class="keyword">return</span> emp;
  744. }
  745. <span class="directive">public</span> <span class="type">void</span> AddEmployee(Employee e) {
  746. EmployeeStore.Add(e);
  747. _logSvc.LogInfo(<span class="string"><span class="delimiter">&quot;</span><span class="content">Added employee with id {0}</span><span class="delimiter">&quot;</span></span>, e.EmployeeId);
  748. }
  749. <span class="directive">public</span> IQueryable&lt;Employee&gt; Employees() {
  750. <span class="keyword">return</span> EmployeeStore.AsQueryable();
  751. }
  752. }
  753. </pre></td>
  754. </tr></table>
  755. </div>
  756. <p>Now the services are getting more robust and theyre not tightly coupled to each other, they refer only to interfaces of the services they depend on. Main() however, where construction is going on, is getting messy.</p>
  757. <div><table class="CodeRay"><tr>
  758. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  759. <a href="#n2" name="n2">2</a>
  760. <a href="#n3" name="n3">3</a>
  761. <a href="#n4" name="n4">4</a>
  762. <a href="#n5" name="n5">5</a>
  763. <a href="#n6" name="n6">6</a>
  764. <a href="#n7" name="n7">7</a>
  765. <a href="#n8" name="n8">8</a>
  766. <a href="#n9" name="n9">9</a>
  767. <strong><a href="#n10" name="n10">10</a></strong>
  768. <a href="#n11" name="n11">11</a>
  769. <a href="#n12" name="n12">12</a>
  770. </pre></td>
  771. <td class="code"><pre><span class="directive">static</span> <span class="type">void</span> Main(string<span class="type">[]</span> args) {
  772. <span class="comment">// ** Without using an DI Container approach **</span>
  773. <span class="comment">// Create a new logging service, required for uh.. everything</span>
  774. ILogService consoleLog = <span class="keyword">new</span> ConsoleLogger();
  775. <span class="comment">// Create a new ident service, required for the DAL</span>
  776. IIdentService identSvc = <span class="keyword">new</span> WindowsIdentService(consoleLog);
  777. <span class="comment">// Create a new DAL</span>
  778. IDataProvider dal = <span class="keyword">new</span> DevDataProvider(identSvc, consoleLog);
  779. </pre></td>
  780. </tr></table>
  781. </div>
  782. <p>Finally were at the point where we can see the benefit of an dependency injection container. One thing about DI containers is that theyre already written. Several mature, robust, open-source DI containers exist. Well use AutoFac, because thats what Ive been using lately. We include <a href="http://www.nuget.org/List/Packages/Autofac">AutoFac</a> using <a href="http://www.nuget.org">NuGet</a>.</p>
  783. <pre><code>// Create a singleton dependency injection container
  784. private static readonly IContainer Container = ConfigureContainer();
  785. // Configure the container
  786. static IContainer ConfigureContainer() {
  787. // This is how AutoFac works. Other DI containers have similar
  788. // mechanisms for configuring the container
  789. var bld = new ContainerBuilder();
  790. // Register the types that implement the interfaces that are required
  791. // for injection. Note that we have robust control over lifetime, in
  792. // this case ILogService and IIdentService will be singletons, and
  793. // IDataProvider will provide a new instance each time it's requested
  794. bld.RegisterType&lt;ConsoleLogger&gt;().As&lt;ILogService&gt;().SingleInstance();
  795. bld.RegisterType&lt;WindowsIdentService&gt;().As&lt;IIdentService&gt;().SingleInstance();
  796. bld.RegisterType&lt;DevDataProvider&gt;().As&lt;IDataProvider&gt;();
  797. return bld.Build();
  798. }
  799. static void Main(string[] args) {
  800. // ** Using an IoC Container approach **
  801. var dal = Container.Resolve&lt;IDataProvider&gt;();
  802. </code></pre>
  803. <p>Weve created a static instance of IContainer (an AutoFac DI container). When we start the app we configure the container, which fundamentally consists of mapping the interfaces to concrete types that will be injected. For example, line 14 specifies that when theres a need for an instance of ILogService, we will create an instance of ConsoleLogger. It further says that the DI container should use a SingleInstance() of ConsoleLogger. This has the effect of making ConsoleLogger a singleton. In our example, both the WindowsIdentService and the DevDataProvider will be handed the same instance of ConsoleLogger.</p>
  804. <p>The magic happens when we call Container.Resolve<idataprovider>(). The container determines what concrete class to create, and it looks for any dependencies in the constructor. It will see that to build a DevDataProvider, it needs an ILogService and an IWindowsIdentService, it will recursively resolve those as well.</idataprovider></p>
  805. <p>These are the basics of dependency injection. Even in this simple example, it should be obvious that the components and classes that we can create can be designed with very low coupling and cohesion using this technique. There are anti-patterns for using DI as well. You should endeavor to practice this technique, do research and learn the most effective uses; theres plenty of material out there.</p>
  806. <p>I hope this example was helpful. Next post Ill extend this sample by looking at testing, and mock objects, and how DI injection can make testing far easier.</p>
  807. <p>Source code samples can be found at this <a href="https://bitbucket.org/efvincent/blog-post-dependency-injection-101">bitbucket repository</a>.</p>
  808. <p><em>Update:</em> Follow up post - <a href="http://efvincent.github.io/2011/05/28/di-mock">Dependency Injection, Testing, and Mocking</a></p>
  809. ]]></content>
  810. </entry>
  811. <entry>
  812. <title type="html"><![CDATA[NuGet Galleries of Geeky Goodness.]]></title>
  813. <link href="http://efvincent.github.io/blog/2011/01/12/nuget-geeky-goodness/"/>
  814. <updated>2011-01-12T18:27:26-05:00</updated>
  815. <id>http://efvincent.github.io/blog/2011/01/12/nuget-geeky-goodness</id>
  816. <content type="html"><![CDATA[<p>In a <a href="http://blog.efvincent.com/open-source-nuget-and-more/">previous post</a> I described how Scott Hanselmans <a href="http://www.hanselman.com/blog/PDC10BuildingABlogWithMicrosoftUnnamedPackageOfWebLove.aspx">presentation</a> during PDC 2010 introduced me to several wonderful and interesting technologies that are either just now out or about to be. The first one Ill discuss is <a href="http://nuget.codeplex.com">NuGet</a>. There are many excellent introductions to NuGet by <a href="http://www.hanselman.com/blog/IntroducingNuPackPackageManagementForNETAnotherPieceOfTheWebStack.aspx">Hanselman</a> and others. Ill see if I can make a meaningful contribution.</p>
  817. <p>NuGet is an add-on to VS2010. It allows us to access <em>packages</em> that have been published either locally or publicly on the web. The main NuGet gallery just went live today at <a href="http://nuget.org">http://nuget.org</a>. These packages make it easy to install, update, and remove libraries and tools in Visual Studio 2010.</p>
  818. <!-- more -->
  819. <h2 id="installation">Installation</h2>
  820. <p>NuGet, like dozens of other useful add-ins, is available through the Visual Studio Extension Manager, reached under _Tools Extension Manager. _</p>
  821. <p><a href="http://blog.efvincent.com/wp-content/uploads/2011/01/image.png"><img src="http://blog.efvincent.com/wp-content/uploads/2011/01/image_thumb.png" alt="image" /></a></p>
  822. <p>From the Extension Manager choose (1) the online gallery, and then (2) search for NuGet. A restart of Visual Studio is required.</p>
  823. <h2 id="the-nuget-package-manager-console">The NuGet Package Manager Console</h2>
  824. <p>NuGet has two user interfaces. Theres a PowerShell powered console window. This is the UI I was first introduced to and have gravitated towards. The console gives you a more complete sense of control over the process. Open the console by selecting <em>View Other Windows Package Manager Console</em>.</p>
  825. <p><a href="http://blog.efvincent.com/wp-content/uploads/2011/01/image1.png"><img src="http://blog.efvincent.com/wp-content/uploads/2011/01/image_thumb1.png" alt="image" /></a></p>
  826. <p>The <em>Package Source</em> drop down defaults to the official NuGet package gallery. There are already hundreds of packages out in the gallery, and you can expect it to grow rapidly. You can list the packages in the official library with:</p>
  827. <p>List-Packages remote</p>
  828. <p>There are a lot of them, and since the console is PowerShell we can take advantage of a PowerShell grid display:</p>
  829. <table>
  830. <tbody>
  831. <tr>
  832. <td>List-Packages remote</td>
  833. <td>out-GridView</td>
  834. </tr>
  835. </tbody>
  836. </table>
  837. <p><a href="http://blog.efvincent.com/wp-content/uploads/2011/01/image2.png"><img src="http://blog.efvincent.com/wp-content/uploads/2011/01/image_thumb2.png" alt="image" /></a></p>
  838. <h2 id="installing-and-removing-packages">Installing and Removing Packages</h2>
  839. <p>Now comes the really cool part. The whole idea of NuGet is to be able to install / add external libraries to your project without having to find them on the web, download a zip or msi file, install it somewhere on your local machine, figure out what the instructions are for incorporating them into your project, and patching it in manually.</p>
  840. <p>Lets take for example, the latest CTP5 version of Entity Framework, that allows for <em>Code First</em> use of the Entity Framework. EF4 will justify at least one future dedicated post, but well use it here for a quick example. Normally, if you want to try out something like a new version of Entity Framework, theres downloading, installing, shaving the chicken, bla bla bla that youve got to do. Not with NuGet. NuGet can effectively __xcopy deploy it into our project.</p>
  841. <p>Create a new console application in Visual Studio. From the Package Manager Console, type <em>Install-Package EF</em> and press the tab key. An intellisense window will pop up showing packages that begin with EF.</p>
  842. <p><a href="http://blog.efvincent.com/wp-content/uploads/2011/01/image3.png"><img src="http://blog.efvincent.com/wp-content/uploads/2011/01/image_thumb3.png" alt="image" /></a></p>
  843. <p>At the time of this writing, there are five packages. The EFCTP4 ones are obsolete, from the last CTP. For this example, choose <em>EFCodeFirst</em> and press enter. The console displays license info, downloads the EFCodeFirst package, and incorporates it into your project. In the solution explorer, we can see a reference  (1) and a file (2) added to the project.</p>
  844. <p><a href="http://blog.efvincent.com/wp-content/uploads/2011/01/image4.png"><img src="http://blog.efvincent.com/wp-content/uploads/2011/01/image_thumb4.png" alt="image" /></a></p>
  845. <p>Checking the properties of the reference to EntityFramework, you can see that its not installed to the GAC, its local to the solution. NuGet creates a solution level folder called <em>packages</em>. In that folder, in addition to components used as references, is all the data that NuGet needs to install and uninstall packages. All local, without changing any configuration on the machine. More details of the inner workings of NuGet and its packages will come at a later date, plus theres information out there you can dig up if youre so inclined.</p>
  846. <h2 id="using-entity-framework">Using Entity Framework</h2>
  847. <p>Now that weve got it installed, lets quickly use EFCodeFirst just to prove its working. For this example, youll need SQL Server installed (there are other options, but one thing at a time). Ive got Express which works fine. In another post Ill show the new SQL Server Compact Edition 4, which coincidentally you can add to a project using NuGet <img src="http://blog.efvincent.com/wp-content/uploads/2011/01/wlEmoticon-smile.png" alt="Smile" />.</p>
  848. <p>EFCodeFirst allows you to build POCO objects and use them to build a DB. Lets build a quick model. There are a few examples floating around modeling blog posts and comments, so lets <em>not</em> do that. Lets do (super simple) prescriptions and medications. Its on my mind because Im recovering from knee surgery. This code is entered directly into the Program.cs source file for this example.</p>
  849. <div><table class="CodeRay"><tr>
  850. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  851. <a href="#n2" name="n2">2</a>
  852. <a href="#n3" name="n3">3</a>
  853. <a href="#n4" name="n4">4</a>
  854. <a href="#n5" name="n5">5</a>
  855. <a href="#n6" name="n6">6</a>
  856. <a href="#n7" name="n7">7</a>
  857. <a href="#n8" name="n8">8</a>
  858. <a href="#n9" name="n9">9</a>
  859. <strong><a href="#n10" name="n10">10</a></strong>
  860. <a href="#n11" name="n11">11</a>
  861. <a href="#n12" name="n12">12</a>
  862. <a href="#n13" name="n13">13</a>
  863. <a href="#n14" name="n14">14</a>
  864. <a href="#n15" name="n15">15</a>
  865. <a href="#n16" name="n16">16</a>
  866. <a href="#n17" name="n17">17</a>
  867. <a href="#n18" name="n18">18</a>
  868. <a href="#n19" name="n19">19</a>
  869. <strong><a href="#n20" name="n20">20</a></strong>
  870. <a href="#n21" name="n21">21</a>
  871. <a href="#n22" name="n22">22</a>
  872. <a href="#n23" name="n23">23</a>
  873. <a href="#n24" name="n24">24</a>
  874. <a href="#n25" name="n25">25</a>
  875. <a href="#n26" name="n26">26</a>
  876. <a href="#n27" name="n27">27</a>
  877. <a href="#n28" name="n28">28</a>
  878. <a href="#n29" name="n29">29</a>
  879. <strong><a href="#n30" name="n30">30</a></strong>
  880. <a href="#n31" name="n31">31</a>
  881. <a href="#n32" name="n32">32</a>
  882. <a href="#n33" name="n33">33</a>
  883. <a href="#n34" name="n34">34</a>
  884. <a href="#n35" name="n35">35</a>
  885. <a href="#n36" name="n36">36</a>
  886. <a href="#n37" name="n37">37</a>
  887. <a href="#n38" name="n38">38</a>
  888. <a href="#n39" name="n39">39</a>
  889. <strong><a href="#n40" name="n40">40</a></strong>
  890. <a href="#n41" name="n41">41</a>
  891. <a href="#n42" name="n42">42</a>
  892. <a href="#n43" name="n43">43</a>
  893. <a href="#n44" name="n44">44</a>
  894. <a href="#n45" name="n45">45</a>
  895. <a href="#n46" name="n46">46</a>
  896. <a href="#n47" name="n47">47</a>
  897. <a href="#n48" name="n48">48</a>
  898. <a href="#n49" name="n49">49</a>
  899. <strong><a href="#n50" name="n50">50</a></strong>
  900. <a href="#n51" name="n51">51</a>
  901. <a href="#n52" name="n52">52</a>
  902. <a href="#n53" name="n53">53</a>
  903. <a href="#n54" name="n54">54</a>
  904. <a href="#n55" name="n55">55</a>
  905. <a href="#n56" name="n56">56</a>
  906. <a href="#n57" name="n57">57</a>
  907. <a href="#n58" name="n58">58</a>
  908. <a href="#n59" name="n59">59</a>
  909. <strong><a href="#n60" name="n60">60</a></strong>
  910. <a href="#n61" name="n61">61</a>
  911. <a href="#n62" name="n62">62</a>
  912. <a href="#n63" name="n63">63</a>
  913. <a href="#n64" name="n64">64</a>
  914. <a href="#n65" name="n65">65</a>
  915. <a href="#n66" name="n66">66</a>
  916. <a href="#n67" name="n67">67</a>
  917. <a href="#n68" name="n68">68</a>
  918. <a href="#n69" name="n69">69</a>
  919. <strong><a href="#n70" name="n70">70</a></strong>
  920. <a href="#n71" name="n71">71</a>
  921. <a href="#n72" name="n72">72</a>
  922. <a href="#n73" name="n73">73</a>
  923. <a href="#n74" name="n74">74</a>
  924. <a href="#n75" name="n75">75</a>
  925. <a href="#n76" name="n76">76</a>
  926. <a href="#n77" name="n77">77</a>
  927. <a href="#n78" name="n78">78</a>
  928. <a href="#n79" name="n79">79</a>
  929. <strong><a href="#n80" name="n80">80</a></strong>
  930. <a href="#n81" name="n81">81</a>
  931. <a href="#n82" name="n82">82</a>
  932. <a href="#n83" name="n83">83</a>
  933. <a href="#n84" name="n84">84</a>
  934. <a href="#n85" name="n85">85</a>
  935. <a href="#n86" name="n86">86</a>
  936. <a href="#n87" name="n87">87</a>
  937. <a href="#n88" name="n88">88</a>
  938. <a href="#n89" name="n89">89</a>
  939. <strong><a href="#n90" name="n90">90</a></strong>
  940. <a href="#n91" name="n91">91</a>
  941. <a href="#n92" name="n92">92</a>
  942. <a href="#n93" name="n93">93</a>
  943. <a href="#n94" name="n94">94</a>
  944. <a href="#n95" name="n95">95</a>
  945. <a href="#n96" name="n96">96</a>
  946. <a href="#n97" name="n97">97</a>
  947. <a href="#n98" name="n98">98</a>
  948. <a href="#n99" name="n99">99</a>
  949. <strong><a href="#n100" name="n100">100</a></strong>
  950. <a href="#n101" name="n101">101</a>
  951. <a href="#n102" name="n102">102</a>
  952. <a href="#n103" name="n103">103</a>
  953. <a href="#n104" name="n104">104</a>
  954. <a href="#n105" name="n105">105</a>
  955. <a href="#n106" name="n106">106</a>
  956. <a href="#n107" name="n107">107</a>
  957. <a href="#n108" name="n108">108</a>
  958. <a href="#n109" name="n109">109</a>
  959. <strong><a href="#n110" name="n110">110</a></strong>
  960. <a href="#n111" name="n111">111</a>
  961. <a href="#n112" name="n112">112</a>
  962. <a href="#n113" name="n113">113</a>
  963. <a href="#n114" name="n114">114</a>
  964. <a href="#n115" name="n115">115</a>
  965. <a href="#n116" name="n116">116</a>
  966. <a href="#n117" name="n117">117</a>
  967. <a href="#n118" name="n118">118</a>
  968. <a href="#n119" name="n119">119</a>
  969. <strong><a href="#n120" name="n120">120</a></strong>
  970. <a href="#n121" name="n121">121</a>
  971. <a href="#n122" name="n122">122</a>
  972. <a href="#n123" name="n123">123</a>
  973. <a href="#n124" name="n124">124</a>
  974. <a href="#n125" name="n125">125</a>
  975. <a href="#n126" name="n126">126</a>
  976. <a href="#n127" name="n127">127</a>
  977. <a href="#n128" name="n128">128</a>
  978. <a href="#n129" name="n129">129</a>
  979. <strong><a href="#n130" name="n130">130</a></strong>
  980. </pre></td>
  981. <td class="code"><pre><span class="directive">public</span> <span class="type">class</span> <span class="class">Prescription</span> {
  982. <span class="directive">public</span> <span class="type">int</span> Id { get; set; }
  983. <span class="directive">public</span> string MedName { get; set; }
  984. <span class="directive">public</span> string Directions { get; set; }
  985. <span class="directive">public</span> <span class="type">int</span> Quantity { get; set; }
  986. <span class="directive">public</span> <span class="type">int</span> Refills { get; set; }
  987. <span class="directive">public</span> <span class="type">int</span> RefillsRemaining { get; set; }
  988. <span class="directive">public</span> ICollection&lt;FilledScript&gt; FilledScripts { get; set; }
  989. }
  990. <span class="directive">public</span> <span class="type">class</span> <span class="class">FilledScript</span> {
  991. <span class="directive">public</span> <span class="type">int</span> Id { get; set; }
  992. <span class="directive">public</span> Prescription Script { get; set; }
  993. <span class="directive">public</span> DateTime Filled { get; set; }
  994. <span class="directive">public</span> <span class="type">int</span> Doses { get; set; }
  995. }
  996. <span class="directive">public</span> <span class="type">class</span> <span class="class">MedContext</span> : DbContext {
  997. <span class="directive">public</span> DbSet&lt;Prescription&gt; Prescriptions { get; set; }
  998. <span class="directive">public</span> DbSet&lt;FilledScript&gt; FilledScripts { get; set; }
  999. }
  1000. &lt;div <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">bogus-wrapper</span><span class="delimiter">'</span></span>&gt;&lt;<span class="class">notextile</span>&gt;&lt;figure <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">code</span><span class="delimiter">'</span></span>&gt;&lt;<span class="class">div</span> <span class="type">class</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">highlight</span><span class="delimiter">&quot;</span></span>&gt;&lt;<span class="class">table</span>&gt;&lt;tr&gt;&lt;td <span class="type">class</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">gutter</span><span class="delimiter">&quot;</span></span>&gt;&lt;<span class="class">pre</span> <span class="type">class</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">line-numbers</span><span class="delimiter">&quot;</span></span>&gt;&lt;<span class="class">span</span> <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">1</span>&lt;/<span class="class">span</span>&gt;
  1001. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">2</span>&lt;/<span class="class">span</span>&gt;
  1002. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">3</span>&lt;/<span class="class">span</span>&gt;
  1003. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">4</span>&lt;/<span class="class">span</span>&gt;
  1004. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">5</span>&lt;/<span class="class">span</span>&gt;
  1005. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">6</span>&lt;/<span class="class">span</span>&gt;
  1006. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">7</span>&lt;/<span class="class">span</span>&gt;
  1007. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">8</span>&lt;/<span class="class">span</span>&gt;
  1008. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">9</span>&lt;/<span class="class">span</span>&gt;
  1009. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">10</span>&lt;/<span class="class">span</span>&gt;
  1010. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">11</span>&lt;/<span class="class">span</span>&gt;
  1011. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">12</span>&lt;/<span class="class">span</span>&gt;
  1012. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">13</span>&lt;/<span class="class">span</span>&gt;
  1013. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">14</span>&lt;/<span class="class">span</span>&gt;
  1014. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">15</span>&lt;/<span class="class">span</span>&gt;
  1015. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">16</span>&lt;/<span class="class">span</span>&gt;
  1016. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">17</span>&lt;/<span class="class">span</span>&gt;
  1017. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">18</span>&lt;/<span class="class">span</span>&gt;
  1018. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">19</span>&lt;/<span class="class">span</span>&gt;
  1019. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">20</span>&lt;/<span class="class">span</span>&gt;
  1020. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">21</span>&lt;/<span class="class">span</span>&gt;
  1021. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">22</span>&lt;/<span class="class">span</span>&gt;
  1022. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">23</span>&lt;/<span class="class">span</span>&gt;
  1023. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">24</span>&lt;/<span class="class">span</span>&gt;
  1024. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">25</span>&lt;/<span class="class">span</span>&gt;
  1025. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">26</span>&lt;/<span class="class">span</span>&gt;
  1026. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">27</span>&lt;/<span class="class">span</span>&gt;
  1027. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">28</span>&lt;/<span class="class">span</span>&gt;
  1028. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">29</span>&lt;/<span class="class">span</span>&gt;
  1029. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">30</span>&lt;/<span class="class">span</span>&gt;
  1030. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">31</span>&lt;/<span class="class">span</span>&gt;
  1031. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">32</span>&lt;/<span class="class">span</span>&gt;
  1032. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">33</span>&lt;/<span class="class">span</span>&gt;
  1033. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">34</span>&lt;/<span class="class">span</span>&gt;
  1034. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">35</span>&lt;/<span class="class">span</span>&gt;
  1035. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">36</span>&lt;/<span class="class">span</span>&gt;
  1036. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">37</span>&lt;/<span class="class">span</span>&gt;
  1037. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">38</span>&lt;/<span class="class">span</span>&gt;
  1038. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">39</span>&lt;/<span class="class">span</span>&gt;
  1039. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">40</span>&lt;/<span class="class">span</span>&gt;
  1040. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">41</span>&lt;/<span class="class">span</span>&gt;
  1041. &lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line-number</span><span class="delimiter">'</span></span>&gt;<span class="integer">42</span>&lt;/<span class="class">span</span>&gt;
  1042. &lt;/pre&gt;&lt;/td&gt;&lt;td <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">code</span><span class="delimiter">'</span></span>&gt;&lt;<span class="class">pre</span>&gt;&lt;code <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="delimiter">'</span></span>&gt;&lt;<span class="class">span</span> <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;
  1043. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;<span class="class">We</span> have a <span class="type">class</span> <span class="class">for</span> a Prescription, and one <span class="keyword">for</span> a FilledScript (filled prescription). We give each one an integer Id, which EF will interpret (by convention) as the primary key and identity <span class="keyword">for</span> each entity. A relation is created between them, again by convention. On the <span class="error"></span>one<span class="error"></span> side,<span class="error"> </span> the Prescription has a collection of filled scripts, and on the <span class="error"></span>many<span class="error"></span> side, the filled script has a reference to its prescription.
  1044. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;
  1045. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;<span class="class">The</span> _MedContext_ <span class="type">class</span> <span class="class">inherits</span> from EF<span class="error"></span>s DbContext, and pulls the model together. Each DbSet&amp;lt;<span class="error"></span>&amp;gt; identifies an entity to EF. In <span class="local-variable">this</span> minimal <span class="keyword">case</span>, that<span class="error"></span>s all that<span class="error"></span>s required to define a model using EFCodeFirst. Lets take a look at using it:
  1046. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;
  1047. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;~~~<span class="class">java</span>
  1048. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;<span class="class">static</span> <span class="type">void</span> Main(string<span class="type">[]</span> args) {
  1049. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;
  1050. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">DbDatabase</span>.SetInitializer(<span class="keyword">new</span> DropCreateDatabaseAlways&amp;lt;MedContext&amp;gt;());
  1051. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;
  1052. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">var</span> ctx = <span class="keyword">new</span> MedContext();
  1053. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">var</span> p = <span class="keyword">new</span> Prescription() {
  1054. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">MedName</span> = <span class="string"><span class="delimiter">&quot;</span><span class="content">Vicoden</span><span class="delimiter">&quot;</span></span>,
  1055. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Directions</span> = <span class="string"><span class="delimiter">&quot;</span><span class="content">One every 4 hours as needed for pain</span><span class="delimiter">&quot;</span></span>,
  1056. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Quantity</span> = <span class="integer">60</span>,
  1057. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Refills</span> = <span class="integer">2</span>,
  1058. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">RefillsRemaining</span> = <span class="integer">1</span>,
  1059. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">FilledScripts</span> = <span class="keyword">new</span><span class="type">[]</span> {
  1060. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">new</span> FilledScript() {
  1061. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Filled</span> = DateTime.Parse(<span class="string"><span class="delimiter">&quot;</span><span class="content">12/28/2010</span><span class="delimiter">&quot;</span></span>),
  1062. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Doses</span> = <span class="integer">0</span>
  1063. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; },
  1064. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">new</span> FilledScript() {
  1065. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Filled</span> = DateTime.Parse(<span class="string"><span class="delimiter">&quot;</span><span class="content">1/12/2011</span><span class="delimiter">&quot;</span></span>),
  1066. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Doses</span> = <span class="integer">48</span>
  1067. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; }
  1068. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; }
  1069. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; };
  1070. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;
  1071. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">ctx</span>.Prescriptions.Add(p);
  1072. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">ctx</span>.SaveChanges();
  1073. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;
  1074. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">foreach</span> (var script in ctx.Prescriptions) {
  1075. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Console</span>.WriteLine(<span class="string"><span class="delimiter">&quot;</span><span class="content">Script for {0}, filled {1} time(s), we have {2} doses on hand</span><span class="delimiter">&quot;</span></span>,
  1076. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">script</span>.MedName,
  1077. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">script</span>.FilledScripts.Count(),
  1078. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">script</span>.FilledScripts.Sum(fs =&amp;gt; fs.Doses));
  1079. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; }
  1080. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;
  1081. &lt;/<span class="class">span</span>&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Console</span>.Write(<span class="string"><span class="delimiter">&quot;</span><span class="char">\n</span><span class="content">Press any key...</span><span class="delimiter">&quot;</span></span>);
  1082. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt; <span class="class">Console</span>.ReadKey(<span class="predefined-constant">true</span>);
  1083. &lt;/span&gt;&lt;span <span class="type">class</span>=<span class="string"><span class="delimiter">'</span><span class="content">line</span><span class="delimiter">'</span></span>&gt;}&lt;/<span class="class">span</span>&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/notextile&gt;&lt;/div&gt;
  1084. For <span class="local-variable">this</span> simple example I<span class="error"></span>m just adding some data and retrieving it right from the main() function of the console app. Line <span class="integer">3</span> probably the only line that needs explanation. It<span class="error"></span>s a call to the <span class="directive">static</span> method SetInitializer() on the <span class="directive">static</span> DbDatabase <span class="type">class</span> <span class="class">of</span> EF. The parameter is a <span class="keyword">new</span> instance of DropCreateDatabaseAlways&lt;MedContext&gt;. Creating <span class="local-variable">this</span> initializer with it<span class="error"></span>s type parameter set to our MedContext tells the EF engine that it should always drop the database and recreate it, every time the app is run. This is part of EF<span class="error"></span>s <span class="keyword">new</span> fluent <span class="type">interface</span>. Under <span class="class">almost</span> no circumstance would you actually use <span class="local-variable">this</span> initializer, but it<span class="error"></span>s handy <span class="keyword">for</span> testing and playing around. This way you can iterate over your model getting a <span class="keyword">new</span> database <span class="keyword">for</span> each run.
  1085. The rest of the function adds a Prescription object with two FilledScript objects, and saves it in the context. It then loops through the prescriptions and writes some info to the console about each. No rocket science there.
  1086. <span class="error">#</span><span class="error">#</span> Where did EF Create the Database?
  1087. One cool thing about EFCodeFirst is that you can leave off pretty much all the configuration information. We didn<span class="error"></span>t tell EF anything about how or where to create the database. It came up with some reasonable defaults. If you open SSMS and connect to your instance of SQL Express, you can see the database it created. Here<span class="error"></span>s a DB diagram in SSMS from what EF created:
  1088. [![image](http:<span class="comment">//blog.efvincent.com/wp-content/uploads/2011/01/image_thumb5.png)](http://blog.efvincent.com/wp-content/uploads/2011/01/image5.png)</span>
  1089. The database it created (<span class="integer">1</span>) is named according to the context that it stores, MedContext <span class="keyword">for</span> us. It created tables (<span class="integer">2</span> &amp; <span class="integer">3</span>) <span class="keyword">for</span> the entities we created, and to implement the one to many relationship, it added a foreign key to the FilledScripts table linking it to the Prescriptions table. There<span class="error"></span>s always a DBA to disagree with an auto-generated schema, but in <span class="local-variable">this</span> simple <span class="keyword">case</span>, you must admit there<span class="error"></span>s not a whole lot you could <span class="keyword">do</span> differently. If we select the records out of the database after our run you get the expected results:
  1090. [![image](http:<span class="comment">//blog.efvincent.com/wp-content/uploads/2011/01/image_thumb6.png)](http://blog.efvincent.com/wp-content/uploads/2011/01/image6.png)</span>
  1091. All of <span class="local-variable">this</span> was created by convention, and can also be overridden and specified explicitly using either attributes on the classes that make up the model, or by using EF<span class="error"></span>s fluent API. This barely scratches the surface, but hopefully gets you interested. I<span class="error"></span>ll cover EF in more depth in a future post, plus there<span class="error"></span>s plenty of info out there already.
  1092. <span class="error">#</span><span class="error">#</span> Back to NuGet <span class="error"></span> Removing a <span class="predefined-type">Package</span>
  1093. Ok, we<span class="error"></span>ve seen how easy it is to add a <span class="keyword">package</span> <span class="namespace">like</span> <span class="namespace">EFCodeFirst</span> (<span class="namespace">and</span> <span class="namespace">how</span> <span class="namespace">cool</span> <span class="namespace">EF</span> <span class="namespace">itself</span> <span class="namespace">is</span>). <span class="namespace">NuGet</span> <span class="namespace">also</span> <span class="namespace">allows</span> <span class="namespace">you</span> <span class="namespace">to</span> <span class="namespace">remove</span> <span class="namespace">a</span> <span class="namespace">package</span> <span class="namespace">easily</span>. <span class="namespace">In</span> <span class="namespace">the</span> <span class="namespace">Package</span> <span class="namespace">Manager</span> <span class="namespace">Console</span> <span class="namespace">window</span>, <span class="namespace">issue</span> <span class="namespace">the</span> <span class="namespace">command</span>:
  1094. </pre></td>
  1095. </tr></table>
  1096. </div>
  1097. <p>PM&gt; Uninstall-Package EFCodeFirst
  1098. Successfully removed EFCodeFirst 0.8 from ConsoleApplication2
  1099. Successfully uninstalled EFCodeFirst 0.8
  1100. ~~~</p>
  1101. <p>NuGet will remove all traces of the package from your project. For EFCodeFirst theres not much to remove. But other packages are far more complicated, even pulling in prerequisite packages, and modifying the web or app.config. NuGet undoes all these changes when a package is removed.</p>
  1102. <h2 id="try-it-yourself">Try it yourself!</h2>
  1103. <p>One great thing about NuGet is how painless it makes trying out new things. Youre not fouling up your precious work machine with a bunch of installations. You can create a quick test project, add a bunch of things youve always wanted to try, and just blow it all away when youre done. No evidence youve been <em>learning</em>.</p>
  1104. <p>Ever want to try Fluent NHibernate but didnt feel like dealing with all the crap that goes with tracking it down and installing it? How about Ninject, Castle, ELMAH, iTextSharp, Moq, or Prism? Theyre all out there. Just NuGet them and start playing / learning.</p>
  1105. <h2 id="what-else">What else?</h2>
  1106. <p>I didnt even mention the wizardy, non-console approach. Right click on your project, and select Add Library Package Reference and you get a pretty UI that lets you click instead of type. But youre a coder. You can type.</p>
  1107. <p>Publishing your own package. You can create any package you want. Perhaps one that pulls in some of your favorite utility classes. Or perhaps youve got some corporate libraries and frameworks that you want to be able to incorporate using NuGet. You can create your own private or a corporate NuGet gallery. Or if you have something worth while, publish it up to the official NuGet gallery, its own to the public.</p>
  1108. <p>I hope youve found this ramble of mine useful. Search around for more NuGet goodness. There are plenty of bloggers way more interesting then me publishing good information.</p>
  1109. <p>Happy Coding!</p>
  1110. ]]></content>
  1111. </entry>
  1112. <entry>
  1113. <title type="html"><![CDATA[Open Source, MVC, MVVM, Entity Framework, NuGet, and More]]></title>
  1114. <link href="http://efvincent.github.io/blog/2011/01/12/open-source-nuget-and-more/"/>
  1115. <updated>2011-01-12T08:53:31-05:00</updated>
  1116. <id>http://efvincent.github.io/blog/2011/01/12/open-source-nuget-and-more</id>
  1117. <content type="html"><![CDATA[<p><strong>Updated</strong>: see the <a href="http://blog.efvincent.com/nuget-geeky-goodness/">NuGet post</a></p>
  1118. <p>The 2010 PDC was a few months ago. There was plenty of interesting and exciting tech news coming from the conference, but the one session that really sparked something with me was Scott Hanselmans Presentation, <em><a href="http://www.hanselman.com/blog/PDC10BuildingABlogWithMicrosoftUnnamedPackageOfWebLove.aspx">ASP.NET + Packaging + Open Source = Crazy Delicious</a></em>. Officially, I was mining PDC for Azure and Windows Identity Foundation material for the project I was (and still am) working on. But I <em>love</em> Hanselmans presentation style; is stuff is always entertaining, stimulating, and <strong>packed</strong> with information. This one was no exception.
  1119. <!-- more -->
  1120. In a nutshell, the presentation described several different new and pre-release technologies mashed up together into a single very technical demo. All of these techs are interesting, and over the last couple of months Ive dived into several, if not all of them and Ive learned a whole lot. I plan on writing about these techs, mostly because when I do I end up learning a lot in the process. But also so I can promote some of these in some small way. In the coming [random time period] Ill be posting on:</p>
  1121. <p><a href="http://nuget.codeplex.com/"><strong>NuGet</strong></a> <em>a free, open source developer focused package management system for the .NET platform intent on simplifying the process of incorporating third party libraries into a .NET application during development</em>. (thats quoted from the Codeplex page). Its way cooler then it sounds youll see.</p>
  1122. <p><strong><a href="http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx">Entity Framework Magic Unicorn Edition</a></strong> Thats what Hanselman called it, its got one of those painful Microsoft names in real life, but Magic Unicorn sounds better. Its Entity Framework 4, the Code Only Entity Framework. EF without boxes and lines. Its super cool and youll love it. Trust me.</p>
  1123. <p><strong><a href="http://weblogs.asp.net/scottgu/archive/2010/12/10/announcing-asp-net-mvc-3-release-candidate-2.aspx">ASP.NET MVC</a> </strong> Not bleeding edge, its been around for a couple of years now. Version 3 is in beta right now, and its getting tight. Time to take a look. Even if youre not going to use it at work next week, its important to start thinking about web development done differently then ASP.NET (some would argue, correctly).</p>
  1124. <p><strong>MVVM Pattern in WPF and Silverlight</strong> Ok this one is not from Hanselmans talk, but at the same time Ive been looking at all the other tech Ive had to dive into some WPF UI work for a project, and I figured Id see what all the chatter was about with MVVM. Ive spent so many years server side, I decided to approach UI with a clean slate.</p>
  1125. <p>Im sure therell be more. Im rehabbing from knee replacement surgery, so I have some extra time behind the keyboard. Now <a href="http://blog.efvincent.com/nuget-geeky-goodness/">on to NuGet</a>.</p>
  1126. ]]></content>
  1127. </entry>
  1128. <entry>
  1129. <title type="html"><![CDATA[In Car VideoCarolina Motorsports Park]]></title>
  1130. <link href="http://efvincent.github.io/blog/2010/08/22/in-car-videocarolina-motorsports-park/"/>
  1131. <updated>2010-08-22T19:57:06-04:00</updated>
  1132. <id>http://efvincent.github.io/blog/2010/08/22/in-car-videocarolina-motorsports-park</id>
  1133. <content type="html"><![CDATA[<p>Ive just finished uploading a new in-car video from the Hurricane region PCA Drivers Ed event at Carolina Motorsports Park in South Carolina. View it embedded here, or click the link below the picture to go to Vimeo.</p>
  1134. <p><a href="http://vimeo.com/14339850">PCA DE CMP August 2010</a> from <a href="http://vimeo.com/efvincent">Eric Vincent</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
  1135. <p><!-- more --></p>
  1136. <p>Some notes about the video and data acquisition, for those interested in the gory, geeky details:</p>
  1137. <p>· Video was shot on a <a href="http://www.amazon.com/gp/product/B002VA57XC">GoPro HD</a>. Last year I tried a ContourHD, but the picture wasnt quite as good and the sound was terrible the GoPro does a better job dealing with the wind noise.</p>
  1138. <p>· The data (speedo, Tach, Throttle position) was collected using a <a href="http://www.amazon.com/PLX-Devices-2340-KIWI-Wifi/dp/B002ICSOTC">PLX 2340 KIWI Wifi</a>. This device interfaces with the OBD-II port of your car (also used by mechanics to read diagnostics), and transmits several different types of metrics in real time over Wi-Fi at with an observed sample rate of about 3 samples / second.</p>
  1139. <p>· The data was then recorded using <a href="http://www.devtoaster.com/products/rev/">Rev by DevToaster</a> for iPhone. This app is compatible with the PLX, so it can collect data being transmitted by your car. It also adds accelerometer data. Theres GPS too, but the iPhones GPS is completely unusable for track purposes. The sampling frequency is too low, and it does some very funky interpolation which in the end renders the GPS data useless. For example, heres a simple plot (graphed using F#) of one of the runs:</p>
  1140. <p><a href="http://blog.efvincent.com/wp-content/uploads/2010/08/GPSPlot10081401.png"><img src="http://blog.efvincent.com/wp-content/uploads/2010/08/GPSPlot10081401_thumb.png" alt="GPS Plot 100814-01" /></a></p>
  1141. <p>· The data is then exported from the phone as an emailed comma separated value file (.csv).</p>
  1142. <p>· A small program I wrote in F# reads the file and transforms the timestamps in to frame numbers (29.97 frames/second), and the data into either rotational data (for the analog gauges) or simple integers (for the digital gauges).</p>
  1143. <p>· That data can then be imported into Adobe After Effects. Images of the gauges (drawn from scratch in Adobe Illustrator) are animated into a video overlay using the PLX/Rev data.</p>
  1144. <p>· Adobe Premiere then takes the gauges and overlays them on top of the video from the track. Theres some fiddling involved to get the gauge data and video in sync. Premiere then renders the video (20 minutes took 6 hours not sure if Im doing that right).</p>
  1145. <p>· That rendered video is HD and is pretty big, so I used Microsoft Expression Encoder (Adobe has an encoder too) to re-encode the video into a smaller MP4 format that Vimeo wanted for uploading.</p>
  1146. ]]></content>
  1147. </entry>
  1148. <entry>
  1149. <title type="html"><![CDATA[Combinators in C#]]></title>
  1150. <link href="http://efvincent.github.io/blog/2010/05/03/combinators-in-c/"/>
  1151. <updated>2010-05-03T01:15:43-04:00</updated>
  1152. <id>http://efvincent.github.io/blog/2010/05/03/combinators-in-c</id>
  1153. <content type="html"><![CDATA[<p>As C# has evolved it has acquired more and more of what some people refer to has functional programming features and constructs. One such concept is the idea that a function is a first class value. This is a fancy way of saying that functions are values that can be passed to and returned from other functions. A function that operates on other functions is called a high-order function.</p>
  1154. <!-- more -->
  1155. <p>Combinators are high order functions that compose, combine, or otherwise modify functions in useful and interesting ways. These types of operations are not typically seen in C#, but expanding your problem solving toolkit to include these concepts is not only fun and interesting, but can result in new, efficient, robust solutions.</p>
  1156. <h2 id="the-timer">The Timer</h2>
  1157. <p>Imagine youve got a method that you want to put a stopwatch on. For example, in the following code, you need to see how long its taking each download to complete, for debugging information.</p>
  1158. <div><table class="CodeRay"><tr>
  1159. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1160. <a href="#n2" name="n2">2</a>
  1161. <a href="#n3" name="n3">3</a>
  1162. <a href="#n4" name="n4">4</a>
  1163. <a href="#n5" name="n5">5</a>
  1164. <a href="#n6" name="n6">6</a>
  1165. <a href="#n7" name="n7">7</a>
  1166. <a href="#n8" name="n8">8</a>
  1167. <a href="#n9" name="n9">9</a>
  1168. <strong><a href="#n10" name="n10">10</a></strong>
  1169. <a href="#n11" name="n11">11</a>
  1170. <a href="#n12" name="n12">12</a>
  1171. <a href="#n13" name="n13">13</a>
  1172. <a href="#n14" name="n14">14</a>
  1173. <a href="#n15" name="n15">15</a>
  1174. <a href="#n16" name="n16">16</a>
  1175. <a href="#n17" name="n17">17</a>
  1176. <a href="#n18" name="n18">18</a>
  1177. <a href="#n19" name="n19">19</a>
  1178. <strong><a href="#n20" name="n20">20</a></strong>
  1179. <a href="#n21" name="n21">21</a>
  1180. <a href="#n22" name="n22">22</a>
  1181. <a href="#n23" name="n23">23</a>
  1182. <a href="#n24" name="n24">24</a>
  1183. <a href="#n25" name="n25">25</a>
  1184. </pre></td>
  1185. <td class="code"><pre><span class="type">class</span> <span class="class">Program</span> {
  1186. <span class="directive">static</span> string url;
  1187. <span class="directive">static</span> <span class="type">void</span> Main(string<span class="type">[]</span> args) {
  1188. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://microsoft.com</span><span class="delimiter">&quot;</span></span>;
  1189. RetrieveFromWeb();
  1190. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://amazon.com</span><span class="delimiter">&quot;</span></span>;
  1191. RetrieveFromWeb();
  1192. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://dpreview.com</span><span class="delimiter">&quot;</span></span>;
  1193. RetrieveFromWeb();
  1194. Console.Write(<span class="string"><span class="delimiter">&quot;</span><span class="content">Press any key...</span><span class="delimiter">&quot;</span></span>);
  1195. Console.ReadKey(<span class="predefined-constant">true</span>);
  1196. }
  1197. <span class="directive">static</span> <span class="type">void</span> RetrieveFromWeb() {
  1198. <span class="predefined-type">System</span>.Net.WebClient wc = <span class="keyword">new</span> <span class="predefined-type">System</span>.Net.WebClient();
  1199. var s = wc.DownloadString(url);
  1200. Console.WriteLine(<span class="string"><span class="delimiter">&quot;</span><span class="content">URL: {0} - string length is {1}</span><span class="delimiter">&quot;</span></span>, url, s.Length);
  1201. }
  1202. }
  1203. </pre></td>
  1204. </tr></table>
  1205. </div>
  1206. <p>An ugly solution would be to do this.</p>
  1207. <div><table class="CodeRay"><tr>
  1208. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1209. <a href="#n2" name="n2">2</a>
  1210. <a href="#n3" name="n3">3</a>
  1211. <a href="#n4" name="n4">4</a>
  1212. <a href="#n5" name="n5">5</a>
  1213. <a href="#n6" name="n6">6</a>
  1214. <a href="#n7" name="n7">7</a>
  1215. <a href="#n8" name="n8">8</a>
  1216. <a href="#n9" name="n9">9</a>
  1217. <strong><a href="#n10" name="n10">10</a></strong>
  1218. <a href="#n11" name="n11">11</a>
  1219. <a href="#n12" name="n12">12</a>
  1220. <a href="#n13" name="n13">13</a>
  1221. <a href="#n14" name="n14">14</a>
  1222. <a href="#n15" name="n15">15</a>
  1223. <a href="#n16" name="n16">16</a>
  1224. <a href="#n17" name="n17">17</a>
  1225. <a href="#n18" name="n18">18</a>
  1226. <a href="#n19" name="n19">19</a>
  1227. <strong><a href="#n20" name="n20">20</a></strong>
  1228. <a href="#n21" name="n21">21</a>
  1229. </pre></td>
  1230. <td class="code"><pre><span class="directive">static</span> <span class="type">void</span> Main(string<span class="type">[]</span> args) {
  1231. var sw = <span class="keyword">new</span> <span class="predefined-type">System</span>.Diagnostics.Stopwatch();
  1232. sw.Start();
  1233. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://microsoft.com</span><span class="delimiter">&quot;</span></span>;
  1234. RetrieveFromWeb();
  1235. Console.WriteLine(<span class="string"><span class="delimiter">&quot;</span><span class="content">{0:#,##0}ms</span><span class="delimiter">&quot;</span></span>, sw.ElapsedMilliseconds);
  1236. sw.Restart();
  1237. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://amazon.com</span><span class="delimiter">&quot;</span></span>;
  1238. RetrieveFromWeb();
  1239. Console.WriteLine(<span class="string"><span class="delimiter">&quot;</span><span class="content">{0:#,##0}ms</span><span class="delimiter">&quot;</span></span>, sw.ElapsedMilliseconds);
  1240. sw.Restart();
  1241. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://dpreview.com</span><span class="delimiter">&quot;</span></span>;
  1242. RetrieveFromWeb();
  1243. Console.WriteLine(<span class="string"><span class="delimiter">&quot;</span><span class="content">{0:#,##0}ms</span><span class="delimiter">&quot;</span></span>, sw.ElapsedMilliseconds);
  1244. Console.Write(<span class="string"><span class="delimiter">&quot;</span><span class="content">Press any key...</span><span class="delimiter">&quot;</span></span>);
  1245. Console.ReadKey(<span class="predefined-constant">true</span>);
  1246. }
  1247. </pre></td>
  1248. </tr></table>
  1249. </div>
  1250. <p>Try not to get physically ill. You and I both know theres plenty of code running around in the wild that looks a lot like this. Red flags you see repeated code starting, stopping, printing the time. Should we go into the RetrieveFromWeb() method and modify it for timing? Lets not. Lets try this instead. Step one, lets define a variable for the method were calling. Leaving out the timing code for now, we make this change:</p>
  1251. <div><table class="CodeRay"><tr>
  1252. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1253. <a href="#n2" name="n2">2</a>
  1254. <a href="#n3" name="n3">3</a>
  1255. <a href="#n4" name="n4">4</a>
  1256. <a href="#n5" name="n5">5</a>
  1257. <a href="#n6" name="n6">6</a>
  1258. <a href="#n7" name="n7">7</a>
  1259. <a href="#n8" name="n8">8</a>
  1260. <a href="#n9" name="n9">9</a>
  1261. <strong><a href="#n10" name="n10">10</a></strong>
  1262. <a href="#n11" name="n11">11</a>
  1263. <a href="#n12" name="n12">12</a>
  1264. <a href="#n13" name="n13">13</a>
  1265. <a href="#n14" name="n14">14</a>
  1266. </pre></td>
  1267. <td class="code"><pre><span class="directive">static</span> <span class="type">void</span> Main(string<span class="type">[]</span> args) {&lt;/p&gt;&lt;p&gt; <span class="comment">// Create a delegate, set it to the method of interest&lt;/p&gt;&lt;p&gt; Action retrieveFromWeb = RetrieveFromWeb;</span>
  1268. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://microsoft.com</span><span class="delimiter">&quot;</span></span>;
  1269. retrieveFromWeb();
  1270. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://amazon.com</span><span class="delimiter">&quot;</span></span>;
  1271. retrieveFromWeb();
  1272. url = <span class="string"><span class="delimiter">&quot;</span><span class="content">http://dpreview.com</span><span class="delimiter">&quot;</span></span>;
  1273. retrieveFromWeb();
  1274. Console.Write(<span class="string"><span class="delimiter">&quot;</span><span class="content">Press any key...</span><span class="delimiter">&quot;</span></span>);
  1275. Console.ReadKey(<span class="predefined-constant">true</span>);
  1276. }
  1277. </pre></td>
  1278. </tr></table>
  1279. </div>
  1280. <p>Ive added a local variable of type <em>Action, _and set it equal to the call to the method _RetrieveFromWeb(),</em> and now were calling that method indirectly. It has the same exact effect, the method gets called three times. Only weve added a layer of indirection. We do this all the time in OO programming; for example, you might have a Person object, but rather than coding directly to that object, you create an IPerson interface, and code to that, opening up the possibility of mocking the object, decorating it, etc. Similar thing here. Rather than binding the call sites directly to the method, were binding to a variable that points to the method.</p>
  1281. <p>Were doing this because now weve got a value that can be altered or augmented to add additional functionality. This is where a combinator comes in. This is a simple timer combinator:</p>
  1282. <div><table class="CodeRay"><tr>
  1283. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1284. <a href="#n2" name="n2">2</a>
  1285. <a href="#n3" name="n3">3</a>
  1286. <a href="#n4" name="n4">4</a>
  1287. <a href="#n5" name="n5">5</a>
  1288. <a href="#n6" name="n6">6</a>
  1289. <a href="#n7" name="n7">7</a>
  1290. <a href="#n8" name="n8">8</a>
  1291. <a href="#n9" name="n9">9</a>
  1292. <strong><a href="#n10" name="n10">10</a></strong>
  1293. <a href="#n11" name="n11">11</a>
  1294. <a href="#n12" name="n12">12</a>
  1295. <a href="#n13" name="n13">13</a>
  1296. <a href="#n14" name="n14">14</a>
  1297. </pre></td>
  1298. <td class="code"><pre><span class="type">class</span> <span class="class">Combinators</span> {
  1299. <span class="directive">public</span> <span class="directive">static</span> <span class="predefined-type">Action</span> <span class="predefined-type">Time</span>(<span class="predefined-type">Action</span> a) {
  1300. <span class="keyword">return</span> () =&gt; {
  1301. var sw = <span class="keyword">new</span> <span class="predefined-type">System</span>.Diagnostics.Stopwatch();
  1302. sw.Start();
  1303. <span class="keyword">try</span> {
  1304. a();
  1305. } <span class="keyword">finally</span> {
  1306. Console.WriteLine(<span class="string"><span class="delimiter">&quot;</span><span class="content">{0:#,##0}ms</span><span class="delimiter">&quot;</span></span>, sw.ElapsedMilliseconds);
  1307. }
  1308. };
  1309. }
  1310. }
  1311. </pre></td>
  1312. </tr></table>
  1313. </div>
  1314. <p>This combinator takes an <em>Action</em> and returns a new action (aka a new function), that has timing included. At line 8 the parameter action is being called, the timing is whats added. The only change we have to make to the main method is where the delegate is being defined:</p>
  1315. <div><table class="CodeRay"><tr>
  1316. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1317. </pre></td>
  1318. <td class="code"><pre><span class="predefined-type">Action</span> retrieveFromWeb = Combinators.Time(RetrieveFromWeb);&lt;/p&gt;
  1319. </pre></td>
  1320. </tr></table>
  1321. </div>
  1322. <p>The rest of the method stays the same, but now, theres timing added. This is a super-simple, contrived example, but you should be starting to see whats possible. Lets take this a step further. Heres an example simulating retrieval of information from the database:</p>
  1323. <div><table class="CodeRay"><tr>
  1324. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1325. <a href="#n2" name="n2">2</a>
  1326. <a href="#n3" name="n3">3</a>
  1327. <a href="#n4" name="n4">4</a>
  1328. <a href="#n5" name="n5">5</a>
  1329. <a href="#n6" name="n6">6</a>
  1330. <a href="#n7" name="n7">7</a>
  1331. <a href="#n8" name="n8">8</a>
  1332. <a href="#n9" name="n9">9</a>
  1333. <strong><a href="#n10" name="n10">10</a></strong>
  1334. <a href="#n11" name="n11">11</a>
  1335. <a href="#n12" name="n12">12</a>
  1336. <a href="#n13" name="n13">13</a>
  1337. <a href="#n14" name="n14">14</a>
  1338. <a href="#n15" name="n15">15</a>
  1339. <a href="#n16" name="n16">16</a>
  1340. <a href="#n17" name="n17">17</a>
  1341. <a href="#n18" name="n18">18</a>
  1342. <a href="#n19" name="n19">19</a>
  1343. <strong><a href="#n20" name="n20">20</a></strong>
  1344. <a href="#n21" name="n21">21</a>
  1345. <a href="#n22" name="n22">22</a>
  1346. <a href="#n23" name="n23">23</a>
  1347. </pre></td>
  1348. <td class="code"><pre><span class="directive">static</span> <span class="type">void</span> Main(string<span class="type">[]</span> args) {
  1349. Func&lt;string, Guid&gt; lookupUser = LookupUser;
  1350. var emails = <span class="keyword">new</span><span class="type">[]</span> {
  1351. <span class="string"><span class="delimiter">&quot;</span><span class="content">eric@work.com</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">joel@office.com</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">cole@school.com</span><span class="delimiter">&quot;</span></span>,
  1352. <span class="string"><span class="delimiter">&quot;</span><span class="content">karin@job.com</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">haley@home.com</span><span class="delimiter">&quot;</span></span> };
  1353. foreach (var em in emails) {
  1354. var id = lookupUser(em);
  1355. Console.WriteLine(<span class="string"><span class="delimiter">&quot;</span><span class="content">user {0} id = {1}</span><span class="delimiter">&quot;</span></span>, em, id);
  1356. }
  1357. Console.Write(<span class="string"><span class="delimiter">&quot;</span><span class="content">Press any key...</span><span class="delimiter">&quot;</span></span>);
  1358. Console.ReadKey(<span class="predefined-constant">true</span>);
  1359. }
  1360. <span class="directive">static</span> Guid LookupUser(string email) {
  1361. <span class="comment">// Fake looking up a user in the database</span>
  1362. var rnd = <span class="keyword">new</span> <span class="predefined-type">Random</span>(<span class="predefined-type">System</span>.DateTime.Now.Millisecond);
  1363. <span class="predefined-type">Thread</span>.Sleep(rnd.Next(<span class="integer">250</span>, <span class="integer">2500</span>));
  1364. <span class="keyword">return</span> Guid.NewGuid();
  1365. }
  1366. </pre></td>
  1367. </tr></table>
  1368. </div>
  1369. <p>Memoization is the idea that a function can remember the results for given parameters. Its like caching, but the term is specific to caching function results based on input. Heres a simple Memoization combinator for C#:</p>
  1370. <div><table class="CodeRay"><tr>
  1371. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1372. <a href="#n2" name="n2">2</a>
  1373. <a href="#n3" name="n3">3</a>
  1374. <a href="#n4" name="n4">4</a>
  1375. <a href="#n5" name="n5">5</a>
  1376. <a href="#n6" name="n6">6</a>
  1377. <a href="#n7" name="n7">7</a>
  1378. <a href="#n8" name="n8">8</a>
  1379. <a href="#n9" name="n9">9</a>
  1380. <strong><a href="#n10" name="n10">10</a></strong>
  1381. <a href="#n11" name="n11">11</a>
  1382. </pre></td>
  1383. <td class="code"><pre><span class="directive">public</span> <span class="directive">static</span> Func&lt;A, B&gt; Memoize&lt;A, B&gt;(Func&lt;A, B&gt; fn) {
  1384. var dict = <span class="keyword">new</span> <span class="predefined-type">Dictionary</span>&lt;A, B&gt;();
  1385. <span class="keyword">return</span> a =&gt; {
  1386. B b = <span class="keyword">default</span>(B);
  1387. <span class="keyword">if</span> (!dict.TryGetValue(a, out b)) {
  1388. b = fn(a);
  1389. dict.Add(a, b);
  1390. }
  1391. <span class="keyword">return</span> b;
  1392. };
  1393. }
  1394. </pre></td>
  1395. </tr></table>
  1396. </div>
  1397. <p>Its simple, but it demonstrates some very useful and interesting functional programming concepts. First, its takes and returns Func&lt;A,B&gt;. This is a delegate with a parameter of type A that returns a type B. This will work for effectively any method with that signature. Next point of interest, a dictionary is created, then the lambda is created and returned. The lambda refers to the dictionary defined outside the lambda. It is said that the dictionary is <em>captured</em> in a <em>closure</em>. Its not important that you remember the terms, but look over the code and see if the concept is clicking for you. This function will return (effectively) a function, the dictionary is <em>captured</em> by that function. Even when the call to Memoize() goes out of scope, the dict variable will still exist in the returned function. Enough talk. We modify the main program just slightly:</p>
  1398. <div><table class="CodeRay"><tr>
  1399. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1400. </pre></td>
  1401. <td class="code"><pre>Func&lt;string, Guid&gt; lookupUser = Combinators.Memoize(LookupUser);
  1402. </pre></td>
  1403. </tr></table>
  1404. </div>
  1405. <p>The Memoize function will create a new function, one that caches results of the LookupUser function <em>automatically.</em> Nothing else has to change in the program to take advantage of this. Want to be sure that its actually working? Time it! The non-memoized LookupUser() has a built in Thread.Sleep(2500), and so takes 2.5sec * number of lookups to run. The memoized version will run almost instantly, so we can prove the memoizer is working by timing. The time combinator we created earlier was for timing Actions. Ive created a overload of the time combinator that has the signature we need - Func&lt;A,B&gt;:</p>
  1406. <div><table class="CodeRay"><tr>
  1407. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1408. <a href="#n2" name="n2">2</a>
  1409. <a href="#n3" name="n3">3</a>
  1410. <a href="#n4" name="n4">4</a>
  1411. <a href="#n5" name="n5">5</a>
  1412. <a href="#n6" name="n6">6</a>
  1413. <a href="#n7" name="n7">7</a>
  1414. <a href="#n8" name="n8">8</a>
  1415. <a href="#n9" name="n9">9</a>
  1416. <strong><a href="#n10" name="n10">10</a></strong>
  1417. <a href="#n11" name="n11">11</a>
  1418. </pre></td>
  1419. <td class="code"><pre><span class="directive">public</span> <span class="directive">static</span> Func&lt;A, B&gt; <span class="predefined-type">Time</span>&lt;A, B&gt;(Func&lt;A, B&gt; fn) {
  1420. <span class="keyword">return</span> a =&gt; {
  1421. var sw = <span class="keyword">new</span> <span class="predefined-type">System</span>.Diagnostics.Stopwatch();
  1422. sw.Start();
  1423. <span class="keyword">try</span> {
  1424. <span class="keyword">return</span> fn(a);
  1425. } <span class="keyword">finally</span> {
  1426. Console.WriteLine(<span class="string"><span class="delimiter">&quot;</span><span class="content">{0:#,##0}ms</span><span class="delimiter">&quot;</span></span>, sw.ElapsedMilliseconds);
  1427. }
  1428. };
  1429. }
  1430. </pre></td>
  1431. </tr></table>
  1432. </div>
  1433. <p>and added it to the definition of lookUpUser in the main function</p>
  1434. <div><table class="CodeRay"><tr>
  1435. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1436. <a href="#n2" name="n2">2</a>
  1437. <a href="#n3" name="n3">3</a>
  1438. </pre></td>
  1439. <td class="code"><pre>Func&lt;string, Guid&gt; lookupUser =
  1440. Combinators.Time(
  1441. Combinators.Memoize&lt;string,Guid&gt;(LookupUser));&lt;/p&gt;
  1442. </pre></td>
  1443. </tr></table>
  1444. </div>
  1445. <p>Again without modifying the main code, weve augmented the method. Throw in some duplicate email addresses to test it out. The real power of these techniques becomes more evident the more you use them. Functional programming developers have been using these are similar techniques for years, and now with the added ability and flexibility of C#, we can employ these patters as well.</p>
  1446. ]]></content>
  1447. </entry>
  1448. <entry>
  1449. <title type="html"><![CDATA[Parsing Json Using F#]]></title>
  1450. <link href="http://efvincent.github.io/blog/2010/04/27/parsing-json-using-f/"/>
  1451. <updated>2010-04-27T14:29:49-04:00</updated>
  1452. <id>http://efvincent.github.io/blog/2010/04/27/parsing-json-using-f</id>
  1453. <content type="html"><![CDATA[<p>I was in one of those curious moods the other day, and decided to check out the API for the service behind my RSS reader, <a href="http://www.newsgator.com/Individuals/FeedDemon/Default.aspx">FeedDemon</a>. I like this reader because it keeps my subscriptions and read / unread data synchronized across machines and my iPhone via an app called <a href="http://netnewswireapp.com/iphone/">NetNewsWire</a>.</p>
  1454. <!-- more -->
  1455. <p>Well it ends up that Google has gobbled up the service and its now Google Reader. Fair enough. It means you can also read your RSS feeds on the web at the Google reader site. Whatevs. It also turns out that Google has not publicized the API for that service yet. Yuck. But there are a couple of people out there (like <a href="http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI">here</a> and <a href="http://blog.martindoms.com/2009/08/15/using-the-google-reader-api-part-1/">here</a>) who have picked it apart using fiddler or some such thing.</p>
  1456. <p>Well to put this meandering story to an end, I was playing with the API and it seems that some of the methods only return JSON. Others return XML, and others still are switchable. Messy. No wonder its not public yet. So that brings me to the point of this post Parsing Json using F#.</p>
  1457. <h3 id="why-f">Why F#?</h3>
  1458. <p>Ive avoided posting about F# to date, even though I love playing with it; I feel that posts about C# are more relevant. People are using F#, but Ive never had the chance to use it on the job, and I dont know anyone personally who has either. But since its <em>mainstream</em> now, what the heck. Plus parsing is one of those tasks thats right up F#s alley. If you havent worked with a functional language since college (or ever), give it a whirl. Its refreshingly different from pure, straight, intensely object oriented thinking.</p>
  1459. <h3 id="json-briefly">Json, Briefly</h3>
  1460. <p>Most everyone knows what Json is by now. Its just a tad more horrifying in real life as the supernatural killer from the Friday the 13th movies with whom it homophonetically shares its name. Its a text format for representing data that can be evaluated in that wonderfully fast and lose language of the web, JavaScript, resulting in actual JavaScript objects. Read about it from the <a href="http://json.org">experts here</a>. Heres an example of some awesome <a href="http://json.org">Json</a>:</p>
  1461. <div><table class="CodeRay"><tr>
  1462. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1463. <a href="#n2" name="n2">2</a>
  1464. <a href="#n3" name="n3">3</a>
  1465. <a href="#n4" name="n4">4</a>
  1466. <a href="#n5" name="n5">5</a>
  1467. <a href="#n6" name="n6">6</a>
  1468. <a href="#n7" name="n7">7</a>
  1469. <a href="#n8" name="n8">8</a>
  1470. <a href="#n9" name="n9">9</a>
  1471. <strong><a href="#n10" name="n10">10</a></strong>
  1472. <a href="#n11" name="n11">11</a>
  1473. <a href="#n12" name="n12">12</a>
  1474. <a href="#n13" name="n13">13</a>
  1475. <a href="#n14" name="n14">14</a>
  1476. <a href="#n15" name="n15">15</a>
  1477. <a href="#n16" name="n16">16</a>
  1478. <a href="#n17" name="n17">17</a>
  1479. <a href="#n18" name="n18">18</a>
  1480. <a href="#n19" name="n19">19</a>
  1481. <strong><a href="#n20" name="n20">20</a></strong>
  1482. <a href="#n21" name="n21">21</a>
  1483. <a href="#n22" name="n22">22</a>
  1484. </pre></td>
  1485. <td class="code"><pre>{
  1486. <span class="key"><span class="delimiter">&quot;</span><span class="content">glossary</span><span class="delimiter">&quot;</span></span>: {
  1487. <span class="key"><span class="delimiter">&quot;</span><span class="content">title</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">example glossary</span><span class="delimiter">&quot;</span></span>,
  1488. <span class="key"><span class="delimiter">&quot;</span><span class="content">GlossDiv</span><span class="delimiter">&quot;</span></span>: {
  1489. <span class="key"><span class="delimiter">&quot;</span><span class="content">title</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">S</span><span class="delimiter">&quot;</span></span>,
  1490. <span class="key"><span class="delimiter">&quot;</span><span class="content">GlossList</span><span class="delimiter">&quot;</span></span>: {
  1491. <span class="key"><span class="delimiter">&quot;</span><span class="content">GlossEntry</span><span class="delimiter">&quot;</span></span>: {
  1492. <span class="key"><span class="delimiter">&quot;</span><span class="content">ID</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">SGML</span><span class="delimiter">&quot;</span></span>,
  1493. <span class="key"><span class="delimiter">&quot;</span><span class="content">SortAs</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">SGML</span><span class="delimiter">&quot;</span></span>,
  1494. <span class="key"><span class="delimiter">&quot;</span><span class="content">GlossTerm</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">Standard Generalized Markup Language</span><span class="delimiter">&quot;</span></span>,
  1495. <span class="key"><span class="delimiter">&quot;</span><span class="content">Acronym</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">SGML</span><span class="delimiter">&quot;</span></span>,
  1496. <span class="key"><span class="delimiter">&quot;</span><span class="content">Abbrev</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">ISO 8879:1986</span><span class="delimiter">&quot;</span></span>,
  1497. <span class="key"><span class="delimiter">&quot;</span><span class="content">GlossDef</span><span class="delimiter">&quot;</span></span>: {
  1498. <span class="key"><span class="delimiter">&quot;</span><span class="content">para</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">A meta-markup language, used to create markup languages such as DocBook.</span><span class="delimiter">&quot;</span></span>,
  1499. <span class="key"><span class="delimiter">&quot;</span><span class="content">GlossSeeAlso</span><span class="delimiter">&quot;</span></span>: [<span class="string"><span class="delimiter">&quot;</span><span class="content">GML</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">XML</span><span class="delimiter">&quot;</span></span>]
  1500. },
  1501. <span class="key"><span class="delimiter">&quot;</span><span class="content">GlossSee</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">markup</span><span class="delimiter">&quot;</span></span>
  1502. }
  1503. }
  1504. }
  1505. }
  1506. }
  1507. </pre></td>
  1508. </tr></table>
  1509. </div>
  1510. <h3 id="the-tokenizer">The Tokenizer</h3>
  1511. <p>Im no parsing / compiler / language expert, but I do know that tokenizing is the first step. This is when we run through the string and create tokens; identifying the open and close braces, the name value pairs, etc.</p>
  1512. <p>First thing we want to look at is the Token type, which is a discriminated union. This type defines the <em>logical</em> things that are in the Json string. For example, an open quote, some characters, and a close quote is a string.</p>
  1513. <div><table class="CodeRay"><tr>
  1514. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1515. <a href="#n2" name="n2">2</a>
  1516. <a href="#n3" name="n3">3</a>
  1517. <a href="#n4" name="n4">4</a>
  1518. <a href="#n5" name="n5">5</a>
  1519. <a href="#n6" name="n6">6</a>
  1520. </pre></td>
  1521. <td class="code"><pre>type <span class="constant">Token</span> =
  1522. | <span class="constant">OpenBracket</span> | <span class="constant">CloseBracket</span>
  1523. | <span class="constant">OpenArray</span> | <span class="constant">CloseArray</span>
  1524. | <span class="constant">Colon</span> | <span class="constant">Comma</span>
  1525. | <span class="constant">String</span> of string
  1526. | <span class="constant">Number</span> of string
  1527. </pre></td>
  1528. </tr></table>
  1529. </div>
  1530. <p>For this simple parser, the tokens are as above, open and close bracket and square bracket (aka array), colon, comma, numbers, and strings. This is a good reason to start with Json, its painfully simple. The tokenize function below turns the string into a list of tokens.</p>
  1531. <div><table class="CodeRay"><tr>
  1532. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1533. <a href="#n2" name="n2">2</a>
  1534. <a href="#n3" name="n3">3</a>
  1535. <a href="#n4" name="n4">4</a>
  1536. <a href="#n5" name="n5">5</a>
  1537. <a href="#n6" name="n6">6</a>
  1538. <a href="#n7" name="n7">7</a>
  1539. <a href="#n8" name="n8">8</a>
  1540. <a href="#n9" name="n9">9</a>
  1541. <strong><a href="#n10" name="n10">10</a></strong>
  1542. <a href="#n11" name="n11">11</a>
  1543. <a href="#n12" name="n12">12</a>
  1544. <a href="#n13" name="n13">13</a>
  1545. <a href="#n14" name="n14">14</a>
  1546. <a href="#n15" name="n15">15</a>
  1547. <a href="#n16" name="n16">16</a>
  1548. <a href="#n17" name="n17">17</a>
  1549. <a href="#n18" name="n18">18</a>
  1550. <a href="#n19" name="n19">19</a>
  1551. <strong><a href="#n20" name="n20">20</a></strong>
  1552. <a href="#n21" name="n21">21</a>
  1553. <a href="#n22" name="n22">22</a>
  1554. <a href="#n23" name="n23">23</a>
  1555. <a href="#n24" name="n24">24</a>
  1556. <a href="#n25" name="n25">25</a>
  1557. <a href="#n26" name="n26">26</a>
  1558. <a href="#n27" name="n27">27</a>
  1559. <a href="#n28" name="n28">28</a>
  1560. <a href="#n29" name="n29">29</a>
  1561. <strong><a href="#n30" name="n30">30</a></strong>
  1562. <a href="#n31" name="n31">31</a>
  1563. <a href="#n32" name="n32">32</a>
  1564. <a href="#n33" name="n33">33</a>
  1565. <a href="#n34" name="n34">34</a>
  1566. <a href="#n35" name="n35">35</a>
  1567. <a href="#n36" name="n36">36</a>
  1568. <a href="#n37" name="n37">37</a>
  1569. <a href="#n38" name="n38">38</a>
  1570. <a href="#n39" name="n39">39</a>
  1571. <strong><a href="#n40" name="n40">40</a></strong>
  1572. </pre></td>
  1573. <td class="code"><pre>let tokenize source =
  1574. let rec parseString acc = function
  1575. | <span class="string"><span class="delimiter">'</span><span class="char">\\</span><span class="delimiter">'</span></span> :: <span class="string"><span class="delimiter">'</span><span class="content">&quot;</span><span class="delimiter">'</span></span> :: t -&gt; <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> escaped quote
  1576. parseString (acc + <span class="string"><span class="delimiter">&quot;</span><span class="char">\&quot;</span><span class="delimiter">&quot;</span></span>) t
  1577. | <span class="string"><span class="delimiter">'</span><span class="content">&quot;</span><span class="delimiter">'</span></span> :: t -&gt; <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> closing quote terminates
  1578. acc, t
  1579. | c :: t -&gt; <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> otherwise accumulate
  1580. parseString (acc + (c.ToString())) t
  1581. | _ -&gt; failwith <span class="string"><span class="delimiter">&quot;</span><span class="content">Malformed string.</span><span class="delimiter">&quot;</span></span>
  1582. let rec token acc = function
  1583. | (<span class="string"><span class="delimiter">'</span><span class="content">)</span><span class="delimiter">'</span></span> :: _) as t -&gt; acc, t <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> closing paren terminates
  1584. | (<span class="string"><span class="delimiter">'</span><span class="content">:</span><span class="delimiter">'</span></span> :: _) as t -&gt; acc, t <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> colon terminates
  1585. | (<span class="string"><span class="delimiter">'</span><span class="content">,</span><span class="delimiter">'</span></span> :: _) as t -&gt; acc, t <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> comma terminates
  1586. | w :: t <span class="keyword">when</span> <span class="constant">Char</span>.IsWhiteSpace(w) -&gt; acc, t <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> whitespace terminates
  1587. | [] -&gt; acc, [] /<span class="regexp"><span class="delimiter">/</span><span class="content"> end of list terminates
  1588. | c :: t -&gt; token (acc + (c.ToString())) t </span><span class="delimiter">/</span></span>/ otherwise accumulate chars
  1589. let rec tokenize<span class="string"><span class="delimiter">'</span><span class="content"> acc = function
  1590. | w :: t when Char.IsWhiteSpace(w) -&gt; tokenize</span><span class="delimiter">'</span></span> acc t <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> skip whitespace
  1591. | <span class="string"><span class="delimiter">'</span><span class="content">{</span><span class="delimiter">'</span></span> :: t -&gt; tokenize<span class="string"><span class="delimiter">'</span><span class="content"> (OpenBracket :: acc) t
  1592. | </span><span class="delimiter">'</span></span>}<span class="string"><span class="delimiter">'</span><span class="content"> :: t -&gt; tokenize</span><span class="delimiter">'</span></span> (<span class="constant">CloseBracket</span> :: acc) t
  1593. | <span class="string"><span class="delimiter">'</span><span class="content">[</span><span class="delimiter">'</span></span> :: t -&gt; tokenize<span class="string"><span class="delimiter">'</span><span class="content"> (OpenArray :: acc) t
  1594. | </span><span class="delimiter">'</span></span>]<span class="string"><span class="delimiter">'</span><span class="content"> :: t -&gt; tokenize</span><span class="delimiter">'</span></span> (<span class="constant">CloseArray</span> :: acc) t
  1595. | <span class="string"><span class="delimiter">'</span><span class="content">:</span><span class="delimiter">'</span></span> :: t -&gt; tokenize<span class="string"><span class="delimiter">'</span><span class="content"> (Colon :: acc) t
  1596. | </span><span class="delimiter">'</span></span>,<span class="string"><span class="delimiter">'</span><span class="content"> :: t -&gt; tokenize</span><span class="delimiter">'</span></span> (<span class="constant">Comma</span> :: acc) t
  1597. | <span class="string"><span class="delimiter">'</span><span class="content">&quot;</span><span class="delimiter">'</span></span> :: t -&gt; <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> start of string
  1598. let s, t<span class="string"><span class="delimiter">'</span><span class="content"> = parseString &quot;&quot; t
  1599. tokenize</span><span class="delimiter">'</span></span> (<span class="constant">Token</span>.String(s) :: acc) t<span class="string"><span class="delimiter">'</span><span class="content">
  1600. | </span><span class="delimiter">'</span></span>-<span class="string"><span class="delimiter">'</span><span class="content"> :: d :: t when Char.IsDigit(d) -&gt; // start of negative number
  1601. let n, t</span><span class="delimiter">'</span></span> = token (<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span> + d.ToString()) t
  1602. tokenize<span class="string"><span class="delimiter">'</span><span class="content"> (Token.Number(n) :: acc) t</span><span class="delimiter">'</span></span>
  1603. | <span class="string"><span class="delimiter">'</span><span class="content">+</span><span class="delimiter">'</span></span> :: d :: t | d :: t <span class="keyword">when</span> <span class="constant">Char</span>.IsDigit(d) -&gt; <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> start of positive number
  1604. let n, t<span class="string"><span class="delimiter">'</span><span class="content"> = token (d.ToString()) t
  1605. tokenize</span><span class="delimiter">'</span></span> (<span class="constant">Token</span>.Number(n) :: acc) t<span class="string"><span class="delimiter">'</span><span class="content">
  1606. | [] -&gt; List.rev acc // end of list terminates
  1607. | _ -&gt; failwith &quot;Tokinzation error&quot;
  1608. tokenize</span><span class="delimiter">'</span></span> [] source
  1609. </pre></td>
  1610. </tr></table>
  1611. </div>
  1612. <p>We dont have time for the full treatment of F#. If theres any interest, Ill post up some tutorials or at least links to some of the very many existing good tutorials out there already. For now, assume we have an understanding of the syntax, and the logic of tokenizing and parsing is what were after here.</p>
  1613. <p>One of the first things we see is that <em>tokenize</em> defines a few functions within the function. Great feature of F#, allowing definitions of inner functions; it allows the coder to partition logic without having function explosion.</p>
  1614. <p>The driving inner function is <em>tokenize</em>, whose signature is (Token list &gt; char list &gt; Token list). This means it takes a Token list and a char list, and returns a Token list. The first token list (acc) is an accumulator. This list is built up as the procedure calls itself recursively. This is a common pattern in functional languages, to thread an accumulator through recursive calls. The second parameter is a char list, or a list of characters from the source string.</p>
  1615. <p>We dont see the char list explicitly because of the use of the <em>function</em> keyword at like 20, this keyword means that the last parameter (the char list) is implicitly used in a match statement, the cases of which follow after the function keyword. The syntax would be equivalent to:</p>
  1616. <div><table class="CodeRay"><tr>
  1617. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1618. <a href="#n2" name="n2">2</a>
  1619. <a href="#n3" name="n3">3</a>
  1620. <a href="#n4" name="n4">4</a>
  1621. <a href="#n5" name="n5">5</a>
  1622. </pre></td>
  1623. <td class="code"><pre>let rec tokenize<span class="string"><span class="delimiter">'</span><span class="content"> acc sourceChars =
  1624. match sourceChars with
  1625. | w :: t when Char.IsWhiteSpace(w) -&gt; tokenize</span><span class="delimiter">'</span></span> acc t <span class="regexp"><span class="delimiter">/</span><span class="delimiter">/</span></span> skip whitespace
  1626. | <span class="string"><span class="delimiter">'</span><span class="content">{</span><span class="delimiter">'</span></span> :: t -&gt; tokenize<span class="string"><span class="delimiter">'</span><span class="content"> (OpenBracket :: acc) t
  1627. | </span><span class="delimiter">'</span></span>}<span class="string"><span class="delimiter">'</span><span class="content"> :: t -&gt; tokenize</span><span class="delimiter">'</span></span> (<span class="constant">CloseBracket</span> :: acc) t
  1628. </pre></td>
  1629. </tr></table>
  1630. </div>
  1631. <p>The idea that the sourceChars variable being passed immediately to the match..with construct is so common in F# that the <em>function</em> keyword is used as a contraction, allowing the elimination of what is an unnecessary variable. In many cases, this construct allows for a one line function definition.</p>
  1632. <p>Most of the cases in the block matches a character which in turn maps to a token, which is appended to the accumulator (acc : Token list), and passed to a recursive call of tokenize. This way the tokens are built up (in reverse order) as the string is traversed. This is seen in lines 22-27. Line 21 skips whitespace by calling tokenize without adding a token to the accumulator first.</p>
  1633. <p>Things are a bit more interesting at lines 28, 31, and 34. Line 28 detects the beginning of a string, and starts a new recursive thread with the <em>parseString</em> function, the signature of which is (string &gt; char list &gt; string * char list). So the accumulator is a string, the work is being done on a char list, to which is passed our source char list, and the return is a tuple of string * char list, which is our parsed string and the rest of the source char list. One (of Im sure <strong>many</strong>) optimizations that could be made is to use a mutable StringBuilder as the accumulator in parseString.</p>
  1634. <p>The <em>token</em> function on line 12 does a similar job for non-string literals (numbers in this case, there are no bools in Json).</p>
  1635. <p>Lastly, line 37 handles the case where we run out of source characters. The Token list weve been accumulating is backwards; weve been appending to the front of the list all this time. This is a common pattern. At the end, we return the reverse of the list. When the Json at the top is put through the tokenizer, we get this:</p>
  1636. <div><table class="CodeRay"><tr>
  1637. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1638. <a href="#n2" name="n2">2</a>
  1639. <a href="#n3" name="n3">3</a>
  1640. <a href="#n4" name="n4">4</a>
  1641. <a href="#n5" name="n5">5</a>
  1642. <a href="#n6" name="n6">6</a>
  1643. <a href="#n7" name="n7">7</a>
  1644. <a href="#n8" name="n8">8</a>
  1645. <a href="#n9" name="n9">9</a>
  1646. <strong><a href="#n10" name="n10">10</a></strong>
  1647. <a href="#n11" name="n11">11</a>
  1648. <a href="#n12" name="n12">12</a>
  1649. <a href="#n13" name="n13">13</a>
  1650. <a href="#n14" name="n14">14</a>
  1651. <a href="#n15" name="n15">15</a>
  1652. <a href="#n16" name="n16">16</a>
  1653. <a href="#n17" name="n17">17</a>
  1654. <a href="#n18" name="n18">18</a>
  1655. </pre></td>
  1656. <td class="code"><pre>&gt; let tk = tokenize source;;
  1657. val tk : <span class="constant">Token</span> list =
  1658. [<span class="constant">OpenBracket</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">glossary</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">OpenBracket</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">title</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>;
  1659. <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">example glossary</span><span class="delimiter">&quot;</span></span>; <span class="constant">Comma</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">GlossDiv</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">OpenBracket</span>;
  1660. <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">title</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">S</span><span class="delimiter">&quot;</span></span>; <span class="constant">Comma</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">GlossList</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>;
  1661. <span class="constant">OpenBracket</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">GlossEntry</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">OpenBracket</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">ID</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>;
  1662. <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">SGML</span><span class="delimiter">&quot;</span></span>; <span class="constant">Comma</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">SortAs</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">SGML</span><span class="delimiter">&quot;</span></span>; <span class="constant">Comma</span>;
  1663. <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">GlossTerm</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">Standard Generalized Markup Language</span><span class="delimiter">&quot;</span></span>;
  1664. <span class="constant">Comma</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">Acronym</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">SGML</span><span class="delimiter">&quot;</span></span>; <span class="constant">Comma</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">Abbrev</span><span class="delimiter">&quot;</span></span>;
  1665. <span class="constant">Colon</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">ISO 8879:1986</span><span class="delimiter">&quot;</span></span>; <span class="constant">Comma</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">GlossDef</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">OpenBracket</span>;
  1666. <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">para</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>;
  1667. <span class="constant">String</span>
  1668. <span class="string"><span class="delimiter">&quot;</span><span class="content">A meta-markup language, used to create markup languages such as DocBook.</span><span class="delimiter">&quot;</span></span>;
  1669. <span class="constant">Comma</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">GlossSeeAlso</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>; <span class="constant">OpenArray</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">GML</span><span class="delimiter">&quot;</span></span>; <span class="constant">Comma</span>;
  1670. <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">XML</span><span class="delimiter">&quot;</span></span>; <span class="constant">CloseArray</span>; <span class="constant">CloseBracket</span>; <span class="constant">Comma</span>; <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">GlossSee</span><span class="delimiter">&quot;</span></span>; <span class="constant">Colon</span>;
  1671. <span class="constant">String</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">markup</span><span class="delimiter">&quot;</span></span>; <span class="constant">CloseBracket</span>; <span class="constant">CloseBracket</span>; <span class="constant">CloseBracket</span>; <span class="constant">CloseBracket</span>;
  1672. <span class="constant">CloseBracket</span>]
  1673. </pre></td>
  1674. </tr></table>
  1675. </div>
  1676. <p>This list of tokens is an intermediate step. From here, we could go in several directions. For my purposes, I wanted to see it as XML. To get there, I created a parser that takes the token list and returns an XElement.</p>
  1677. <div><table class="CodeRay"><tr>
  1678. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1679. <a href="#n2" name="n2">2</a>
  1680. <a href="#n3" name="n3">3</a>
  1681. <a href="#n4" name="n4">4</a>
  1682. <a href="#n5" name="n5">5</a>
  1683. <a href="#n6" name="n6">6</a>
  1684. <a href="#n7" name="n7">7</a>
  1685. <a href="#n8" name="n8">8</a>
  1686. <a href="#n9" name="n9">9</a>
  1687. <strong><a href="#n10" name="n10">10</a></strong>
  1688. <a href="#n11" name="n11">11</a>
  1689. <a href="#n12" name="n12">12</a>
  1690. <a href="#n13" name="n13">13</a>
  1691. <a href="#n14" name="n14">14</a>
  1692. <a href="#n15" name="n15">15</a>
  1693. <a href="#n16" name="n16">16</a>
  1694. <a href="#n17" name="n17">17</a>
  1695. <a href="#n18" name="n18">18</a>
  1696. <a href="#n19" name="n19">19</a>
  1697. <strong><a href="#n20" name="n20">20</a></strong>
  1698. <a href="#n21" name="n21">21</a>
  1699. <a href="#n22" name="n22">22</a>
  1700. <a href="#n23" name="n23">23</a>
  1701. <a href="#n24" name="n24">24</a>
  1702. <a href="#n25" name="n25">25</a>
  1703. <a href="#n26" name="n26">26</a>
  1704. <a href="#n27" name="n27">27</a>
  1705. <a href="#n28" name="n28">28</a>
  1706. <a href="#n29" name="n29">29</a>
  1707. <strong><a href="#n30" name="n30">30</a></strong>
  1708. <a href="#n31" name="n31">31</a>
  1709. <a href="#n32" name="n32">32</a>
  1710. <a href="#n33" name="n33">33</a>
  1711. <a href="#n34" name="n34">34</a>
  1712. <a href="#n35" name="n35">35</a>
  1713. <a href="#n36" name="n36">36</a>
  1714. <a href="#n37" name="n37">37</a>
  1715. <a href="#n38" name="n38">38</a>
  1716. <a href="#n39" name="n39">39</a>
  1717. <strong><a href="#n40" name="n40">40</a></strong>
  1718. <a href="#n41" name="n41">41</a>
  1719. <a href="#n42" name="n42">42</a>
  1720. <a href="#n43" name="n43">43</a>
  1721. <a href="#n44" name="n44">44</a>
  1722. <a href="#n45" name="n45">45</a>
  1723. <a href="#n46" name="n46">46</a>
  1724. <a href="#n47" name="n47">47</a>
  1725. <a href="#n48" name="n48">48</a>
  1726. <a href="#n49" name="n49">49</a>
  1727. <strong><a href="#n50" name="n50">50</a></strong>
  1728. <a href="#n51" name="n51">51</a>
  1729. <a href="#n52" name="n52">52</a>
  1730. <a href="#n53" name="n53">53</a>
  1731. <a href="#n54" name="n54">54</a>
  1732. <a href="#n55" name="n55">55</a>
  1733. <a href="#n56" name="n56">56</a>
  1734. <a href="#n57" name="n57">57</a>
  1735. <a href="#n58" name="n58">58</a>
  1736. <a href="#n59" name="n59">59</a>
  1737. <strong><a href="#n60" name="n60">60</a></strong>
  1738. </pre></td>
  1739. <td class="code"><pre>let parseToXml source =
  1740. let map = function
  1741. | <span class="constant">Token</span>.Number(n) -&gt; n.ToString()
  1742. | <span class="constant">Token</span>.String(x) -&gt; x
  1743. | v -&gt; failwith <span class="string"><span class="delimiter">&quot;</span><span class="content">Syntax Error, unrecognized token in map()</span><span class="delimiter">&quot;</span></span>
  1744. let rec parseValue (<span class="key">acc</span>:<span class="constant">XElement</span>) = function
  1745. | <span class="constant">OpenBracket</span> :: t -&gt;
  1746. let newElement, t<span class="string"><span class="delimiter">'</span><span class="content"> = parseElement acc t
  1747. newElement, t</span><span class="delimiter">'</span></span>
  1748. | <span class="constant">OpenArray</span> :: t -&gt;
  1749. let name = acc.Name.LocalName
  1750. <span class="keyword">if</span> name.EndsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">ies</span><span class="delimiter">&quot;</span></span>) &amp;&amp; name.Length &gt; <span class="integer">3</span> <span class="keyword">then</span>
  1751. let childName = name.Substring(<span class="integer">0</span>, name.Length - <span class="integer">3</span>) + <span class="string"><span class="delimiter">&quot;</span><span class="content">y</span><span class="delimiter">&quot;</span></span>
  1752. let newListElement, t<span class="string"><span class="delimiter">'</span><span class="content"> = parseArray childName acc t
  1753. newListElement, t</span><span class="delimiter">'</span></span>
  1754. elif name.EndsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">s</span><span class="delimiter">&quot;</span></span>) &amp;&amp; name.Length &gt; <span class="integer">1</span> <span class="keyword">then</span>
  1755. let childName = name.Substring(<span class="integer">0</span>, name.Length - <span class="integer">1</span>)
  1756. let newListElement, t<span class="string"><span class="delimiter">'</span><span class="content"> = parseArray childName acc t
  1757. newListElement, t</span><span class="delimiter">'</span></span>
  1758. <span class="keyword">else</span>
  1759. let childName = acc.Name.LocalName
  1760. acc.Name &lt;- <span class="constant">XName</span>.Get(childName + <span class="string"><span class="delimiter">&quot;</span><span class="content">s</span><span class="delimiter">&quot;</span></span>)
  1761. let newListElement, t<span class="string"><span class="delimiter">'</span><span class="content"> = parseArray childName acc t
  1762. newListElement, t</span><span class="delimiter">'</span></span>
  1763. | h :: t -&gt;
  1764. acc.Value &lt;- map(h)
  1765. acc, t
  1766. | _ -&gt; failwith <span class="string"><span class="delimiter">&quot;</span><span class="content">bad value</span><span class="delimiter">&quot;</span></span>
  1767. <span class="keyword">and</span> parseArray name acc = function
  1768. | <span class="constant">Comma</span> :: t -&gt; parseArray name acc t
  1769. | <span class="constant">CloseArray</span> :: t -&gt; acc, t
  1770. | t -&gt;
  1771. let newElement = XElement(<span class="constant">XName</span>.Get(name))
  1772. let acc<span class="string"><span class="delimiter">'</span><span class="content">, t</span><span class="delimiter">'</span></span> = parseValue newElement t
  1773. acc.Add(acc<span class="string"><span class="delimiter">'</span><span class="content">)
  1774. parseArray name acc t</span><span class="delimiter">'</span></span>
  1775. <span class="keyword">and</span> parseElement (acc : <span class="constant">XElement</span>) = function
  1776. | <span class="constant">Comma</span> :: t -&gt;
  1777. parseElement acc t
  1778. | <span class="constant">Token</span>.String(n) :: <span class="constant">Colon</span> :: t -&gt;
  1779. let newElement = XElement(<span class="constant">XName</span>.Get(n))
  1780. let v, t<span class="string"><span class="delimiter">'</span><span class="content"> = parseValue newElement t
  1781. acc.Add(v)
  1782. parseElement acc t</span><span class="delimiter">'</span></span>
  1783. | <span class="constant">CloseBracket</span> :: t -&gt;
  1784. acc, t
  1785. | _ -&gt; failwith <span class="string"><span class="delimiter">&quot;</span><span class="content">Malformed JSON object</span><span class="delimiter">&quot;</span></span>
  1786. let root = XElement(<span class="constant">XName</span>.Get(<span class="string"><span class="delimiter">&quot;</span><span class="content">root</span><span class="delimiter">&quot;</span></span>))
  1787. let tokens = tokenize source
  1788. match tokens with
  1789. | <span class="constant">OpenBracket</span> :: t -&gt;
  1790. let result, t<span class="string"><span class="delimiter">'</span><span class="content"> = parseElement root t
  1791. result
  1792. | _ -&gt; failwith &quot;Json did not begin with an object&quot;
  1793. </span><span class="delimiter">'</span></span>
  1794. </pre></td>
  1795. </tr></table>
  1796. </div>
  1797. <p>There is still syntax checking happening in the parse step. The tokenizer would have found illegal tokens, but the parse function will find illegal Json structure. It works in a similar way to the tokenizer, except instead of a raw stream of characters, weve got a stream of tokens, which is examined one by one and passed to a set of recursive functions which accumulates the XML, in this case as an XElement.</p>
  1798. <p>parseToXml defines inner functions <em>map</em>, <em>parseValue</em>, <em>parseArray</em>, and <em>parseElement.</em> It then gets to work by creating a root XElement, and getting the Token list. Json should start with an OpenBracket token. Anything else and we failwith an error (like C#s throw). When we find that OpenBracket, the recursion begins with a call to parseElement. The root XElement serves as the accumulator, and the Token list is the work to be done.</p>
  1799. <p>You should be able to see whats happening if youre somewhat comfortable with F#. The parseValue function does some extra work to wrap arrays in nodes where the singularity / plurality of the node makes it read a bit better (in English, most of the time). The other point of interest is that the accumulator is a mutable object in parseToXml, unlike the Token list was in tokenize. At lines 37 and 46, the newly created elements are added to the accumulator using the Add(XElement) method, which mutates the accumulator and keeps using it. This is a departure from purer functional techniques, but thats whats cool about F#, you can make those departures where it makes sense. In this case, leveraging the XElement class of the .NET framework was worth it. Consuming this class from C# is that much easier and more intuitive.</p>
  1800. <p>After all is said and done, this is the XML that is emitted.</p>
  1801. <div><table class="CodeRay"><tr>
  1802. <td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
  1803. <a href="#n2" name="n2">2</a>
  1804. <a href="#n3" name="n3">3</a>
  1805. <a href="#n4" name="n4">4</a>
  1806. <a href="#n5" name="n5">5</a>
  1807. <a href="#n6" name="n6">6</a>
  1808. <a href="#n7" name="n7">7</a>
  1809. <a href="#n8" name="n8">8</a>
  1810. <a href="#n9" name="n9">9</a>
  1811. <strong><a href="#n10" name="n10">10</a></strong>
  1812. <a href="#n11" name="n11">11</a>
  1813. <a href="#n12" name="n12">12</a>
  1814. <a href="#n13" name="n13">13</a>
  1815. <a href="#n14" name="n14">14</a>
  1816. <a href="#n15" name="n15">15</a>
  1817. <a href="#n16" name="n16">16</a>
  1818. <a href="#n17" name="n17">17</a>
  1819. <a href="#n18" name="n18">18</a>
  1820. <a href="#n19" name="n19">19</a>
  1821. <strong><a href="#n20" name="n20">20</a></strong>
  1822. <a href="#n21" name="n21">21</a>
  1823. <a href="#n22" name="n22">22</a>
  1824. <a href="#n23" name="n23">23</a>
  1825. <a href="#n24" name="n24">24</a>
  1826. <a href="#n25" name="n25">25</a>
  1827. </pre></td>
  1828. <td class="code"><pre><span class="tag">&lt;root&gt;</span>
  1829. <span class="tag">&lt;glossary&gt;</span>
  1830. <span class="tag">&lt;title&gt;</span>example glossary<span class="tag">&lt;/title&gt;</span>
  1831. <span class="tag">&lt;GlossDiv&gt;</span>
  1832. <span class="tag">&lt;title&gt;</span>S<span class="tag">&lt;/title&gt;</span>
  1833. <span class="tag">&lt;GlossList&gt;</span>
  1834. <span class="tag">&lt;GlossEntry&gt;</span>
  1835. <span class="tag">&lt;ID&gt;</span>SGML<span class="tag">&lt;/ID&gt;</span>
  1836. <span class="tag">&lt;SortAs&gt;</span>SGML<span class="tag">&lt;/SortAs&gt;</span>
  1837. <span class="tag">&lt;GlossTerm&gt;</span>Standard Generalized Markup Language<span class="tag">&lt;/GlossTerm&gt;</span>
  1838. <span class="tag">&lt;Acronym&gt;</span>SGML<span class="tag">&lt;/Acronym&gt;</span>
  1839. <span class="tag">&lt;Abbrev&gt;</span>ISO 8879:1986<span class="tag">&lt;/Abbrev&gt;</span>
  1840. <span class="tag">&lt;GlossDef&gt;</span>
  1841. <span class="tag">&lt;para&gt;</span>A meta-markup language, used to create markup languages such as DocBook.<span class="tag">&lt;/para&gt;</span>
  1842. <span class="tag">&lt;GlossSeeAlsos&gt;</span>
  1843. <span class="tag">&lt;GlossSeeAlso&gt;</span>GML<span class="tag">&lt;/GlossSeeAlso&gt;</span>
  1844. <span class="tag">&lt;GlossSeeAlso&gt;</span>XML<span class="tag">&lt;/GlossSeeAlso&gt;</span>
  1845. <span class="tag">&lt;/GlossSeeAlsos&gt;</span>
  1846. <span class="tag">&lt;/GlossDef&gt;</span>
  1847. <span class="tag">&lt;GlossSee&gt;</span>markup<span class="tag">&lt;/GlossSee&gt;</span>
  1848. <span class="tag">&lt;/GlossEntry&gt;</span>
  1849. <span class="tag">&lt;/GlossList&gt;</span>
  1850. <span class="tag">&lt;/GlossDiv&gt;</span>
  1851. <span class="tag">&lt;/glossary&gt;</span>
  1852. <span class="tag">&lt;/root&gt;</span>
  1853. </pre></td>
  1854. </tr></table>
  1855. </div>
  1856. <p>It isnt the most sophisticated, performant, or Im sure accurate Json parser out there. But it does the trick for my immediate need, is a good starting point for more sophistication later if needed, and was an excellent exercise in parsing and F#. It was fun to write, and hopefully it stimulates some curiosities. Let me know if youve got any questions or comments.</p>
  1857. ]]></content>
  1858. </entry>
  1859. <entry>
  1860. <title type="html"><![CDATA[Roll Your Own Language Constructs]]></title>
  1861. <link href="http://efvincent.github.io/blog/2010/02/02/roll-your-own-language-constructs/"/>
  1862. <updated>2010-02-02T23:24:18-05:00</updated>
  1863. <id>http://efvincent.github.io/blog/2010/02/02/roll-your-own-language-constructs</id>
  1864. <content type="html"><![CDATA[<p>My last couple of blog entries were ostensibly about lambda functions (<a href="http://blog.efvincent.com/c-nuts-and-bolts-lambdas/">last one</a>, <a href="http://blog.efvincent.com/c-nuts-and-bolts-lambdas02">one before</a>). With these ideas, or a general comfort level with lambdas and the Action&lt;&gt; and Func&lt;&gt; delegate types in the back of your mind, consider this.</p>
  1865. <!-- more -->
  1866. <p>I was working on a project where the development team was instructed to implement a retry logic into our data access layer. In other words, if we experience database connectivity problems, retry the operation as seems reasonable.</p>
  1867. <p>Heres some code were going to use as a basis for the conversation:</p>
  1868. <div class="bogus-wrapper"><notextile><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>
  1869. <span class="line-number">2</span>
  1870. <span class="line-number">3</span>
  1871. <span class="line-number">4</span>
  1872. <span class="line-number">5</span>
  1873. <span class="line-number">6</span>
  1874. <span class="line-number">7</span>
  1875. <span class="line-number">8</span>
  1876. <span class="line-number">9</span>
  1877. <span class="line-number">10</span>
  1878. <span class="line-number">11</span>
  1879. <span class="line-number">12</span>
  1880. <span class="line-number">13</span>
  1881. <span class="line-number">14</span>
  1882. <span class="line-number">15</span>
  1883. <span class="line-number">16</span>
  1884. <span class="line-number">17</span>
  1885. <span class="line-number">18</span>
  1886. <span class="line-number">19</span>
  1887. <span class="line-number">20</span>
  1888. <span class="line-number">21</span>
  1889. <span class="line-number">22</span>
  1890. <span class="line-number">23</span>
  1891. <span class="line-number">24</span>
  1892. <span class="line-number">25</span>
  1893. <span class="line-number">26</span>
  1894. <span class="line-number">27</span>
  1895. <span class="line-number">28</span>
  1896. <span class="line-number">29</span>
  1897. <span class="line-number">30</span>
  1898. <span class="line-number">31</span>
  1899. <span class="line-number">32</span>
  1900. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">class</span> <span class="nc">Program</span> <span class="p">{</span>
  1901. </span><span class="line"> <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
  1902. </span><span class="line">
  1903. </span><span class="line"> <span class="k">try</span> <span class="p">{</span>
  1904. </span><span class="line"> <span class="n">Retry01</span><span class="p">();</span>
  1905. </span><span class="line"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">ex</span><span class="p">)</span> <span class="p">{</span>
  1906. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">ex</span><span class="p">.</span><span class="n">Message</span><span class="p">);</span>
  1907. </span><span class="line"> <span class="p">}</span>
  1908. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;Press any key...&quot;</span><span class="p">);</span>
  1909. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">ReadKey</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
  1910. </span><span class="line"> <span class="p">}</span>
  1911. </span><span class="line">
  1912. </span><span class="line"> <span class="k">static</span> <span class="k">void</span> <span class="nf">Retry01</span><span class="p">()</span> <span class="p">{</span>
  1913. </span><span class="line"> <span class="c1">// Iterate through the directories on the C:\ drive</span>
  1914. </span><span class="line"> <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">dir</span> <span class="k">in</span> <span class="n">Directory</span><span class="p">.</span><span class="n">EnumerateDirectories</span><span class="p">(</span><span class="s">&quot;C:\\&quot;</span><span class="p">))</span> <span class="p">{</span>
  1915. </span><span class="line"> <span class="n">OccasionallyThrow</span><span class="p">(</span><span class="m">0.1d</span><span class="p">);</span>
  1916. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;dir: {0}&quot;</span><span class="p">,</span> <span class="n">dir</span><span class="p">);</span>
  1917. </span><span class="line"> <span class="p">}</span>
  1918. </span><span class="line"> <span class="p">}</span>
  1919. </span><span class="line">
  1920. </span><span class="line"> <span class="k">static</span> <span class="n">Random</span> <span class="n">_rnd</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Random</span><span class="p">(</span><span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">.</span><span class="n">Millisecond</span><span class="p">);</span>
  1921. </span><span class="line"> <span class="c1">/// &lt;summary&gt;</span>
  1922. </span><span class="line"> <span class="c1">/// Occasionally throw an exception</span>
  1923. </span><span class="line"> <span class="c1">/// &lt;/summary&gt;</span>
  1924. </span><span class="line"> <span class="c1">/// &lt;param name=&quot;freq&quot;&gt;Percentage (as a fraction) of the time to</span>
  1925. </span><span class="line"> <span class="c1">/// throw an exception. Uses a random number generator, so</span>
  1926. </span><span class="line"> <span class="c1">/// this is not an exact measure&lt;/param&gt;</span>
  1927. </span><span class="line"> <span class="k">static</span> <span class="k">void</span> <span class="nf">OccasionallyThrow</span><span class="p">(</span><span class="kt">double</span> <span class="n">freq</span><span class="p">)</span> <span class="p">{</span>
  1928. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">_rnd</span><span class="p">.</span><span class="n">NextDouble</span><span class="p">()</span> <span class="p">&lt;=</span> <span class="n">freq</span><span class="p">)</span>
  1929. </span><span class="line"> <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidOperationException</span><span class="p">(</span><span class="s">&quot;An occasional exception&quot;</span><span class="p">);</span>
  1930. </span><span class="line"> <span class="p">}</span>
  1931. </span><span class="line"><span class="p">}</span>
  1932. </span></code></pre></td></tr></table></div></figure></notextile></div>
  1933. <p>Weve got a method, <code>OccasionallyThrow(freq)</code> that, occasionally throws an exception (duh). Weve got a method that iterates through directories on the C:\ drive and pretty much cant get through it without throwing.</p>
  1934. <p>So first pass, lets fix <code>Retry01()</code> so it actually retries.</p>
  1935. <div class="bogus-wrapper"><notextile><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>
  1936. <span class="line-number">2</span>
  1937. <span class="line-number">3</span>
  1938. <span class="line-number">4</span>
  1939. <span class="line-number">5</span>
  1940. <span class="line-number">6</span>
  1941. <span class="line-number">7</span>
  1942. <span class="line-number">8</span>
  1943. <span class="line-number">9</span>
  1944. <span class="line-number">10</span>
  1945. <span class="line-number">11</span>
  1946. <span class="line-number">12</span>
  1947. <span class="line-number">13</span>
  1948. <span class="line-number">14</span>
  1949. <span class="line-number">15</span>
  1950. <span class="line-number">16</span>
  1951. <span class="line-number">17</span>
  1952. <span class="line-number">18</span>
  1953. <span class="line-number">19</span>
  1954. <span class="line-number">20</span>
  1955. <span class="line-number">21</span>
  1956. <span class="line-number">22</span>
  1957. <span class="line-number">23</span>
  1958. <span class="line-number">24</span>
  1959. <span class="line-number">25</span>
  1960. <span class="line-number">26</span>
  1961. <span class="line-number">27</span>
  1962. <span class="line-number">28</span>
  1963. <span class="line-number">29</span>
  1964. <span class="line-number">30</span>
  1965. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">Retry01</span><span class="p">()</span> <span class="p">{</span>
  1966. </span><span class="line"> <span class="c1">// Iterate through the directories on the C:\ drive</span>
  1967. </span><span class="line"> <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">dir</span> <span class="k">in</span> <span class="n">Directory</span><span class="p">.</span><span class="n">EnumerateDirectories</span><span class="p">(</span><span class="s">&quot;C:\\&quot;</span><span class="p">))</span> <span class="p">{</span>
  1968. </span><span class="line">
  1969. </span><span class="line"> <span class="kt">int</span> <span class="n">retryCount</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
  1970. </span><span class="line"> <span class="kt">bool</span> <span class="n">done</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
  1971. </span><span class="line"> <span class="k">do</span> <span class="p">{</span>
  1972. </span><span class="line"> <span class="k">try</span> <span class="p">{</span>
  1973. </span><span class="line">
  1974. </span><span class="line"> <span class="n">OccasionallyThrow</span><span class="p">(</span><span class="m">0.25d</span><span class="p">);</span>
  1975. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;dir: {0}&quot;</span><span class="p">,</span> <span class="n">dir</span><span class="p">);</span>
  1976. </span><span class="line">
  1977. </span><span class="line"> <span class="n">done</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
  1978. </span><span class="line">
  1979. </span><span class="line"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">ex</span><span class="p">)</span> <span class="p">{</span>
  1980. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">ex</span> <span class="k">is</span> <span class="n">InvalidOperationException</span><span class="p">)</span> <span class="p">{</span>
  1981. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">retryCount</span><span class="p">++</span> <span class="p">&lt;</span> <span class="m">3</span><span class="p">)</span> <span class="p">{</span>
  1982. </span><span class="line"> <span class="c1">// can try again. Under the limit</span>
  1983. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Caught exception, retry #{0}&quot;</span><span class="p">,</span> <span class="n">retryCount</span><span class="p">);</span>
  1984. </span><span class="line"> <span class="n">done</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
  1985. </span><span class="line"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  1986. </span><span class="line"> <span class="c1">// retried too many times already</span>
  1987. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Exceeded retry count. Throwing.&quot;</span><span class="p">);</span>
  1988. </span><span class="line"> <span class="k">throw</span><span class="p">;</span>
  1989. </span><span class="line"> <span class="p">}</span>
  1990. </span><span class="line"> <span class="p">}</span>
  1991. </span><span class="line"> <span class="p">}</span>
  1992. </span><span class="line"> <span class="p">}</span> <span class="k">while</span> <span class="p">(!</span><span class="n">done</span><span class="p">);</span>
  1993. </span><span class="line"> <span class="p">}</span>
  1994. </span><span class="line"><span class="p">}</span>
  1995. </span></code></pre></td></tr></table></div></figure></notextile></div>
  1996. <p>Yikes. Thats a bunch of code. Assuming we want to make this construct generally available, some refactoring is in order. Worse, the boilerplate code that manages retries <em>surrounds</em> the code we want to apply it to, at lines 10 and 11 of a 30 line block of code. This is a similar problem to the one described in <a href="http://blog.efvincent.com/c-nuts-and-bolts-lambdas02">my last post</a>, so you may see where this is going. Heres one approach to solving the problem.</p>
  1997. <div class="bogus-wrapper"><notextile><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>
  1998. <span class="line-number">2</span>
  1999. <span class="line-number">3</span>
  2000. <span class="line-number">4</span>
  2001. <span class="line-number">5</span>
  2002. <span class="line-number">6</span>
  2003. <span class="line-number">7</span>
  2004. <span class="line-number">8</span>
  2005. <span class="line-number">9</span>
  2006. <span class="line-number">10</span>
  2007. <span class="line-number">11</span>
  2008. <span class="line-number">12</span>
  2009. <span class="line-number">13</span>
  2010. <span class="line-number">14</span>
  2011. <span class="line-number">15</span>
  2012. <span class="line-number">16</span>
  2013. <span class="line-number">17</span>
  2014. <span class="line-number">18</span>
  2015. <span class="line-number">19</span>
  2016. <span class="line-number">20</span>
  2017. <span class="line-number">21</span>
  2018. <span class="line-number">22</span>
  2019. <span class="line-number">23</span>
  2020. <span class="line-number">24</span>
  2021. <span class="line-number">25</span>
  2022. <span class="line-number">26</span>
  2023. <span class="line-number">27</span>
  2024. <span class="line-number">28</span>
  2025. <span class="line-number">29</span>
  2026. <span class="line-number">30</span>
  2027. <span class="line-number">31</span>
  2028. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">Retry</span><span class="p">(</span><span class="n">Action</span> <span class="n">action</span><span class="p">,</span> <span class="kt">int</span> <span class="n">maxRetries</span> <span class="p">=</span> <span class="m">3</span><span class="p">)</span> <span class="p">{</span>
  2029. </span><span class="line"> <span class="kt">int</span> <span class="n">retryCount</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
  2030. </span><span class="line"> <span class="kt">bool</span> <span class="n">done</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
  2031. </span><span class="line"> <span class="k">do</span> <span class="p">{</span>
  2032. </span><span class="line"> <span class="k">try</span> <span class="p">{</span>
  2033. </span><span class="line"> <span class="n">action</span><span class="p">();</span>
  2034. </span><span class="line"> <span class="n">done</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
  2035. </span><span class="line"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">ex</span><span class="p">)</span> <span class="p">{</span>
  2036. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">ex</span> <span class="k">is</span> <span class="n">InvalidOperationException</span><span class="p">)</span> <span class="p">{</span>
  2037. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">retryCount</span><span class="p">++</span> <span class="p">&lt;</span> <span class="n">maxRetries</span><span class="p">)</span> <span class="p">{</span>
  2038. </span><span class="line"> <span class="c1">// can try again. Under the limit</span>
  2039. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Caught exception, retry #{0}&quot;</span><span class="p">,</span> <span class="n">retryCount</span><span class="p">);</span>
  2040. </span><span class="line"> <span class="n">done</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
  2041. </span><span class="line"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  2042. </span><span class="line"> <span class="c1">// retried too many times already</span>
  2043. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Exceeded retry count. Throwing.&quot;</span><span class="p">);</span>
  2044. </span><span class="line"> <span class="k">throw</span><span class="p">;</span>
  2045. </span><span class="line"> <span class="p">}</span>
  2046. </span><span class="line"> <span class="p">}</span>
  2047. </span><span class="line"> <span class="p">}</span>
  2048. </span><span class="line"> <span class="p">}</span> <span class="k">while</span> <span class="p">(!</span><span class="n">done</span><span class="p">);</span>
  2049. </span><span class="line"><span class="p">}</span>
  2050. </span><span class="line">
  2051. </span><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">Retry02</span><span class="p">()</span> <span class="p">{</span>
  2052. </span><span class="line"> <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">dir</span> <span class="k">in</span> <span class="n">Directory</span><span class="p">.</span><span class="n">EnumerateDirectories</span><span class="p">(</span><span class="s">&quot;C:\\&quot;</span><span class="p">))</span> <span class="p">{</span>
  2053. </span><span class="line"> <span class="n">Retry</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
  2054. </span><span class="line"> <span class="n">OccasionallyThrow</span><span class="p">(</span><span class="m">0.25d</span><span class="p">);</span>
  2055. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;dir: {0}&quot;</span><span class="p">,</span> <span class="n">dir</span><span class="p">);</span>
  2056. </span><span class="line"> <span class="p">},</span> <span class="m">3</span><span class="p">);</span>
  2057. </span><span class="line"> <span class="p">}</span>
  2058. </span><span class="line"><span class="p">}</span>
  2059. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2060. <p>This approach solves many of the problems weve identified. The retry logic is encapsulated in a function thats trivial to reuse. One point of interest here if youre not familiar with the syntax and techniques, it may look a bit strange. But it also should look a little familiar; consider the using block:</p>
  2061. <div class="bogus-wrapper"><notextile><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>
  2062. <span class="line-number">2</span>
  2063. <span class="line-number">3</span>
  2064. <span class="line-number">4</span>
  2065. <span class="line-number">5</span>
  2066. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="kt">byte</span> <span class="n">someByte</span> <span class="p">=</span> <span class="m">100</span><span class="p">;</span>
  2067. </span><span class="line"><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">stream</span> <span class="p">=</span> <span class="n">File</span><span class="p">.</span><span class="n">Open</span><span class="p">(</span><span class="s">&quot;C:\\data.dat&quot;</span><span class="p">,</span> <span class="n">FileMode</span><span class="p">.</span><span class="n">CreateNew</span><span class="p">))</span> <span class="p">{</span>
  2068. </span><span class="line"> <span class="k">for</span> <span class="p">(</span><span class="kt">byte</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">someByte</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
  2069. </span><span class="line"> <span class="n">stream</span><span class="p">.</span><span class="n">WriteByte</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
  2070. </span><span class="line"><span class="p">}</span>
  2071. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2072. <p>The C# using block has a similar pattern. Theres some construct (using), and then a block of code to which the construct applies. It has a similar feel to our Retry() solution. Hmmm could we use the Retry() approach to write our own using?</p>
  2073. <div class="bogus-wrapper"><notextile><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>
  2074. <span class="line-number">2</span>
  2075. <span class="line-number">3</span>
  2076. <span class="line-number">4</span>
  2077. <span class="line-number">5</span>
  2078. <span class="line-number">6</span>
  2079. <span class="line-number">7</span>
  2080. <span class="line-number">8</span>
  2081. <span class="line-number">9</span>
  2082. <span class="line-number">10</span>
  2083. <span class="line-number">11</span>
  2084. <span class="line-number">12</span>
  2085. <span class="line-number">13</span>
  2086. <span class="line-number">14</span>
  2087. <span class="line-number">15</span>
  2088. <span class="line-number">16</span>
  2089. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="n">Using</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">T</span> <span class="n">disposableVar</span><span class="p">,</span> <span class="n">Action</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">usingBlock</span><span class="p">)</span> <span class="k">where</span> <span class="n">T</span> <span class="p">:</span> <span class="n">IDisposable</span> <span class="p">{</span>
  2090. </span><span class="line"> <span class="k">try</span> <span class="p">{</span>
  2091. </span><span class="line"> <span class="n">usingBlock</span><span class="p">(</span><span class="n">disposableVar</span><span class="p">);</span>
  2092. </span><span class="line"> <span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
  2093. </span><span class="line"> <span class="n">disposableVar</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
  2094. </span><span class="line"> <span class="p">}</span>
  2095. </span><span class="line"><span class="p">}</span>
  2096. </span><span class="line">
  2097. </span><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">UsingMyUsing</span><span class="p">()</span> <span class="p">{</span>
  2098. </span><span class="line"> <span class="kt">byte</span> <span class="n">someByte</span> <span class="p">=</span> <span class="m">100</span><span class="p">;</span>
  2099. </span><span class="line">
  2100. </span><span class="line"> <span class="n">Using</span><span class="p">(</span><span class="n">File</span><span class="p">.</span><span class="n">Open</span><span class="p">(</span><span class="s">&quot;C:\\data.dat&quot;</span><span class="p">,</span> <span class="n">FileMode</span><span class="p">.</span><span class="n">CreateNew</span><span class="p">),</span> <span class="n">stream</span> <span class="p">=&gt;</span> <span class="p">{</span>
  2101. </span><span class="line"> <span class="k">for</span> <span class="p">(</span><span class="kt">byte</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">someByte</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
  2102. </span><span class="line"> <span class="n">stream</span><span class="p">.</span><span class="n">WriteByte</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
  2103. </span><span class="line"> <span class="p">});</span>
  2104. </span><span class="line"><span class="p">}</span>
  2105. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2106. <p>See thats why I like coding so much thats definitely cool. Its not exactly character for character like the using statement, but its pretty darn close (actually, mine is a couple of characters shorter). And its equivalent (at least it is superficially, I havent checked thoroughly, its almost 1am after all). It had to get a little fancier with the generics, but weve recreated a C# language construct.</p>
  2107. <p>This article is long enough, and Im sure you get the picture. To me, this is a great example of how functional thinking can lead to interesting, robust solutions to problems. Let me know if youve got any questions or comments. Until then, have fun!</p>
  2108. ]]></content>
  2109. </entry>
  2110. <entry>
  2111. <title type="html"><![CDATA[Lambdas Exposing Disposable Resources in Your API]]></title>
  2112. <link href="http://efvincent.github.io/blog/2010/02/02/c-nuts-and-bolts-lambdas02/"/>
  2113. <updated>2010-02-02T13:51:56-05:00</updated>
  2114. <id>http://efvincent.github.io/blog/2010/02/02/c-nuts-and-bolts-lambdas02</id>
  2115. <content type="html"><![CDATA[<p>The <a href="http://blog.efvincent.com/c-nuts-and-bolts-lambdas/">last article</a> described the absolute (and I mean really absolute) basics of lambdas in C#. Assuming youre continuing from there, where to next? Lets use some lambdas. There are two approaches we can use. First is using lambdas in places you traditionally used other approaches. Second is using them in new and interesting ways. Hmmm. Which to choose.
  2116. <!-- more --></p>
  2117. <h3 id="new-and-interesting-code-constructs-using-lambdas">New and Interesting Code Constructs using Lambdas</h3>
  2118. <p>Yea thatll do. Lets take an example situation. Youre tasked with writing part of a data access layer. Its a low level data access layer, were not using Entity Framework, no Linq to SQL. No NHibernate. Just you and the keyboard. Sweet.</p>
  2119. <p>The team decides theyre comfortable with the forward only read only data reader. Ok. So you start sketching out your code and end up with this:</p>
  2120. <div class="bogus-wrapper"><notextile><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>
  2121. <span class="line-number">2</span>
  2122. <span class="line-number">3</span>
  2123. <span class="line-number">4</span>
  2124. <span class="line-number">5</span>
  2125. <span class="line-number">6</span>
  2126. <span class="line-number">7</span>
  2127. <span class="line-number">8</span>
  2128. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">public</span> <span class="k">static</span> <span class="n">IDataReader</span> <span class="nf">GetSomeData</span><span class="p">()</span> <span class="p">{</span>
  2129. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">con</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlConnection</span><span class="p">(</span><span class="n">conString</span><span class="p">))</span>
  2130. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">cmd</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlCommand</span><span class="p">(</span><span class="n">cmdString</span><span class="p">,</span> <span class="n">con</span><span class="p">))</span> <span class="p">{</span>
  2131. </span><span class="line"> <span class="n">con</span><span class="p">.</span><span class="n">Open</span><span class="p">();</span>
  2132. </span><span class="line"> <span class="n">IDataReader</span> <span class="n">rdr</span> <span class="p">=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">ExecuteReader</span><span class="p">();</span>
  2133. </span><span class="line"> <span class="k">return</span> <span class="n">rdr</span><span class="p">;</span>
  2134. </span><span class="line"> <span class="p">}</span>
  2135. </span><span class="line"><span class="p">}</span>
  2136. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2137. <p>Well, this wont work. Trying to return the reader, but youve got a command and a connection both in using blocks. On returning, those blocks will terminate, disposing of the connection and command (which is good). What now? Briefly consider <em>not</em> using using blocks, not disposing of anything and just returning the reader. Nah just cant do that. Ok, so bail on data reader and go with a data set or some other statefull representation of the data I guess.</p>
  2138. <p>But WAIT! Dont punch out just yet. Whats happening here is weve got a disposable resource we want to use in a spot thats surrounded if you will by other important code. Lets take a look at this:</p>
  2139. <div class="bogus-wrapper"><notextile><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>
  2140. <span class="line-number">2</span>
  2141. <span class="line-number">3</span>
  2142. <span class="line-number">4</span>
  2143. <span class="line-number">5</span>
  2144. <span class="line-number">6</span>
  2145. <span class="line-number">7</span>
  2146. <span class="line-number">8</span>
  2147. <span class="line-number">9</span>
  2148. </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">UsingReaderGetSomeData</span><span class="p">(</span><span class="n">Action</span><span class="p">&lt;</span><span class="n">IDataReader</span><span class="p">&gt;</span> <span class="n">processor</span><span class="p">)</span> <span class="p">{</span>
  2149. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">con</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlConnection</span><span class="p">(</span><span class="n">conString</span><span class="p">))</span>
  2150. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">cmd</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlCommand</span><span class="p">(</span><span class="n">cmdString</span><span class="p">,</span> <span class="n">con</span><span class="p">))</span> <span class="p">{</span>
  2151. </span><span class="line"> <span class="n">con</span><span class="p">.</span><span class="n">Open</span><span class="p">();</span>
  2152. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="n">IDataReader</span> <span class="n">rdr</span> <span class="p">=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">ExecuteReader</span><span class="p">())</span> <span class="p">{</span>
  2153. </span><span class="line"> <span class="n">processor</span><span class="p">(</span><span class="n">rdr</span><span class="p">);</span>
  2154. </span><span class="line"> <span class="p">}</span>
  2155. </span><span class="line"> <span class="p">}</span>
  2156. </span><span class="line"><span class="p">}</span>
  2157. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2158. <p>Now weve got a method that does all the right things with the data reader. The reader, its connection, and its command are all in using blocks so theyll be properly disposed of. We ask the caller to supply an <code>Action&lt;IDataReader&gt;</code>, and well apply that action to our well protected data reader.</p>
  2159. <p>This looks reasonable, but since its a data reader, wont the caller always be doing the <code>while(rdr.Read())</code> thing? Lets take care of that for them.</p>
  2160. <div class="bogus-wrapper"><notextile><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>
  2161. <span class="line-number">2</span>
  2162. <span class="line-number">3</span>
  2163. <span class="line-number">4</span>
  2164. <span class="line-number">5</span>
  2165. <span class="line-number">6</span>
  2166. <span class="line-number">7</span>
  2167. <span class="line-number">8</span>
  2168. <span class="line-number">9</span>
  2169. <span class="line-number">10</span>
  2170. <span class="line-number">11</span>
  2171. </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">UsingReaderGetSomeData</span><span class="p">(</span><span class="n">Action</span><span class="p">&lt;</span><span class="n">IDataRecord</span><span class="p">&gt;</span> <span class="n">processor</span><span class="p">)</span> <span class="p">{</span>
  2172. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">con</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlConnection</span><span class="p">(</span><span class="n">conString</span><span class="p">))</span>
  2173. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">cmd</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlCommand</span><span class="p">(</span><span class="n">cmdString</span><span class="p">,</span> <span class="n">con</span><span class="p">))</span> <span class="p">{</span>
  2174. </span><span class="line"> <span class="n">con</span><span class="p">.</span><span class="n">Open</span><span class="p">();</span>
  2175. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="n">IDataReader</span> <span class="n">rdr</span> <span class="p">=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">ExecuteReader</span><span class="p">())</span> <span class="p">{</span>
  2176. </span><span class="line"> <span class="k">while</span><span class="p">(</span><span class="n">rdr</span><span class="p">.</span><span class="n">Read</span><span class="p">())</span> <span class="p">{</span>
  2177. </span><span class="line"> <span class="n">processor</span><span class="p">(</span><span class="n">rdr</span><span class="p">);</span>
  2178. </span><span class="line"> <span class="p">}</span>
  2179. </span><span class="line"> <span class="p">}</span>
  2180. </span><span class="line"> <span class="p">}</span>
  2181. </span><span class="line"><span class="p">}</span>
  2182. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2183. <p>Now instead of asking for an <code>Action&lt;IDataReader&gt;</code>, were asking for an <code>Action&lt;IDataRecord&gt;</code> that will be called once for each record. Our function can iterate the data reader and call the processor once for each result. Heres a sample caller that builds an HTML ordered list and writes the results to the console:</p>
  2184. <div class="bogus-wrapper"><notextile><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>
  2185. <span class="line-number">2</span>
  2186. <span class="line-number">3</span>
  2187. <span class="line-number">4</span>
  2188. <span class="line-number">5</span>
  2189. <span class="line-number">6</span>
  2190. <span class="line-number">7</span>
  2191. <span class="line-number">8</span>
  2192. <span class="line-number">9</span>
  2193. <span class="line-number">10</span>
  2194. <span class="line-number">11</span>
  2195. <span class="line-number">12</span>
  2196. <span class="line-number">13</span>
  2197. <span class="line-number">14</span>
  2198. <span class="line-number">15</span>
  2199. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
  2200. </span><span class="line">
  2201. </span><span class="line"> <span class="n">StringBuilder</span> <span class="n">sb</span> <span class="p">=</span> <span class="k">new</span> <span class="n">StringBuilder</span><span class="p">();</span>
  2202. </span><span class="line"> <span class="n">sb</span><span class="p">.</span><span class="n">AppendLine</span><span class="p">(</span><span class="s">&quot;&lt;ol&gt;&quot;</span><span class="p">);</span>
  2203. </span><span class="line"> <span class="n">Dal</span><span class="p">.</span><span class="n">UsingReaderGetSomeData</span><span class="p">(</span><span class="n">dr</span> <span class="p">=&gt;</span> <span class="p">{</span>
  2204. </span><span class="line"> <span class="n">sb</span><span class="p">.</span><span class="n">Append</span><span class="p">(</span><span class="s">&quot; &lt;li&gt;&quot;</span><span class="p">);</span>
  2205. </span><span class="line"> <span class="n">sb</span><span class="p">.</span><span class="n">Append</span><span class="p">(</span><span class="n">dr</span><span class="p">[</span><span class="m">0</span><span class="p">]);</span>
  2206. </span><span class="line"> <span class="n">sb</span><span class="p">.</span><span class="n">AppendLine</span><span class="p">(</span><span class="s">&quot;&lt;/li&gt;&quot;</span><span class="p">);</span>
  2207. </span><span class="line"> <span class="p">});</span>
  2208. </span><span class="line"> <span class="n">sb</span><span class="p">.</span><span class="n">AppendLine</span><span class="p">(</span><span class="s">&quot;&lt;/ol&gt;&quot;</span><span class="p">);</span>
  2209. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">sb</span><span class="p">);</span>
  2210. </span><span class="line">
  2211. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;Press any key...&quot;</span><span class="p">);</span>
  2212. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">ReadKey</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
  2213. </span><span class="line"><span class="p">}</span>
  2214. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2215. <p>A client uses our function like a loop. Everything it puts in the curly braces from line 5 9 is like the the body of the loop. With this approach, were getting the benefits of the data reader, its fast and forward only. The construct is similar to a loop, so the consumers (our team mates) should be able to understand how to use this. And finally, were taking proper care to dispose of the resources.</p>
  2216. <p>To summarize, this approach allows you define functions that accept functions as parameters, and build more complex behavior. This technique is called <em>functional composition</em>. Its one of the core principal concepts of Functional Programming, but as weve seen here, it can be applied to solutions in imperative programming languages like C# to great effect. Using techniques like this help you break your code down in smaller and smaller chunks, with some functions doing little bits of work, and other functions serving as glue or framework code. All this makes your code easier to test and less prone to errors if done correctly.</p>
  2217. <h3 id="taking-it-further-or-something-more-like-real-production-code">Taking it Further, or, Something More like Real Production Code</h3>
  2218. <p>Alright, that was interesting. And as far as blog posts go, thats all I was really trying to get across. But if youre curious about what production code might look like that uses an approach like this, heres an example:</p>
  2219. <div class="bogus-wrapper"><notextile><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>
  2220. <span class="line-number">2</span>
  2221. <span class="line-number">3</span>
  2222. <span class="line-number">4</span>
  2223. <span class="line-number">5</span>
  2224. <span class="line-number">6</span>
  2225. <span class="line-number">7</span>
  2226. <span class="line-number">8</span>
  2227. <span class="line-number">9</span>
  2228. <span class="line-number">10</span>
  2229. <span class="line-number">11</span>
  2230. <span class="line-number">12</span>
  2231. <span class="line-number">13</span>
  2232. <span class="line-number">14</span>
  2233. <span class="line-number">15</span>
  2234. <span class="line-number">16</span>
  2235. <span class="line-number">17</span>
  2236. <span class="line-number">18</span>
  2237. <span class="line-number">19</span>
  2238. <span class="line-number">20</span>
  2239. <span class="line-number">21</span>
  2240. <span class="line-number">22</span>
  2241. <span class="line-number">23</span>
  2242. <span class="line-number">24</span>
  2243. <span class="line-number">25</span>
  2244. <span class="line-number">26</span>
  2245. <span class="line-number">27</span>
  2246. <span class="line-number">28</span>
  2247. <span class="line-number">29</span>
  2248. <span class="line-number">30</span>
  2249. <span class="line-number">31</span>
  2250. <span class="line-number">32</span>
  2251. <span class="line-number">33</span>
  2252. <span class="line-number">34</span>
  2253. <span class="line-number">35</span>
  2254. <span class="line-number">36</span>
  2255. <span class="line-number">37</span>
  2256. <span class="line-number">38</span>
  2257. <span class="line-number">39</span>
  2258. <span class="line-number">40</span>
  2259. <span class="line-number">41</span>
  2260. <span class="line-number">42</span>
  2261. <span class="line-number">43</span>
  2262. <span class="line-number">44</span>
  2263. <span class="line-number">45</span>
  2264. <span class="line-number">46</span>
  2265. <span class="line-number">47</span>
  2266. <span class="line-number">48</span>
  2267. <span class="line-number">49</span>
  2268. <span class="line-number">50</span>
  2269. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">private</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">UsingReader</span><span class="p">(</span>
  2270. </span><span class="line"> <span class="kt">string</span> <span class="n">command</span><span class="p">,</span>
  2271. </span><span class="line"> <span class="n">Action</span><span class="p">&lt;</span><span class="n">SqlCommand</span><span class="p">&gt;</span> <span class="n">preAction</span> <span class="p">=</span> <span class="k">null</span><span class="p">,</span>
  2272. </span><span class="line"> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">Action</span><span class="p">&lt;</span><span class="n">IDataRecord</span><span class="p">&gt;&gt;</span> <span class="n">recordProcessors</span> <span class="p">=</span> <span class="k">null</span><span class="p">,</span>
  2273. </span><span class="line"> <span class="n">Action</span><span class="p">&lt;</span><span class="n">SqlCommand</span><span class="p">&gt;</span> <span class="n">postAction</span> <span class="p">=</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
  2274. </span><span class="line">
  2275. </span><span class="line"> <span class="c1">// Instantiate connection and command, open the connection</span>
  2276. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">con</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlConnection</span><span class="p">(</span><span class="n">conString</span><span class="p">))</span>
  2277. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">cmd</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlCommand</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">con</span><span class="p">))</span> <span class="p">{</span>
  2278. </span><span class="line"> <span class="n">con</span><span class="p">.</span><span class="n">Open</span><span class="p">();</span>
  2279. </span><span class="line">
  2280. </span><span class="line"> <span class="c1">// Execute a pre-action if specified</span>
  2281. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">preAction</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span> <span class="n">preAction</span><span class="p">(</span><span class="n">cmd</span><span class="p">);</span>
  2282. </span><span class="line">
  2283. </span><span class="line"> <span class="c1">// If the reader processing blocks are supplied</span>
  2284. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">recordProcessors</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
  2285. </span><span class="line">
  2286. </span><span class="line"> <span class="c1">// Get an enumerator for the processing blocks &amp; move</span>
  2287. </span><span class="line"> <span class="c1">// to the first processor</span>
  2288. </span><span class="line"> <span class="kt">var</span> <span class="n">processorEnumerator</span> <span class="p">=</span> <span class="n">recordProcessors</span><span class="p">.</span><span class="n">GetEnumerator</span><span class="p">();</span>
  2289. </span><span class="line"> <span class="k">if</span> <span class="p">(!</span><span class="n">processorEnumerator</span><span class="p">.</span><span class="n">MoveNext</span><span class="p">())</span>
  2290. </span><span class="line"> <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidOperationException</span><span class="p">(</span>
  2291. </span><span class="line"> <span class="s">&quot;Supply at least one record processor&quot;</span><span class="p">);</span>
  2292. </span><span class="line">
  2293. </span><span class="line"> <span class="c1">// Open the reader</span>
  2294. </span><span class="line"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">reader</span> <span class="p">=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">ExecuteReader</span><span class="p">(</span><span class="n">CommandBehavior</span><span class="p">.</span><span class="n">CloseConnection</span><span class="p">))</span> <span class="p">{</span>
  2295. </span><span class="line">
  2296. </span><span class="line"> <span class="k">do</span> <span class="p">{</span>
  2297. </span><span class="line"> <span class="c1">// Get the current record processing block</span>
  2298. </span><span class="line"> <span class="kt">var</span> <span class="n">recordProcessor</span> <span class="p">=</span> <span class="n">processorEnumerator</span><span class="p">.</span><span class="n">Current</span><span class="p">;</span>
  2299. </span><span class="line">
  2300. </span><span class="line"> <span class="c1">// Iterate the records of the IDataReader using the current block</span>
  2301. </span><span class="line"> <span class="k">while</span> <span class="p">(</span><span class="n">reader</span><span class="p">.</span><span class="n">Read</span><span class="p">())</span>
  2302. </span><span class="line"> <span class="n">recordProcessor</span><span class="p">(</span><span class="n">reader</span><span class="p">);</span>
  2303. </span><span class="line">
  2304. </span><span class="line"> <span class="c1">// The loop condition advances both IDataReader and enumerator</span>
  2305. </span><span class="line"> <span class="c1">// in sync continuing as long as there&#39;s a next resultSet and a</span>
  2306. </span><span class="line"> <span class="c1">// processor to process it</span>
  2307. </span><span class="line"> <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">reader</span><span class="p">.</span><span class="n">NextResult</span><span class="p">()</span> <span class="p">&amp;&amp;</span> <span class="n">processorEnumerator</span><span class="p">.</span><span class="n">MoveNext</span><span class="p">());</span>
  2308. </span><span class="line"> <span class="p">}</span>
  2309. </span><span class="line">
  2310. </span><span class="line"> <span class="p">}</span> <span class="k">else</span>
  2311. </span><span class="line"> <span class="c1">// If there are no actions to execute using data reader, just execute query</span>
  2312. </span><span class="line"> <span class="n">cmd</span><span class="p">.</span><span class="n">ExecuteNonQuery</span><span class="p">();</span>
  2313. </span><span class="line">
  2314. </span><span class="line"> <span class="c1">// Do any clean up that might be needed</span>
  2315. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">postAction</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
  2316. </span><span class="line"> <span class="n">postAction</span><span class="p">(</span><span class="n">cmd</span><span class="p">);</span>
  2317. </span><span class="line"> <span class="p">}</span>
  2318. </span><span class="line"><span class="p">}</span>
  2319. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2320. <p>Here we pass optional pre- and post- actions that allow the caller to optionally manipulate the command before and after its executed. We also accept a set of actions were calling record processors, to handle the case when a stored procedure or command is returning multiple result sets. In the case of multiple result sets, wed expect the caller to send a different record processor for each result set it expects.</p>
  2321. <p>So this seems like a lot of code. Why bother? The way I approached it was that this code is a private method of the data access layer, and the public methods would leverage this method to avoid repeating the gory details of working with data readers. Leveraging the above method, our original <code>GetSomeData()</code> now looks like:</p>
  2322. <div class="bogus-wrapper"><notextile><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>
  2323. <span class="line-number">2</span>
  2324. <span class="line-number">3</span>
  2325. </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">UsingReaderGetSomeData</span><span class="p">(</span><span class="n">Action</span><span class="p">&lt;</span><span class="n">IDataRecord</span><span class="p">&gt;</span> <span class="n">recordProcessor</span><span class="p">)</span> <span class="p">{</span>
  2326. </span><span class="line"> <span class="n">UsingReader</span><span class="p">(</span><span class="n">cmdString</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">new</span> <span class="n">Action</span><span class="p">&lt;</span><span class="n">IDataRecord</span><span class="p">&gt;[]</span> <span class="p">{</span> <span class="n">recordProcessor</span> <span class="p">});</span>
  2327. </span><span class="line"><span class="p">}</span>
  2328. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2329. <p>And if we had a data access method that took a couple of parameters, it would look like this:</p>
  2330. <div class="bogus-wrapper"><notextile><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>
  2331. <span class="line-number">2</span>
  2332. <span class="line-number">3</span>
  2333. <span class="line-number">4</span>
  2334. <span class="line-number">5</span>
  2335. </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">UsingReaderGetSearch</span><span class="p">(</span><span class="kt">string</span> <span class="n">criteria</span><span class="p">,</span> <span class="n">Action</span><span class="p">&lt;</span><span class="n">IDataRecord</span><span class="p">&gt;</span> <span class="n">resultProcessor</span><span class="p">)</span> <span class="p">{</span>
  2336. </span><span class="line"> <span class="n">UsingReader</span><span class="p">(</span><span class="n">cmdString</span><span class="p">,</span>
  2337. </span><span class="line"> <span class="n">cmd</span> <span class="p">=&gt;</span> <span class="n">cmd</span><span class="p">.</span><span class="n">Parameters</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="k">new</span> <span class="n">SqlParameter</span><span class="p">(</span><span class="s">&quot;@searchCriteria&quot;</span><span class="p">,</span> <span class="n">criteria</span><span class="p">)),</span>
  2338. </span><span class="line"> <span class="k">new</span> <span class="n">Action</span><span class="p">&lt;</span><span class="n">IDataRecord</span><span class="p">&gt;[]</span> <span class="p">{</span> <span class="n">resultProcessor</span> <span class="p">});</span>
  2339. </span><span class="line"><span class="p">}</span>
  2340. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2341. <p>I hope this has proved helpful. Ill keep throwing more of these posts out there, let me know if theres something youd like to see.</p>
  2342. ]]></content>
  2343. </entry>
  2344. <entry>
  2345. <title type="html"><![CDATA[C# Nuts and Bolts: Lambdas]]></title>
  2346. <link href="http://efvincent.github.io/blog/2010/02/01/c-nuts-and-bolts-lambdas/"/>
  2347. <updated>2010-02-01T14:19:41-05:00</updated>
  2348. <id>http://efvincent.github.io/blog/2010/02/01/c-nuts-and-bolts-lambdas</id>
  2349. <content type="html"><![CDATA[<p>You dont need to use Lambdas to make a living writing code in .NET. You can probably get away with not even knowing what Linq is. You can also still find work coding in .NET 2.0. But thats painfully BORING. So to avoid the stinging monotony of working in a 5 year reverse time-shift, lets take a look at lambdas.</p>
  2350. <!-- more -->
  2351. <p>The (arguably) simplest lambda.</p>
  2352. <div class="bogus-wrapper"><notextile><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>
  2353. <span class="line-number">2</span>
  2354. <span class="line-number">3</span>
  2355. <span class="line-number">4</span>
  2356. <span class="line-number">5</span>
  2357. <span class="line-number">6</span>
  2358. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="kt">string</span> <span class="n">message</span> <span class="p">=</span> <span class="s">&quot;Hello World&quot;</span><span class="p">;</span>
  2359. </span><span class="line"><span class="n">Action</span> <span class="n">simpleLambda</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">message</span><span class="p">);</span>
  2360. </span><span class="line">
  2361. </span><span class="line"><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="err"></span><span class="n">Get</span> <span class="n">ready</span> <span class="k">for</span> <span class="n">a</span> <span class="n">message</span><span class="p">!</span><span class="err"></span><span class="p">);</span>
  2362. </span><span class="line"><span class="n">simpleLambda</span><span class="p">();</span>
  2363. </span><span class="line"><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="err"></span><span class="n">That</span> <span class="n">was</span> <span class="n">the</span> <span class="n">message</span><span class="p">!</span><span class="err"></span><span class="p">);</span>
  2364. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2365. <p>The the type Action is a delegate, which can be thought of as a function pointer. The variable simpleLambda is now a function. The same way that message is a string. In reality, there are delegates and pointers involved, but for the day to day, just think of simpleLambda as a function. It can be called just like you would any function, which is what weve done here.</p>
  2366. <p>There are two different Types that are generally used for these functions. They are Action and Func. Action, which we just saw, is a function that doesnt return anything. Its a void function. When we want to define a function that returns something, we use the Func type. Remember back to your early days of Visual Basic, Pascal, etc., when there were different keywords that youd use to specify if there was a return value or not? Same kinda thing here. Func returns, Action doesnt. So heres a Func example.</p>
  2367. <div class="bogus-wrapper"><notextile><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>
  2368. <span class="line-number">2</span>
  2369. <span class="line-number">3</span>
  2370. <span class="line-number">4</span>
  2371. <span class="line-number">5</span>
  2372. <span class="line-number">6</span>
  2373. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="c1">// Define a func that returns something</span>
  2374. </span><span class="line">
  2375. </span><span class="line"><span class="n">Func</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">minutesAndSeconds</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="kt">string</span><span class="p">.</span><span class="n">Format</span><span class="p">(</span><span class="s">&quot;{0:mm:ss.ffff}&quot;</span><span class="p">,</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">);</span>
  2376. </span><span class="line">
  2377. </span><span class="line"><span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;Current Minutes and seconds are: &quot;</span><span class="p">);</span>
  2378. </span><span class="line"><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">minutesAndSeconds</span><span class="p">());</span>
  2379. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2380. <p>Heres a function that returns a string. Its type is Func<string>, which you can read as a function that returns a string. Lets break down the syntax of the lambda itself. It centers around the lambda operator =&gt;, which some people read as goes to. In both our examples, simpleLambda and minutesAndSeconds are functions that take no parameters. So on the left of the lambda operator are empty parenthesis. Means no parameters to the function. Easy. On the right is the body of the function.</string></p>
  2381. <p>There are two ways of expressing the body of the function. If the body is a single statement, you can just put that statement. This is called an Expression Lambda. If you need more than one statement on the right of the Lambda operator, you end up with something like this:</p>
  2382. <div class="bogus-wrapper"><notextile><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>
  2383. <span class="line-number">2</span>
  2384. <span class="line-number">3</span>
  2385. <span class="line-number">4</span>
  2386. <span class="line-number">5</span>
  2387. <span class="line-number">6</span>
  2388. <span class="line-number">7</span>
  2389. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="n">Func</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="kt">string</span><span class="p">&gt;</span> <span class="n">hasher</span> <span class="p">=</span>
  2390. </span><span class="line"> <span class="n">s</span> <span class="p">=&gt;</span> <span class="p">{</span>
  2391. </span><span class="line"> <span class="kt">var</span> <span class="n">sha</span> <span class="p">=</span> <span class="k">new</span> <span class="n">System</span><span class="p">.</span><span class="n">Security</span><span class="p">.</span><span class="n">Cryptography</span><span class="p">.</span><span class="n">SHA1CryptoServiceProvider</span><span class="p">();</span>
  2392. </span><span class="line"> <span class="k">return</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToBase64String</span><span class="p">(</span><span class="n">sha</span><span class="p">.</span><span class="n">ComputeHash</span><span class="p">(</span><span class="n">ASCIIEncoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">s</span><span class="p">)));</span>
  2393. </span><span class="line"> <span class="p">};</span>
  2394. </span><span class="line">
  2395. </span><span class="line"><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;The base64 encoded SHA1 hash of \&quot;Hello World\&quot; is {0}&quot;</span><span class="p">,</span> <span class="n">hasher</span><span class="p">(</span><span class="s">&quot;Hello World&quot;</span><span class="p">));</span>
  2396. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2397. <p>A couple of differences here first theres some added whitespace to make stuff more readable. Dont let it throw you. Whitespace == good. Second, the type is now Func&lt;string, string&gt;. The key to reading the Func type is that the last generic type specification is the return type. So it reads a function that takes a string and returns a string. Since this lambda takes a string as a parameter, to the left of the lambda operator goes the parameter. You can name this parameter anything you want, just like when youre defining a regular function. This parameter is bound to the input to the function.</p>
  2398. <p>The next thing thats different is there are open and close curly brackets, just like a function definition, after the lambda operator. This is the body, its just like a function body. You declare local variables in here, and when youre done, you return something. Or if this is an Action instead of a Func, you dont need to return anything (remember, Action is like a void function). This is the same function except as a statically defined method on a class:</p>
  2399. <div class="bogus-wrapper"><notextile><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>
  2400. <span class="line-number">2</span>
  2401. <span class="line-number">3</span>
  2402. <span class="line-number">4</span>
  2403. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">public</span> <span class="k">static</span> <span class="kt">string</span> <span class="nf">Hasher</span><span class="p">(</span><span class="kt">string</span> <span class="n">s</span><span class="p">)</span> <span class="p">{</span>
  2404. </span><span class="line"> <span class="kt">var</span> <span class="n">sha</span> <span class="p">=</span> <span class="k">new</span> <span class="n">System</span><span class="p">.</span><span class="n">Security</span><span class="p">.</span><span class="n">Cryptography</span><span class="p">.</span><span class="n">SHA1CryptoServiceProvider</span><span class="p">();</span>
  2405. </span><span class="line"> <span class="k">return</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToBase64String</span><span class="p">(</span><span class="n">sha</span><span class="p">.</span><span class="n">ComputeHash</span><span class="p">(</span><span class="n">ASCIIEncoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">s</span><span class="p">)));</span>
  2406. </span><span class="line"><span class="p">}</span>
  2407. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2408. <p>Thaaaaatts pretty much it. Therere plenty of implementation details under the covers, and theres a whole world of design patterns and techniques to explore with regards to <em>using</em> lambdas. But as far as what they are, youre looking at it. Ill push it a little further in the next blog post. If youve got any questions or want to dive deeper into this or any other subject I write about, let me know in the comments. In the mean time, have fun!</p>
  2409. ]]></content>
  2410. </entry>
  2411. <entry>
  2412. <title type="html"><![CDATA[Applied Functional: Getting User Input]]></title>
  2413. <link href="http://efvincent.github.io/blog/2010/01/31/applied-functional-01/"/>
  2414. <updated>2010-01-31T22:12:13-05:00</updated>
  2415. <id>http://efvincent.github.io/blog/2010/01/31/applied-functional-01</id>
  2416. <content type="html"><![CDATA[<p>The thing with spending time on functional programming is that the typical .NET programmer will not likely be able to write production code in F#, and almost certainly not in Haskell. But what you are able to do is apply a new set of problem solving approaches to your every day work.
  2417. <!-- more -->
  2418. So heres a simple problem that we see all the time; youre writing a console application to test a component. Heres the pseudo code:</p>
  2419. <div class="bogus-wrapper"><notextile><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>
  2420. <span class="line-number">2</span>
  2421. <span class="line-number">3</span>
  2422. <span class="line-number">4</span>
  2423. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="c1">/// While still processing</span>
  2424. </span><span class="line"><span class="c1">/// Get a string from the user</span>
  2425. </span><span class="line"><span class="c1">/// Process the string</span>
  2426. </span><span class="line"><span class="c1">/// End While</span>
  2427. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2428. <p>Super duper simple. So heres a straight forward way to code it:</p>
  2429. <div class="bogus-wrapper"><notextile><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>
  2430. <span class="line-number">2</span>
  2431. <span class="line-number">3</span>
  2432. <span class="line-number">4</span>
  2433. <span class="line-number">5</span>
  2434. <span class="line-number">6</span>
  2435. <span class="line-number">7</span>
  2436. <span class="line-number">8</span>
  2437. <span class="line-number">9</span>
  2438. <span class="line-number">10</span>
  2439. <span class="line-number">11</span>
  2440. <span class="line-number">12</span>
  2441. <span class="line-number">13</span>
  2442. <span class="line-number">14</span>
  2443. <span class="line-number">15</span>
  2444. <span class="line-number">16</span>
  2445. <span class="line-number">17</span>
  2446. <span class="line-number">18</span>
  2447. <span class="line-number">19</span>
  2448. <span class="line-number">20</span>
  2449. <span class="line-number">21</span>
  2450. <span class="line-number">22</span>
  2451. <span class="line-number">23</span>
  2452. <span class="line-number">24</span>
  2453. <span class="line-number">25</span>
  2454. <span class="line-number">26</span>
  2455. <span class="line-number">27</span>
  2456. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
  2457. </span><span class="line"> <span class="n">NonReusableLoop</span><span class="p">();</span>
  2458. </span><span class="line"><span class="p">}</span>
  2459. </span><span class="line">
  2460. </span><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">NonReusableLoop</span><span class="p">()</span> <span class="p">{</span>
  2461. </span><span class="line"> <span class="kt">string</span> <span class="n">input</span> <span class="p">=</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
  2462. </span><span class="line"> <span class="kt">bool</span> <span class="n">done</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
  2463. </span><span class="line"> <span class="k">do</span> <span class="p">{</span>
  2464. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;Enter a web site to process. Press enter to end: &quot;</span><span class="p">);</span>
  2465. </span><span class="line"> <span class="n">input</span> <span class="p">=</span> <span class="n">Console</span><span class="p">.</span><span class="n">ReadLine</span><span class="p">();</span>
  2466. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="kt">string</span><span class="p">.</span><span class="n">IsNullOrEmpty</span><span class="p">(</span><span class="n">input</span><span class="p">))</span> <span class="p">{</span>
  2467. </span><span class="line"> <span class="n">done</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
  2468. </span><span class="line"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  2469. </span><span class="line"> <span class="n">ProcessWebSite</span><span class="p">(</span><span class="n">input</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span> <span class="c1">// don&#39;t really care about second parameter</span>
  2470. </span><span class="line"> <span class="p">}</span>
  2471. </span><span class="line"> <span class="p">}</span> <span class="k">while</span> <span class="p">(!</span><span class="n">done</span><span class="p">);</span>
  2472. </span><span class="line"><span class="p">}</span>
  2473. </span><span class="line">
  2474. </span><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">ProcessWebSite</span><span class="p">(</span><span class="kt">string</span> <span class="n">webSite</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">someOtherParameter</span><span class="p">)</span> <span class="p">{</span>
  2475. </span><span class="line"> <span class="c1">// Do some fake work</span>
  2476. </span><span class="line"> <span class="k">if</span> <span class="p">(!</span><span class="n">webSite</span><span class="p">.</span><span class="n">StartsWith</span><span class="p">(</span><span class="s">&quot;http://&quot;</span><span class="p">,</span> <span class="n">StringComparison</span><span class="p">.</span><span class="n">OrdinalIgnoreCase</span><span class="p">))</span> <span class="p">{</span>
  2477. </span><span class="line"> <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidOperationException</span><span class="p">(</span><span class="s">&quot;Poorly formed web site name&quot;</span><span class="p">);</span>
  2478. </span><span class="line"> <span class="p">}</span>
  2479. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Processing web site {0}&quot;</span><span class="p">,</span> <span class="n">webSite</span><span class="p">);</span>
  2480. </span><span class="line"> <span class="kt">var</span> <span class="n">rnd</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Random</span><span class="p">(</span><span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">.</span><span class="n">Millisecond</span><span class="p">);</span>
  2481. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Web site has {0:#,##0} pages!&quot;</span><span class="p">,</span> <span class="n">rnd</span><span class="p">.</span><span class="n">Next</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="m">1000</span><span class="p">));</span>
  2482. </span><span class="line"><span class="p">}</span>
  2483. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2484. <p>So lets say we want to extract something reusable out of this. Lets say we regularly churn up little console apps and were tired of writing this over and over again.</p>
  2485. <p>There are a couple of approaches that seem obvious you if youve got your functional thinking cap on. For example, this first pass looks like a function that does the interesting work (calls ProcessWebSite()) in the middle of a bunch of other stuff (getting user input, looping, checking for the quit condition). Lets go with that observation:</p>
  2486. <div class="bogus-wrapper"><notextile><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>
  2487. <span class="line-number">2</span>
  2488. <span class="line-number">3</span>
  2489. <span class="line-number">4</span>
  2490. <span class="line-number">5</span>
  2491. <span class="line-number">6</span>
  2492. <span class="line-number">7</span>
  2493. <span class="line-number">8</span>
  2494. <span class="line-number">9</span>
  2495. <span class="line-number">10</span>
  2496. <span class="line-number">11</span>
  2497. <span class="line-number">12</span>
  2498. <span class="line-number">13</span>
  2499. <span class="line-number">14</span>
  2500. <span class="line-number">15</span>
  2501. <span class="line-number">16</span>
  2502. <span class="line-number">17</span>
  2503. <span class="line-number">18</span>
  2504. <span class="line-number">19</span>
  2505. <span class="line-number">20</span>
  2506. <span class="line-number">21</span>
  2507. <span class="line-number">22</span>
  2508. <span class="line-number">23</span>
  2509. <span class="line-number">24</span>
  2510. <span class="line-number">25</span>
  2511. <span class="line-number">26</span>
  2512. <span class="line-number">27</span>
  2513. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
  2514. </span><span class="line"> <span class="n">ProcessUserInput</span><span class="p">(</span><span class="s">&quot;Enter a web site url&quot;</span><span class="p">,</span> <span class="n">input</span> <span class="p">=&gt;</span> <span class="n">ProcessWebSite</span><span class="p">(</span><span class="n">input</span><span class="p">,</span> <span class="k">true</span><span class="p">));</span>
  2515. </span><span class="line"><span class="p">}</span>
  2516. </span><span class="line">
  2517. </span><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">ProcessUserInput</span><span class="p">(</span><span class="kt">string</span> <span class="n">prompt</span><span class="p">,</span> <span class="n">Action</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">fn</span><span class="p">)</span> <span class="p">{</span>
  2518. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">fn</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
  2519. </span><span class="line"> <span class="kt">string</span> <span class="n">input</span> <span class="p">=</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
  2520. </span><span class="line"> <span class="kt">bool</span> <span class="n">done</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
  2521. </span><span class="line"> <span class="k">do</span> <span class="p">{</span>
  2522. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;{0}. Press enter to end: &quot;</span><span class="p">,</span> <span class="n">prompt</span><span class="p">);</span>
  2523. </span><span class="line"> <span class="n">input</span> <span class="p">=</span> <span class="n">Console</span><span class="p">.</span><span class="n">ReadLine</span><span class="p">();</span>
  2524. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="kt">string</span><span class="p">.</span><span class="n">IsNullOrEmpty</span><span class="p">(</span><span class="n">input</span><span class="p">))</span> <span class="p">{</span>
  2525. </span><span class="line"> <span class="n">done</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
  2526. </span><span class="line"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  2527. </span><span class="line"> <span class="k">try</span> <span class="p">{</span>
  2528. </span><span class="line"> <span class="n">fn</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
  2529. </span><span class="line"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">ex</span><span class="p">)</span> <span class="p">{</span>
  2530. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Exception thrown: {0}&quot;</span><span class="p">,</span> <span class="n">ex</span><span class="p">.</span><span class="n">Message</span><span class="p">);</span>
  2531. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;Show exception stack? (y/N):&quot;</span><span class="p">);</span>
  2532. </span><span class="line"> <span class="kt">var</span> <span class="n">exInput</span> <span class="p">=</span> <span class="n">Console</span><span class="p">.</span><span class="n">ReadLine</span><span class="p">();</span>
  2533. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">exInput</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;y&quot;</span><span class="p">,</span> <span class="n">StringComparison</span><span class="p">.</span><span class="n">OrdinalIgnoreCase</span><span class="p">))</span> <span class="p">{</span>
  2534. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">ex</span><span class="p">.</span><span class="n">ToString</span><span class="p">());</span>
  2535. </span><span class="line"> <span class="p">}</span>
  2536. </span><span class="line"> <span class="p">}</span>
  2537. </span><span class="line"> <span class="p">}</span>
  2538. </span><span class="line"> <span class="p">}</span> <span class="k">while</span> <span class="p">(!</span><span class="n">done</span><span class="p">);</span>
  2539. </span><span class="line"><span class="p">}</span>
  2540. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2541. <p>Now weve got a function that does the collection of the user strings, checking for the quit condition, and even adds some simple error handling to catch any exceptions that the work might throw. The parameter is an Action<string>. This is the .NET way of describing a function that returns void and has a single string parameter. This is a functional way of looking at the problem, because in functional programming passing functions around and working on functions is a fundamental technique. Getting used to doing this is a powerful tool.</string></p>
  2542. <p>But theres a better way of looking at it. What if we think of the strings the user is entering as a set of strings. We end up with something like this:</p>
  2543. <div class="bogus-wrapper"><notextile><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>
  2544. <span class="line-number">2</span>
  2545. <span class="line-number">3</span>
  2546. <span class="line-number">4</span>
  2547. <span class="line-number">5</span>
  2548. <span class="line-number">6</span>
  2549. <span class="line-number">7</span>
  2550. <span class="line-number">8</span>
  2551. <span class="line-number">9</span>
  2552. <span class="line-number">10</span>
  2553. <span class="line-number">11</span>
  2554. <span class="line-number">12</span>
  2555. <span class="line-number">13</span>
  2556. <span class="line-number">14</span>
  2557. <span class="line-number">15</span>
  2558. <span class="line-number">16</span>
  2559. <span class="line-number">17</span>
  2560. <span class="line-number">18</span>
  2561. <span class="line-number">19</span>
  2562. <span class="line-number">20</span>
  2563. <span class="line-number">21</span>
  2564. <span class="line-number">22</span>
  2565. <span class="line-number">23</span>
  2566. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
  2567. </span><span class="line"> <span class="n">ProcessStrings</span><span class="p">(</span>
  2568. </span><span class="line"> <span class="n">SetOfUserInput</span><span class="p">(</span><span class="s">&quot;Enter a web site url&quot;</span><span class="p">),</span>
  2569. </span><span class="line"> <span class="n">str</span> <span class="p">=&gt;</span> <span class="n">ProcessWebSite</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="k">true</span><span class="p">));</span>
  2570. </span><span class="line"><span class="p">}</span>
  2571. </span><span class="line">
  2572. </span><span class="line"><span class="k">static</span> <span class="k">void</span> <span class="nf">ProcessStrings</span><span class="p">(</span><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">setOfStrings</span><span class="p">,</span> <span class="n">Action</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">fn</span><span class="p">)</span> <span class="p">{</span>
  2573. </span><span class="line"> <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">item</span> <span class="k">in</span> <span class="n">setOfStrings</span><span class="p">)</span> <span class="n">fn</span><span class="p">(</span><span class="n">item</span><span class="p">);</span>
  2574. </span><span class="line"><span class="p">}</span>
  2575. </span><span class="line">
  2576. </span><span class="line"><span class="k">static</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">SetOfUserInput</span><span class="p">(</span><span class="kt">string</span> <span class="n">prompt</span><span class="p">)</span> <span class="p">{</span>
  2577. </span><span class="line"> <span class="kt">string</span> <span class="n">input</span> <span class="p">=</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
  2578. </span><span class="line"> <span class="kt">bool</span> <span class="n">done</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
  2579. </span><span class="line"> <span class="k">do</span> <span class="p">{</span>
  2580. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;{0}. Press enter to end: &quot;</span><span class="p">,</span> <span class="n">prompt</span><span class="p">);</span>
  2581. </span><span class="line"> <span class="n">input</span> <span class="p">=</span> <span class="n">Console</span><span class="p">.</span><span class="n">ReadLine</span><span class="p">();</span>
  2582. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="kt">string</span><span class="p">.</span><span class="n">IsNullOrEmpty</span><span class="p">(</span><span class="n">input</span><span class="p">))</span> <span class="p">{</span>
  2583. </span><span class="line"> <span class="n">done</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
  2584. </span><span class="line"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  2585. </span><span class="line"> <span class="k">yield</span> <span class="k">return</span> <span class="n">input</span><span class="p">;</span>
  2586. </span><span class="line"> <span class="p">}</span>
  2587. </span><span class="line"> <span class="p">}</span> <span class="k">while</span> <span class="p">(!</span><span class="n">done</span><span class="p">);</span>
  2588. </span><span class="line"><span class="p">}</span>
  2589. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2590. <p>Now weve got a function that returns a set of strings (IEnumerable<string> is the .NET way of saying a set of strings), and a function that takes a set of strings and applies a function to each member. The yield keyword makes the SetOfUserInput() method into a set. Each time the yield return keyword is hit, the value is passed out to the caller. When the caller attempts to retrieve the next value from the set, control is passed to the line after the yield return. This construct is called a continuation, and its a powerful concept.</string></p>
  2591. <p>These two simple concepts, that functions can be passed around and worked on, and that you can generate sets of data using continuations, are simple and fundamental to functional programming. But as these examples show you can use these techniques to your advantage in C#, solving real, every day problems.</p>
  2592. ]]></content>
  2593. </entry>
  2594. <entry>
  2595. <title type="html"><![CDATA[C# Nuts and Bolts: Delegates and Functions, Part I]]></title>
  2596. <link href="http://efvincent.github.io/blog/2009/08/24/nuts-bolts-delegates-functions-1/"/>
  2597. <updated>2009-08-24T23:32:21-04:00</updated>
  2598. <id>http://efvincent.github.io/blog/2009/08/24/nuts-bolts-delegates-functions-1</id>
  2599. <content type="html"><![CDATA[<p>Two years ago I took up the <a href="http://en.wikipedia.org/wiki/OCaml">OCaml</a> programming language, purely out of intellectual curiosity. For me, <a href="http://en.wikipedia.org/wiki/OCaml">OCaml</a> was a gateway drug to functional programming in general. Ive since spent a good bit of time with <a href="http://msdn.microsoft.com/en-us/fsharp/default.aspx">F#</a> and <a href="http://en.wikipedia.org/wiki/Haskell_(programming_language)">Haskell</a>. With the consulting work I do I dont have the opportunity to use these languages in production, but I have found that using these languages has unlocked a new worlds of problem solving techniques.</p>
  2600. <p>This series lays down a groundwork of C# understanding upon which we can build a library of modern problem solving techniques, where we take the most useful functional approaches, and see how to apply them to C# programming in .NET. Even if youve not any interest in functional programming, this series can be of service helping you understand some of the less obvious aspects of C# programming.
  2601. <!-- more --></p>
  2602. <h2 id="delegates">Delegates</h2>
  2603. <p>C++ has pointers to functions. C# has delegates. A <a href="http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx">delegate</a> is a .NET type that can be thought of as a type safe function pointer. A function pointer is a variable that instead of pointing to or containing data, points to a function. This variable can be used to invoke, or call, the function it is pointing at.</p>
  2604. <p><em>Type safe</em> refers to the fact that a delegate variable cannot point to just any function, it can only point to a function that matches the delegates <em>signature</em>. Signature refers to the parameters and return value of the function. Together, the parameters and return type form a fingerprint for a function which must match that the delegate.</p>
  2605. <p>In this example, a delegate is created at line 5 called <code>GetStatsDelegate </code>where the signature specifies a single <code>string</code> parameter and an <code>integer</code> return value. Judging from the name, the delegate should point to a function that gets some stats about a string.</p>
  2606. <div class="bogus-wrapper"><notextile><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>
  2607. <span class="line-number">2</span>
  2608. <span class="line-number">3</span>
  2609. <span class="line-number">4</span>
  2610. <span class="line-number">5</span>
  2611. <span class="line-number">6</span>
  2612. <span class="line-number">7</span>
  2613. <span class="line-number">8</span>
  2614. <span class="line-number">9</span>
  2615. <span class="line-number">10</span>
  2616. <span class="line-number">11</span>
  2617. <span class="line-number">12</span>
  2618. <span class="line-number">13</span>
  2619. <span class="line-number">14</span>
  2620. <span class="line-number">15</span>
  2621. <span class="line-number">16</span>
  2622. <span class="line-number">17</span>
  2623. <span class="line-number">18</span>
  2624. <span class="line-number">19</span>
  2625. <span class="line-number">20</span>
  2626. <span class="line-number">21</span>
  2627. <span class="line-number">22</span>
  2628. <span class="line-number">23</span>
  2629. <span class="line-number">24</span>
  2630. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">class</span> <span class="nc">Program</span>
  2631. </span><span class="line"><span class="p">{</span>
  2632. </span><span class="line"> <span class="c1">// define a delegate type for a function that takes a</span>
  2633. </span><span class="line"> <span class="c1">// string and returns an int</span>
  2634. </span><span class="line"> <span class="k">delegate</span> <span class="kt">int</span> <span class="nf">GetStatsDelegate</span><span class="p">(</span><span class="kt">string</span> <span class="n">str</span><span class="p">);</span>
  2635. </span><span class="line">
  2636. </span><span class="line"> <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  2637. </span><span class="line">
  2638. </span><span class="line"> <span class="c1">// Define a variable of our new delegate type, and</span>
  2639. </span><span class="line"> <span class="c1">// assign it a value. Any method with the same signature</span>
  2640. </span><span class="line"> <span class="c1">// can be assigned to this variable.</span>
  2641. </span><span class="line"> <span class="n">GetStatsDelegate</span> <span class="n">myFunc</span> <span class="p">=</span> <span class="n">GetLengthWithoutSpaces</span><span class="p">;</span>
  2642. </span><span class="line">
  2643. </span><span class="line"> <span class="c1">// Both these print 0</span>
  2644. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">myFunc</span><span class="p">(</span><span class="s">&quot;Hello&quot;</span><span class="p">));</span>
  2645. </span><span class="line"> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">GetLengthWithoutSpaces</span><span class="p">(</span><span class="s">&quot;Hello&quot;</span><span class="p">));</span>
  2646. </span><span class="line"> <span class="p">}</span>
  2647. </span><span class="line">
  2648. </span><span class="line"> <span class="c1">// This is a function that we can point to, because it has</span>
  2649. </span><span class="line"> <span class="c1">// the right signature for our delegate</span>
  2650. </span><span class="line"> <span class="k">public</span> <span class="k">static</span> <span class="kt">int</span> <span class="nf">GetLengthWithoutSpaces</span><span class="p">(</span><span class="kt">string</span> <span class="n">s</span><span class="p">)</span> <span class="p">{</span>
  2651. </span><span class="line"> <span class="k">return</span> <span class="m">0</span><span class="p">;</span>
  2652. </span><span class="line"> <span class="p">}</span>
  2653. </span><span class="line"><span class="p">}</span>
  2654. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2655. <p>At line 12 the delegate we created (which is a type) is used to define a variable, <code>myFunc</code>. We then set <code>myFuncs</code> value equal to <code>GetLengthWithoutSpaces</code>, which is a function. Lines 15 and 16 call the function, once using the delegate, and once the traditional way.<a href="http://blog.efvincent.com/wp-content/uploads/2009/08/image.png"><img src="http://blog.efvincent.com/wp-content/uploads/2009/08/image_thumb.png" alt="image" /></a></p>
  2656. <p>Heres where it starts to get interesting. This is a snip from <a href="http://www.red-gate.com/products/reflector/">Reflector</a>, looking at how <code>GetStatsDelegate</code> is defined.  We defined it as a delegate, but the compiler has built what looks like a standard class which inherits from the MulticastDelegate framework class.</p>
  2657. <p>This is good to know. C# treats delegates in a special way. Theyve been granted their own keyword and a special unique way of declaration. The declaration declares a subclass for us, saving us the trouble of building out a subclass ourselves. If we use Reflector to dig into the base class (System.Delegate), we see these properties and fields:</p>
  2658. <div class="bogus-wrapper"><notextile><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>
  2659. <span class="line-number">2</span>
  2660. <span class="line-number">3</span>
  2661. <span class="line-number">4</span>
  2662. <span class="line-number">5</span>
  2663. <span class="line-number">6</span>
  2664. <span class="line-number">7</span>
  2665. <span class="line-number">8</span>
  2666. <span class="line-number">9</span>
  2667. <span class="line-number">10</span>
  2668. <span class="line-number">11</span>
  2669. <span class="line-number">12</span>
  2670. <span class="line-number">13</span>
  2671. <span class="line-number">14</span>
  2672. <span class="line-number">15</span>
  2673. <span class="line-number">16</span>
  2674. <span class="line-number">17</span>
  2675. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="c1">// *** From Delegate ***</span>
  2676. </span><span class="line">
  2677. </span><span class="line"><span class="c1">// Properties</span>
  2678. </span><span class="line"><span class="k">public</span> <span class="n">MethodInfo</span> <span class="n">Method</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
  2679. </span><span class="line"><span class="k">public</span> <span class="kt">object</span> <span class="n">Target</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
  2680. </span><span class="line">
  2681. </span><span class="line"><span class="c1">// Fields</span>
  2682. </span><span class="line"><span class="k">internal</span> <span class="n">MethodBase</span> <span class="n">_methodBase</span><span class="p">;</span>
  2683. </span><span class="line"><span class="k">internal</span> <span class="n">IntPtr</span> <span class="n">_methodPtr</span><span class="p">;</span>
  2684. </span><span class="line"><span class="k">internal</span> <span class="n">IntPtr</span> <span class="n">_methodPtrAux</span><span class="p">;</span>
  2685. </span><span class="line"><span class="k">internal</span> <span class="kt">object</span> <span class="n">_target</span><span class="p">;</span>
  2686. </span><span class="line">
  2687. </span><span class="line"><span class="c1">// *** From MulticastDelegate ***</span>
  2688. </span><span class="line">
  2689. </span><span class="line"><span class="c1">// Fields</span>
  2690. </span><span class="line"><span class="k">private</span> <span class="n">IntPtr</span> <span class="n">_invocationCount</span><span class="p">;</span>
  2691. </span><span class="line"><span class="k">private</span> <span class="kt">object</span> <span class="n">_invocationList</span><span class="p">;</span>
  2692. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2693. <p>These fields tell us a few things. An instance of a delegate has reflection information about the method it points to, this is what the <code>MethodInfo</code> public property. The pointer to the function itself is of type <code>IntPtr</code>, which we can think about as a pointer to memory.</p>
  2694. <p>The <code>_target</code> field is important too. In the case of a delegate that points to an instance method (ie a non-static method on a non-null object), the <code>_target</code> field points to the object with the method. This is important because it is not obvious from looking at code that a delegate holds a reference to the object with the method. Its possible for this to be the source of memory leaks, where objects cannot be garbage collected because a delegate is holding a reference. You see this most often in events. Being delegates, events hold references that need to be <em>unregistered</em> in order to release these references.</p>
  2695. <p>Also we have something called <code>_invocationList</code>, which if we dig through the disassembly we come to find is an array of Delegates implemented as a linked list using pointers (<code>IntPtr</code>) directly for performance reasons. This means that <code>MulticastDelegates</code> are delegates that have a chain of additional delegates. This is used heavily in .NETs event mechanism, where an <em>event</em> can have multiple <em>handlers</em>. The handlers are simply functions wrapped in delegates added to the linked list of a the event <code>MulticastDelegate</code>.</p>
  2696. <p>Next post well look at using delegates, not as events (which anyone who has ever dropped a button on a form knows about), but as function pointers and objects, and start looking at some novel approaches to solving common problems.</p>
  2697. <p><em>As always if youve got questions or topics youd like me to follow up on, please leave a not in the comments!</em></p>
  2698. ]]></content>
  2699. </entry>
  2700. <entry>
  2701. <title type="html"><![CDATA[Adding Concurrency Optimization in Silverlight 3]]></title>
  2702. <link href="http://efvincent.github.io/blog/2009/08/18/concurrency-optimization-silverlight/"/>
  2703. <updated>2009-08-18T01:33:22-04:00</updated>
  2704. <id>http://efvincent.github.io/blog/2009/08/18/concurrency-optimization-silverlight</id>
  2705. <content type="html"><![CDATA[<p>About a week ago Joa Ebert posted <a href="http://blog.joa-ebert.com/2009/08/10/flirting-with-silverlight/">Flirting with Silverlight</a>, in which he discussed his experiences with a cool little Lorenz attractor application. The <em>strange attractor</em> app (which you can check at his <a href="http://blog.joa-ebert.com/2009/08/10/flirting-with-silverlight/">blog</a>) was his way of playing around with the newly released Silverlight 3 (Props to Joa for some very cool work BTW). It calculates a shape in 3D defined by some 300,000 particles, and animates the spinning and rotating of this shape as the user moves the mouse across the display surface.</p>
  2706. <p>His point was to relate his first Silverlight experience, and how the non-optimized Silverlight application compared very favorably with the significantly optimized AS3 version. The HTML5 Javascript version was a non-starter, barely able to achieve a few frames per second compared to 30 for AS3 and SL3.
  2707. <!-- more -->
  2708. Joa made <a href="http://blog.joa-ebert.com/2009/08/10/flirting-with-silverlight/">his code</a> available. After looking at the SL3 source code I thought it would be trivial to add some basic concurrency that would <em>significantly</em> increase performance. Heres a comparison of different implementations:</p>
  2709. <ul>
  2710. <li><a href="http://www.joa-ebert.com/swf/index.php?swf=alchemy/Example03">Flash AS3 Version</a>, Optimized</li>
  2711. <li><a href="http://www.joa-ebert.com/files/xpa/attractor/">Original Silverlight Version</a>, naive implementation</li>
  2712. <li><a href="http://efvincent.com/poc/strangeattractor/">Silverlight Version</a>, optimized to leverage Concurrency</li>
  2713. <li><a href="http://mediaerror.com/lab/javascript/strangeattractor">HTML 5 Version</a></li>
  2714. </ul>
  2715. <p>A point of interest, as far as I know there is <a href="http://blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.html">no way to do concurrency in Action Script 3</a>. In Joas application, the bulk of the hard work is done in a loop that executes every frame:</p>
  2716. <div class="bogus-wrapper"><notextile><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>
  2717. <span class="line-number">2</span>
  2718. <span class="line-number">3</span>
  2719. <span class="line-number">4</span>
  2720. <span class="line-number">5</span>
  2721. <span class="line-number">6</span>
  2722. <span class="line-number">7</span>
  2723. <span class="line-number">8</span>
  2724. <span class="line-number">9</span>
  2725. <span class="line-number">10</span>
  2726. <span class="line-number">11</span>
  2727. <span class="line-number">12</span>
  2728. <span class="line-number">13</span>
  2729. <span class="line-number">14</span>
  2730. <span class="line-number">15</span>
  2731. <span class="line-number">16</span>
  2732. <span class="line-number">17</span>
  2733. <span class="line-number">18</span>
  2734. <span class="line-number">19</span>
  2735. <span class="line-number">20</span>
  2736. <span class="line-number">21</span>
  2737. <span class="line-number">22</span>
  2738. <span class="line-number">23</span>
  2739. <span class="line-number">24</span>
  2740. <span class="line-number">25</span>
  2741. <span class="line-number">26</span>
  2742. <span class="line-number">27</span>
  2743. <span class="line-number">28</span>
  2744. <span class="line-number">29</span>
  2745. <span class="line-number">30</span>
  2746. <span class="line-number">31</span>
  2747. <span class="line-number">32</span>
  2748. <span class="line-number">33</span>
  2749. <span class="line-number">34</span>
  2750. <span class="line-number">35</span>
  2751. <span class="line-number">36</span>
  2752. <span class="line-number">37</span>
  2753. <span class="line-number">38</span>
  2754. <span class="line-number">39</span>
  2755. <span class="line-number">40</span>
  2756. <span class="line-number">41</span>
  2757. <span class="line-number">42</span>
  2758. <span class="line-number">43</span>
  2759. <span class="line-number">44</span>
  2760. <span class="line-number">45</span>
  2761. <span class="line-number">46</span>
  2762. <span class="line-number">47</span>
  2763. <span class="line-number">48</span>
  2764. <span class="line-number">49</span>
  2765. <span class="line-number">50</span>
  2766. <span class="line-number">51</span>
  2767. <span class="line-number">52</span>
  2768. <span class="line-number">53</span>
  2769. <span class="line-number">54</span>
  2770. <span class="line-number">55</span>
  2771. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">void</span> <span class="nf">OnStoryboardCompleted</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">EventArgs</span> <span class="n">eventArgs</span><span class="p">)</span>
  2772. </span><span class="line"><span class="p">{</span>
  2773. </span><span class="line"> <span class="n">targetX</span> <span class="p">+=</span> <span class="p">(</span><span class="n">mouseX</span> <span class="p">-</span> <span class="n">targetX</span><span class="p">)</span> <span class="p">*</span> <span class="m">0.1</span><span class="p">;</span>
  2774. </span><span class="line"> <span class="n">targetY</span> <span class="p">+=</span> <span class="p">(</span><span class="n">mouseY</span> <span class="p">-</span> <span class="n">targetY</span><span class="p">)</span> <span class="p">*</span> <span class="m">0.1</span><span class="p">;</span>
  2775. </span><span class="line">
  2776. </span><span class="line"> <span class="kt">var</span> <span class="n">index</span> <span class="p">=</span> <span class="n">MaxScreen</span><span class="p">;</span>
  2777. </span><span class="line"> <span class="kt">var</span> <span class="n">maxIndex</span> <span class="p">=</span> <span class="n">MaxScreen</span><span class="p">;</span>
  2778. </span><span class="line">
  2779. </span><span class="line"> <span class="k">while</span> <span class="p">(--</span><span class="n">index</span> <span class="p">&gt;</span> <span class="p">-</span><span class="m">1</span><span class="p">)</span>
  2780. </span><span class="line"> <span class="n">bitmap</span><span class="p">.</span><span class="n">Pixels</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">=</span> <span class="m">0</span><span class="n">x000000</span><span class="p">;</span>
  2781. </span><span class="line">
  2782. </span><span class="line"> <span class="kt">var</span> <span class="n">particle</span> <span class="p">=</span> <span class="n">particles</span><span class="p">;</span>
  2783. </span><span class="line"> <span class="kt">var</span> <span class="n">matrix</span> <span class="p">=</span> <span class="n">Matrix4x4</span><span class="p">.</span><span class="n">RotationY</span><span class="p">(</span><span class="n">targetX</span> <span class="p">*</span> <span class="m">0.05</span><span class="p">)</span> <span class="p">*</span> <span class="n">Matrix4x4</span><span class="p">.</span><span class="n">RotationX</span><span class="p">(</span><span class="n">targetY</span> <span class="p">*</span> <span class="m">0.05</span><span class="p">)</span> <span class="p">*</span> <span class="n">translationMatrix</span><span class="p">;</span>
  2784. </span><span class="line">
  2785. </span><span class="line"> <span class="kt">var</span> <span class="n">cx</span> <span class="p">=</span> <span class="m">275.0</span><span class="p">;</span>
  2786. </span><span class="line"> <span class="kt">var</span> <span class="n">cy</span> <span class="p">=</span> <span class="m">200.0</span><span class="p">;</span>
  2787. </span><span class="line">
  2788. </span><span class="line"> <span class="kt">var</span> <span class="n">w</span> <span class="p">=</span> <span class="m">0.0</span><span class="p">;</span>
  2789. </span><span class="line"> <span class="kt">var</span> <span class="n">xi</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
  2790. </span><span class="line"> <span class="kt">var</span> <span class="n">yi</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
  2791. </span><span class="line"> <span class="kt">var</span> <span class="n">x</span> <span class="p">=</span> <span class="m">0.0</span><span class="p">;</span>
  2792. </span><span class="line"> <span class="kt">var</span> <span class="n">y</span> <span class="p">=</span> <span class="m">0.0</span><span class="p">;</span>
  2793. </span><span class="line"> <span class="kt">var</span> <span class="n">z</span> <span class="p">=</span> <span class="m">0.0</span><span class="p">;</span>
  2794. </span><span class="line"> <span class="kt">var</span> <span class="n">pz</span> <span class="p">=</span> <span class="m">0.0</span><span class="p">;</span>
  2795. </span><span class="line">
  2796. </span><span class="line"> <span class="k">while</span> <span class="p">(</span><span class="k">null</span> <span class="p">!=</span> <span class="n">particle</span><span class="p">)</span>
  2797. </span><span class="line"> <span class="p">{</span>
  2798. </span><span class="line"> <span class="n">x</span> <span class="p">=</span> <span class="n">particle</span><span class="p">.</span><span class="n">X</span><span class="p">;</span>
  2799. </span><span class="line"> <span class="n">y</span> <span class="p">=</span> <span class="n">particle</span><span class="p">.</span><span class="n">Y</span><span class="p">;</span>
  2800. </span><span class="line"> <span class="n">z</span> <span class="p">=</span> <span class="n">particle</span><span class="p">.</span><span class="n">Z</span><span class="p">;</span>
  2801. </span><span class="line">
  2802. </span><span class="line"> <span class="n">pz</span> <span class="p">=</span> <span class="n">focalLength</span> <span class="p">+</span> <span class="n">x</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I02</span> <span class="p">+</span> <span class="n">y</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I12</span> <span class="p">+</span> <span class="n">z</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I22</span> <span class="p">+</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I32</span><span class="p">;</span>
  2803. </span><span class="line">
  2804. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="m">0.0</span> <span class="p">&lt;</span> <span class="n">pz</span><span class="p">)</span>
  2805. </span><span class="line"> <span class="p">{</span>
  2806. </span><span class="line"> <span class="n">xi</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)(</span> <span class="p">(</span> <span class="n">w</span> <span class="p">=</span> <span class="n">focalLength</span> <span class="p">/</span> <span class="n">pz</span> <span class="p">)</span> <span class="p">*</span> <span class="p">(</span> <span class="n">x</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I00</span> <span class="p">+</span> <span class="n">y</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I10</span> <span class="p">+</span> <span class="n">z</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I20</span> <span class="p">)</span> <span class="p">+</span> <span class="n">cx</span> <span class="p">);</span>
  2807. </span><span class="line"> <span class="n">yi</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)(</span> <span class="n">w</span> <span class="p">*</span> <span class="p">(</span> <span class="n">x</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I01</span> <span class="p">+</span> <span class="n">y</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I11</span> <span class="p">+</span> <span class="n">z</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I21</span> <span class="p">)</span> <span class="p">+</span> <span class="n">cy</span> <span class="p">);</span>
  2808. </span><span class="line">
  2809. </span><span class="line"> <span class="n">index</span> <span class="p">=</span> <span class="n">xi</span> <span class="p">+</span> <span class="n">yi</span> <span class="p">*</span> <span class="n">ScreenWidth</span><span class="p">;</span>
  2810. </span><span class="line">
  2811. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">index</span> <span class="p">&gt;</span> <span class="p">-</span><span class="m">1</span> <span class="p">&amp;&amp;</span> <span class="n">index</span> <span class="p">&lt;</span> <span class="n">maxIndex</span><span class="p">)</span>
  2812. </span><span class="line"> <span class="p">{</span>
  2813. </span><span class="line"> <span class="kt">var</span> <span class="n">color</span> <span class="p">=</span> <span class="n">bitmap</span><span class="p">.</span><span class="n">Pixels</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">+</span> <span class="m">0</span><span class="n">x202020</span><span class="p">;</span>
  2814. </span><span class="line"> <span class="n">bitmap</span><span class="p">.</span><span class="n">Pixels</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">=</span> <span class="n">color</span> <span class="p">&gt;</span> <span class="m">0</span><span class="n">xffffff</span> <span class="p">?</span> <span class="m">0</span><span class="n">xffffff</span> <span class="p">:</span> <span class="n">color</span><span class="p">;</span>
  2815. </span><span class="line"> <span class="p">}</span>
  2816. </span><span class="line"> <span class="p">}</span>
  2817. </span><span class="line">
  2818. </span><span class="line"> <span class="n">particle</span> <span class="p">=</span> <span class="n">particle</span><span class="p">.</span><span class="n">Next</span><span class="p">;</span>
  2819. </span><span class="line"> <span class="p">}</span>
  2820. </span><span class="line">
  2821. </span><span class="line"> <span class="n">bitmap</span><span class="p">.</span><span class="n">Invalidate</span><span class="p">();</span>
  2822. </span><span class="line">
  2823. </span><span class="line"> <span class="n">storyboard</span><span class="p">.</span><span class="n">Begin</span><span class="p">();</span>
  2824. </span><span class="line"> <span class="p">}</span>
  2825. </span><span class="line"><span class="p">}</span>
  2826. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2827. <p>What hes doing here is writing pixels into a bitmap. At line 9, he sets all the pixels to zero (black), erasing the previous frame. At line 23 he starts a loop that will calculate each pixel that should be turned on for the upcoming frame. In both these cases hes dealing with a one dimensional array of pixels. This is the perfect case for data parallelism. The work of setting pixels can be divided between processors.</p>
  2828. <p>In general, concurrency is not a simple technique to implement correctly. The number and type of problems that one can run into are <strong>way</strong> beyond the scope of anything short of a very thick book. But this perhaps the simplest case; simple <em>static composition data parallelism</em>. Its static because you can pre-assign the amount of work each thread will do. Its data parallelism because each thread will be doing the same kind of work (calculating and flipping pixels), as opposed to a solution where one thread does one thing (like talk on the network) while another thread does something else (like shred xml files).</p>
  2829. <p>We get this done by building a function that behaves like a <code>For()</code> loop, but executes the body in parallel between several threads. If youve played with the recently released Visual Studio 2010 beta that has the .NET 4.0 framework, youll recognize this function which is in the next version of the framework (but in a far more sophisticated and powerful form).</p>
  2830. <div class="bogus-wrapper"><notextile><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>
  2831. <span class="line-number">2</span>
  2832. <span class="line-number">3</span>
  2833. <span class="line-number">4</span>
  2834. <span class="line-number">5</span>
  2835. <span class="line-number">6</span>
  2836. <span class="line-number">7</span>
  2837. <span class="line-number">8</span>
  2838. <span class="line-number">9</span>
  2839. <span class="line-number">10</span>
  2840. <span class="line-number">11</span>
  2841. <span class="line-number">12</span>
  2842. <span class="line-number">13</span>
  2843. <span class="line-number">14</span>
  2844. <span class="line-number">15</span>
  2845. <span class="line-number">16</span>
  2846. <span class="line-number">17</span>
  2847. <span class="line-number">18</span>
  2848. <span class="line-number">19</span>
  2849. <span class="line-number">20</span>
  2850. <span class="line-number">21</span>
  2851. <span class="line-number">22</span>
  2852. <span class="line-number">23</span>
  2853. <span class="line-number">24</span>
  2854. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">void</span> <span class="nf">ParallelFor</span><span class="p">(</span><span class="kt">int</span> <span class="n">lo</span><span class="p">,</span> <span class="kt">int</span> <span class="n">hi</span><span class="p">,</span> <span class="n">Action</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">body</span><span class="p">,</span> <span class="kt">int</span> <span class="n">p</span><span class="p">)</span>
  2855. </span><span class="line"><span class="p">{</span>
  2856. </span><span class="line"> <span class="kt">int</span> <span class="n">chunk</span> <span class="p">=</span> <span class="p">(</span><span class="n">hi</span> <span class="p">-</span> <span class="n">lo</span><span class="p">)</span> <span class="p">/</span> <span class="n">p</span><span class="p">;</span> <span class="c1">// Iterations per thread</span>
  2857. </span><span class="line">
  2858. </span><span class="line"> <span class="n">AutoResetEvent</span><span class="p">[]</span> <span class="n">latch</span> <span class="p">=</span> <span class="k">new</span> <span class="n">AutoResetEvent</span><span class="p">[</span><span class="n">p</span><span class="p">];</span>
  2859. </span><span class="line"> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">p</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span> <span class="n">latch</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">=</span> <span class="k">new</span> <span class="n">AutoResetEvent</span><span class="p">(</span><span class="k">false</span><span class="p">);</span>
  2860. </span><span class="line">
  2861. </span><span class="line"> <span class="c1">// Schedule the events to run in parallel</span>
  2862. </span><span class="line"> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">p</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
  2863. </span><span class="line"> <span class="p">{</span>
  2864. </span><span class="line"> <span class="n">ThreadPool</span><span class="p">.</span><span class="n">QueueUserWorkItem</span><span class="p">((</span><span class="n">ob</span><span class="p">)</span> <span class="p">=&gt;</span>
  2865. </span><span class="line"> <span class="p">{</span>
  2866. </span><span class="line"> <span class="kt">int</span> <span class="n">pid</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">ob</span><span class="p">;</span>
  2867. </span><span class="line"> <span class="kt">int</span> <span class="n">start</span> <span class="p">=</span> <span class="n">lo</span> <span class="p">+</span> <span class="n">pid</span> <span class="p">*</span> <span class="n">chunk</span><span class="p">;</span>
  2868. </span><span class="line"> <span class="kt">int</span> <span class="n">end</span> <span class="p">=</span> <span class="n">pid</span> <span class="p">==</span> <span class="n">p</span> <span class="p">-</span> <span class="m">1</span> <span class="p">?</span> <span class="n">hi</span> <span class="p">:</span> <span class="n">start</span> <span class="p">+</span> <span class="n">chunk</span><span class="p">;</span>
  2869. </span><span class="line"> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="p">=</span> <span class="n">start</span><span class="p">;</span> <span class="n">j</span> <span class="p">&lt;</span> <span class="n">end</span><span class="p">;</span> <span class="n">j</span><span class="p">++)</span>
  2870. </span><span class="line"> <span class="p">{</span>
  2871. </span><span class="line"> <span class="n">body</span><span class="p">(</span><span class="n">j</span><span class="p">);</span>
  2872. </span><span class="line"> <span class="p">}</span>
  2873. </span><span class="line"> <span class="n">latch</span><span class="p">[</span><span class="n">pid</span><span class="p">].</span><span class="n">Set</span><span class="p">();</span>
  2874. </span><span class="line"> <span class="p">},</span> <span class="n">i</span><span class="p">);</span>
  2875. </span><span class="line"> <span class="p">}</span>
  2876. </span><span class="line"> <span class="n">WaitHandle</span><span class="p">.</span><span class="n">WaitAll</span><span class="p">(</span><span class="n">latch</span><span class="p">);</span>
  2877. </span><span class="line"><span class="p">}</span>
  2878. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2879. <p>ParallelFor() takes lo and hi values, an <code>Action&lt;int&gt;</code>, and the degree of desired parallelism. The <code>Action&lt;int&gt; </code>is a delegate, which is like a pointer to a function. In this case, its a pointer to a function that has a single int parameter, and returns void. This function is the work that happens every iteration. Silverlight, .NET, and C# make it possible (I think its easy, but Ive been doing this a while) to use anonymous methods and what amount to functional techniques to make Joas code multithreaded.  It may be best to illustrate by example.</p>
  2880. <div class="bogus-wrapper"><notextile><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>
  2881. <span class="line-number">2</span>
  2882. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="k">while</span> <span class="p">(--</span><span class="n">index</span> <span class="p">&gt;</span> <span class="p">-</span><span class="m">1</span><span class="p">)</span>
  2883. </span><span class="line"> <span class="n">bitmap</span><span class="p">.</span><span class="n">Pixels</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">=</span> <span class="m">0</span><span class="n">x000000</span><span class="p">;</span>
  2884. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2885. <p>Joas code above, which initializes the pixels in the bitmap, becomes:</p>
  2886. <div class="bogus-wrapper"><notextile><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>
  2887. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="n">ParallelFor</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">buffer</span><span class="p">.</span><span class="n">Pixels</span><span class="p">.</span><span class="n">Length</span><span class="p">,</span> <span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="n">buffer</span><span class="p">.</span><span class="n">Pixels</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">=</span> <span class="m">0</span><span class="n">x0</span><span class="p">,</span> <span class="n">numComputationThreads</span><span class="p">);</span>
  2888. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2889. <p>The parameters of ParallelFor are zero for where to start the for loop, Pixels.Length for where to end the loop, the lambda <code>function (i) =&gt; buffer.Pixels[i] = 0x0</code>, and the number of threads to use to do the work. The lambda function is anonymous (i.e. we dont have to create a function with a name). The type of i is <em>inferred</em> from context to be an int. The body of the lambda (the part after the =&gt;), is the work that is done each time through the loop.</p>
  2890. <p>This makes the clearing of last frames bitmap concurrent. To make the rendering of the next frame concurrent is a bit more invasive, but still not bad. Heres the concurrent version.</p>
  2891. <div class="bogus-wrapper"><notextile><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>
  2892. <span class="line-number">2</span>
  2893. <span class="line-number">3</span>
  2894. <span class="line-number">4</span>
  2895. <span class="line-number">5</span>
  2896. <span class="line-number">6</span>
  2897. <span class="line-number">7</span>
  2898. <span class="line-number">8</span>
  2899. <span class="line-number">9</span>
  2900. <span class="line-number">10</span>
  2901. <span class="line-number">11</span>
  2902. <span class="line-number">12</span>
  2903. <span class="line-number">13</span>
  2904. <span class="line-number">14</span>
  2905. <span class="line-number">15</span>
  2906. <span class="line-number">16</span>
  2907. <span class="line-number">17</span>
  2908. <span class="line-number">18</span>
  2909. <span class="line-number">19</span>
  2910. <span class="line-number">20</span>
  2911. <span class="line-number">21</span>
  2912. <span class="line-number">22</span>
  2913. <span class="line-number">23</span>
  2914. <span class="line-number">24</span>
  2915. <span class="line-number">25</span>
  2916. <span class="line-number">26</span>
  2917. <span class="line-number">27</span>
  2918. <span class="line-number">28</span>
  2919. <span class="line-number">29</span>
  2920. <span class="line-number">30</span>
  2921. <span class="line-number">31</span>
  2922. <span class="line-number">32</span>
  2923. <span class="line-number">33</span>
  2924. </pre></td><td class="code"><pre><code class="C#"><span class="line"><span class="n">ParallelFor</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">particles</span><span class="p">.</span><span class="n">Length</span><span class="p">,</span> <span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="p">=&gt;</span>
  2925. </span><span class="line"><span class="p">{</span>
  2926. </span><span class="line"> <span class="n">Particle</span> <span class="n">part</span> <span class="p">=</span> <span class="n">particles</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
  2927. </span><span class="line"> <span class="kt">var</span> <span class="n">x</span> <span class="p">=</span> <span class="n">part</span><span class="p">.</span><span class="n">X</span><span class="p">;</span>
  2928. </span><span class="line"> <span class="kt">var</span> <span class="n">y</span> <span class="p">=</span> <span class="n">part</span><span class="p">.</span><span class="n">Y</span><span class="p">;</span>
  2929. </span><span class="line"> <span class="kt">var</span> <span class="n">z</span> <span class="p">=</span> <span class="n">part</span><span class="p">.</span><span class="n">Z</span><span class="p">;</span>
  2930. </span><span class="line">
  2931. </span><span class="line"> <span class="kt">var</span> <span class="n">w</span> <span class="p">=</span> <span class="m">0.0</span><span class="p">;</span>
  2932. </span><span class="line"> <span class="kt">var</span> <span class="n">xi</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
  2933. </span><span class="line"> <span class="kt">var</span> <span class="n">yi</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
  2934. </span><span class="line">
  2935. </span><span class="line"> <span class="kt">var</span> <span class="n">pz</span> <span class="p">=</span> <span class="n">focalLength</span> <span class="p">+</span> <span class="n">x</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I02</span> <span class="p">+</span> <span class="n">y</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I12</span> <span class="p">+</span> <span class="n">z</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I22</span> <span class="p">+</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I32</span><span class="p">;</span>
  2936. </span><span class="line">
  2937. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="m">0.0</span> <span class="p">&lt;</span> <span class="n">pz</span><span class="p">)</span>
  2938. </span><span class="line"> <span class="p">{</span>
  2939. </span><span class="line"> <span class="n">xi</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)((</span><span class="n">w</span> <span class="p">=</span> <span class="n">focalLength</span> <span class="p">/</span> <span class="n">pz</span><span class="p">)</span> <span class="p">*</span> <span class="p">(</span><span class="n">x</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I00</span> <span class="p">+</span> <span class="n">y</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I10</span> <span class="p">+</span> <span class="n">z</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I20</span><span class="p">)</span> <span class="p">+</span> <span class="n">cx</span><span class="p">);</span>
  2940. </span><span class="line"> <span class="n">yi</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)(</span><span class="n">w</span> <span class="p">*</span> <span class="p">(</span><span class="n">x</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I01</span> <span class="p">+</span> <span class="n">y</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I11</span> <span class="p">+</span> <span class="n">z</span> <span class="p">*</span> <span class="n">matrix</span><span class="p">.</span><span class="n">I21</span><span class="p">)</span> <span class="p">+</span> <span class="n">cy</span><span class="p">);</span>
  2941. </span><span class="line">
  2942. </span><span class="line"> <span class="kt">var</span> <span class="n">index</span> <span class="p">=</span> <span class="n">xi</span> <span class="p">+</span> <span class="n">yi</span> <span class="p">*</span> <span class="n">ScreenWidth</span><span class="p">;</span>
  2943. </span><span class="line">
  2944. </span><span class="line"> <span class="k">if</span> <span class="p">(</span><span class="n">index</span> <span class="p">&gt;</span> <span class="p">-</span><span class="m">1</span> <span class="p">&amp;&amp;</span> <span class="n">index</span> <span class="p">&lt;</span> <span class="n">maxIndex</span><span class="p">)</span>
  2945. </span><span class="line"> <span class="p">{</span>
  2946. </span><span class="line"> <span class="kt">var</span> <span class="n">color</span> <span class="p">=</span> <span class="n">buffer</span><span class="p">.</span><span class="n">Pixels</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">+</span> <span class="m">0</span><span class="n">x202020</span><span class="p">;</span>
  2947. </span><span class="line"> <span class="n">buffer</span><span class="p">.</span><span class="n">Pixels</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">=</span> <span class="n">color</span> <span class="p">&gt;</span> <span class="m">0</span><span class="n">xffffff</span> <span class="p">?</span> <span class="m">0</span><span class="n">xffffff</span> <span class="p">:</span> <span class="n">color</span><span class="p">;</span>
  2948. </span><span class="line"> <span class="p">}</span>
  2949. </span><span class="line"> <span class="p">}</span>
  2950. </span><span class="line">
  2951. </span><span class="line"><span class="p">},</span> <span class="n">numComputationThreads</span><span class="p">);</span>
  2952. </span><span class="line">
  2953. </span><span class="line"><span class="n">buffer</span><span class="p">.</span><span class="n">Invalidate</span><span class="p">();</span>
  2954. </span><span class="line"><span class="n">lastRender</span> <span class="p">=</span> <span class="n">elapsed</span><span class="p">;</span>
  2955. </span><span class="line">
  2956. </span><span class="line"><span class="p">}</span>
  2957. </span></code></pre></td></tr></table></div></figure></notextile></div>
  2958. <p>There are a few changes that I made to make the optimization a bit easier. Joa used a linked list of particles, I captured an array, just because it was a bit easier to make concurrent. But the significant difference is the body of Joas loop is now in an anonymous function. Values that will change in the body of the loop are now defined in the loop (x,y,z, etc). This is because if the loop used the variables defined outside the lambda, then the different threads would try to use the same variables as one another, which is obviously a problem. Other than that, the code is pretty much the same.</p>
  2959. <p>So how much of an improvement is there? Yea, a lot. I put a frame counter on Joas original code and on my MBP dual Core Duo 2.4Ghz 4Gig ram running Windows 7 release, it was getting about 30 frames per second. On OS X it was about the same. With the concurrency, and set to use 4 threads, it got up to 45 fps. On my quad core Dell M6400 Core 2 Exreme Q9300 at 2.54 Ghz with 8gig ram, it went up to 65 fps. If found it was best to use more threads then you have cores. So 4 threads was good on the dual core, 8 on the quad core.</p>
  2960. <p>Of course, this means the app will absolutely peg the processor, which is good if you want max speed. But you can also throttle the frame rate back, say hold it at 30, and use less processor to get the same fps as the original.</p>
  2961. <p>Silverlight 3 has caused a bit of a splash in the RIA community if the Twitter chatter is any indication. There is some venomous talk out there; you know the such and such tech sucks, such and such tech rules, and of course Microsoft is evil. I choose to stay out of that fray, perhaps its hitting 40 that did it. I dont care to argue with Fanbois. I will say that the the community will discover that the .NET framework and C# (even VB.NET) make for a serious development platform that will benefit the community at large. Its a very good time to be a developer!</p>
  2962. <p>Heres a link to a zip file containing my version of the project: <a href="https://skydrive.live.com/?cid=db16741b8ce498b0#">Strange Attractor Project</a></p>
  2963. <p>Would you like to see the concepts in this post expanded? Want to know more about concurrency, functional patterns, generics? Leave me a note in the comments or send me a Twitter reply at @efvincent. Oh, and thanks for reading!</p>
  2964. ]]></content>
  2965. </entry>
  2966. </feed>