<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>codeface</title>
	<atom:link href="http://blog.markrendle.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.markrendle.net</link>
	<description>on making software</description>
	<lastBuildDate>Wed, 23 May 2012 11:52:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.markrendle.net' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>codeface</title>
		<link>http://blog.markrendle.net</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.markrendle.net/osd.xml" title="codeface" />
	<atom:link rel='hub' href='http://blog.markrendle.net/?pushpress=hub'/>
		<item>
		<title>The Three Little Pigs (Redux)</title>
		<link>http://blog.markrendle.net/2012/05/11/the-three-little-pigs-redux/</link>
		<comments>http://blog.markrendle.net/2012/05/11/the-three-little-pigs-redux/#comments</comments>
		<pubDate>Fri, 11 May 2012 13:50:30 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=302</guid>
		<description><![CDATA[Once upon a time there were three little pigs who were all grown up and ready to strike out on their own. As they left their childhood home, their dear old mother warned them to look out for the Big Bad Wolf, who was at large in the area and hungry for little pig meat. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=302&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Once upon a time there were three little pigs who were all grown up and ready to strike out on their own. As they left their childhood home, their dear old mother warned them to look out for the Big Bad Wolf, who was at large in the area and hungry for little pig meat.</p>
<p>The first little pig was lazy and frivolous, so he built his house out of straw. When the Big Bad Wolf arrived, he huffed and he puffed and he blew the house down, and ate the little pig, because this is the Grimm version.</p>
<p>The second little pig was very serious, so he decided to engage a large consultancy firm to handle the building of his house for him. The consultancy firm assigned four of their best Big Fat Pigs to the project, and they scheduled a very expensive meeting with the little pig to discuss requirements. The little pig told them he wanted a nice, comfortable house with modern conveniences which would keep the Big Bad Wolf at bay. The Big Fat Pigs told the little pig that he should plan ahead more, and recommended that he build a large skyscraper in case he ever decided to run a multi-national corporation from the house. The little pig worried that this would be expensive, but the big fat pigs assured him that costs would be kept down by using cost-effective materials and off-shoring the actual building of the skyscraper. The little pig didn&#8217;t really understand much about building houses, and the big fat pigs seemed to be very clever and had lots of experience, so he signed a very long contract and waited for his skyscraper. Two months later the Big Fat Pigs came back to tell the little pig that they had had a pre-pre-meeting meeting meeting, and had clearly defined an early draft of the project plan. In only eight months they would have the final draft of The Plan, and would be ready to select an architect, who would then submit three different designs for the skyscraper along with thousands of pages of documentation detailing the wolf-proofing measures, so the little pig could be absolutely sure he was going to get the very bestest skyscraper that had ever been built. The Big Fat Pigs had a Gantt chart that covered three years and 142 participants and stakeholders, all with clearly defined activities and responsibilities so they knew exactly where they would be and what they would be doing at any time over the three year project. The Gantt chart was printed in colour on A0 paper and everything.</p>
<p>Sadly, the little pig never got to see the beautiful Gantt chart, because he had been eaten by the Big Bad Wolf. Luckily for the Big Fat Pigs, a clause in the contract he had signed meant that the project could continue in spite of his death, so they carried on. Nine years later, as the final prefabricated part of the skyscraper was fitted for the seventh time (because the previous six parts had not fitted correctly when they arrived from the land far away), the entire skyscraper collapsed because, it turned out, it had been built from substandard parts made from cheap materials in several different countries by unqualified workers who were working from different versions of the design document, which was two thousand pages long. Oh, and somebody had forgotten to dig the foundations, but by the time this was noticed, it was too late to do anything about it, so a complicated system of tensile steel cables and tent pegs was added to the base of the skyscraper to stop it falling over. </p>
<p>(The Big Fat Pigs were very surprised when the tent pegs didn&#8217;t work, despite the fact that they had used the same idea on every project they&#8217;d ever done and it had never worked. They thought maybe it would work next time, if they incorporated the learnings from this project.)</p>
<p>The local council insisted that the little pig&#8217;s family clean up the mess that the collapsing skyscraper had created, and make good the damage to neighbouring properties. The Big Fat Pigs put in a tender for the clean-up project, and got it. That was four years ago. The rusting remains of the skyscraper are still where they landed; the Big Fat Pigs have succeeded in designing a new system for reporting on the progress of the clean-up operation, and are currently waiting for executive approval so that they can move on to the pseudo code stage.</p>
<p>The third little pig hired a really smart architect, who knew a very good builder. The little pig told them he needed a house to protect him from the wolf, so the architect drew up a simple, strong design and the builder built it. After he had moved in, the little pig wanted some improvements, so he went back to the architect and the builder to ask for them. Because the house was very simple, and the builder had built it properly, they were able to make the new improvements quickly and easily, and the third little pig lived happily ever after.</p>
<p>THE END</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/302/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=302&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2012/05/11/the-three-little-pigs-redux/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>&#8220;Pity&#8221;, ninjas, and how not to suck</title>
		<link>http://blog.markrendle.net/2012/04/23/pity-ninjas-and-how-not-to-suck/</link>
		<comments>http://blog.markrendle.net/2012/04/23/pity-ninjas-and-how-not-to-suck/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 15:30:13 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[professional]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[501 developers]]></category>
		<category><![CDATA[craftsmanship]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=296</guid>
		<description><![CDATA[TL;DR Another post giving the 501 Developer Manifesto more attention than it deserves. I honestly wouldn’t waste my time reading it if I were you. … Why are you still here? If you’ve seriously got nothing better to do than read this, I pity you. I really, really pity you. Because you’re pitiable. “Pity” is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=296&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>TL;DR</h3>
<p><em>Another post giving the </em><a href="http://501manifesto.org/" target="_blank"><em>501 Developer Manifesto</em></a><em> more attention than it deserves. I honestly wouldn’t waste my time reading it if I were you.</em></p>
<p><em>…</em></p>
<p><em>Why are you still here? If you’ve seriously got nothing better to do than read this, I pity you. I really, really pity you. Because you’re </em><a href="http://thesaurus.com/browse/pitiable" target="_blank"><em>pitiable</em></a><em>.</em></p>
<h3>“Pity” is a derogatory word</h3>
<p>Let’s get this one out of the way for a start. There’s a reason why “I don’t want your pity” is one of the hallmark clichés of badly written dialogue. If there is <a href="http://501manifesto.org/" target="_blank">probably some pity in</a> your attitude toward someone, it implies that you feel lucky not to be that person; that their situation is deficient in some way that yours is not. If you are making specific reference to an aspect of that someone’s life that they consider important and special and even defining, then you shouldn’t be surprised when they are insulted, and <a href="http://news.ycombinator.com/item?id=3854565" target="_blank">paraphrase Fight Club in Hacker News comments</a>.</p>
<h3>A clarification of terms</h3>
<p>I shouldn’t really need to write this, as <a href="http://www.hanselman.com/blog/501DevelopersFamilyAndExcitementAboutTheCraft.aspx" target="_blank">this post on Scott Hanselman’s blog</a> (the first link on the 501 Manifesto page) explains very clearly what is intended by the epithet “501 developer”. It has nothing to do with what time you leave work, or how hard you work while you are there. Being a 501 developer means that you have no great enthusiasm for your work; no desire to learn new and interesting things; no ambition within your chosen career. It means you’re probably just grinding the levels until you get to a better-paid management role, which you will then carry out very badly because you don’t really understand thing one about software development.</p>
<p><em>If you:</em></p>
<ul>
<li><em>Never read technical blogs</em></li>
<li><em>Are not aware of open source projects (unless they’re forced on you at work)</em></li>
<li><em>Have never attended any kind of developer-focused event</em></li>
<li><em>Don’t own any books about coding or productivity</em></li>
<li><em>Aren’t quite sure why Github is called Github</em></li>
<li><em>Couldn’t* care less about trying to be better at your job</em></li>
</ul>
<p><em>…then you are a 501 developer, and no, we don’t respect you for it. If you do <strong>any</strong> of those things, you’re not a 501 developer, regardless of what time you leave work, and I respect you as a professional and as a human being.</em></p>
<p><em><font size="1">*Yes, Americans, the term is “couldn’t care less”. “I could care less” means “I care”.</font></em></p>
<p>It is perfectly possible to arrive at work at 9am, leave work at 5 or 5:30pm, and yet still read blogs and discuss software development on the internet and follow internet-famous software people Twitter and go to your local user group when there’s a speaker talking about something that interests you and read <a href="http://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank"><em>Clean Code</em></a><em> </em>and maybe do a little bit of extra-curricular coding with something new, and still spend plenty of time with your family and <a href="http://501manifesto.org/blog/?p=18" target="_blank">your Moog synthesiser and collection of blank cassette tapes</a>. </p>
<p>That’s the real issue here, is that by taking the time to register a domain and create a web page and attach a blog to it, and by linking to <a href="http://www.hanselman.com/blog/" target="_blank">Computer Zen</a> and <a href="http://www.codinghorror.com/blog/" target="_blank">Coding Horror</a> and making apparent his knowledge of the Agile manifesto, the author of the 501 manifesto has identified himself as anything but a 501 developer. Maybe the problem is that he’s lucky enough to have never worked with an actual 501 developer, in a massive room full of 501 developers for a 501 company in a 501 vertical market, so he doesn’t understand just how bad it can be.</p>
<p>Because you don’t have to be obsessive about it. You don’t have to self-identify as a ninja or a rock-star or a temporally-displaced Olympian demi-god (no? Just me then*). You don’t have to <em>write</em> the blogs, or <em>speak</em> at the user groups, or <em>write</em> the books, or <em>make</em> the next big thing to avoid being classified 501 (but the people who do those things would prefer it if you didn’t make fun of them for it). You just need to care, just a little bit, that’s all.</p>
<p><em><font size="1">*Irony, dipshit.</font></em></p>
<h3>One last thing</h3>
<p>If you do have an obsession, and it’s not your job, what are you doing to rectify that situation? Because if you have one all-consuming passion and it’s not what you do all day, every day, and the thing that you <em>do</em> do all day every day keeps you from that passion, that sucks.</p>
<p>It sucks to be in that situation. And you can write a manifesto and you can think you’re “taking back the word” and you can convince yourself the people you work with who love what they’re doing and can’t believe somebody’s paying them to do it are pitiable, but at the end of the day you’re the one being kept from doing the thing you really love by having to do something you merely tolerate because you have two kids and an oppressive mortgage.</p>
<blockquote class="twitter-tweet tw-align-center"><p><a href="https://twitter.com/search/%2523501manifesto">#501manifesto</a>? Here&#8217;s a better idea: Find a job you love and you&#8217;ll never work a day in your life.</p>
<p>— Mark Rendle (@markrendle) <a href="https://twitter.com/markrendle/status/192337415048925184">April 17, 2012</a></p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/296/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=296&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2012/04/23/pity-ninjas-and-how-not-to-suck/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>My ideal laptop</title>
		<link>http://blog.markrendle.net/2012/03/18/my-ideal-laptop/</link>
		<comments>http://blog.markrendle.net/2012/03/18/my-ideal-laptop/#comments</comments>
		<pubDate>Sun, 18 Mar 2012 20:29:00 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[meta]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=284</guid>
		<description><![CDATA[In which I want the moon on a stick, I do. As I browse around fantasy-laptop-shopping, I see lots of laptops which have features that I really, really want, but I’ve never found one laptop that has everything. So I’m going to outline the spec I want, comprised entirely of things that are either available [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=284&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><em>In which I want the moon on a stick, I do.</em></p>
<p>As I browse around fantasy-laptop-shopping, I see lots of laptops which have features that I really, really want, but I’ve never found one laptop that has everything. So I’m going to outline the spec I want, comprised entirely of things that are either available in current laptops or, at least, announced and imminent parts.</p>
<p>Currently I have a late-2009 15” MacBook Pro, which has a 2.53Ghz Core 2 Duo CPU, and has been upgraded with 8GB of RAM and a 512GB Crucial m4 SSD. I also have access to a 17” HP Envy, on loan from my last employer while I am doing some freelance work for them.</p>
<p>I do most of my own development, including open source stuff and some speculative projects, on the MacBook, using Parallels 7 to virtualise Windows 7, because when I had it running under Snow Leopard’s Boot Camp it kept blue-screening at inopportune moments. Like five minutes from the end of my presentation at DDD SouthWest 2011.</p>
<p>The MacBook also gets used for most of my speaking engagements, although I have been known to use the Envy when I’m talking about Azure because I’m not sure about running the Azure Emulator inside an emulator.</p>
<h2>The Spec</h2>
<h2></h2>
<h1></h1>
<h3>Form factor</h3>
<p>I’m happy with the size and weight of the MacBook Pro, although obviously thinner and lighter is always welcome. <a href="http://techland.time.com/2012/03/16/rumor-that-air-style-macbook-pro-youve-been-hearing-about-its-in-production/" target="_blank">Remains to be seen whether those Air-style MacBook Pro rumours are true or not</a>. The other good thing about Macs is their small, light power supplies. The brick that comes with the Envy seems to weigh almost as much as the laptop itself, and it insists on you dragging the three-pronged not-quite-a-kettle lead around too. It all adds to the mass and bulk, especially on long trips to overseas conferences. Just make it as thin and light as you can; whatever it adds to the cost I’ll easily make up in savings on chiropractic bills.</p>
<h3>CPU</h3>
<p>I’m running Visual Studio 2010 and 2011, plus SQL Server 2008 R2 and 2012 and IIS 7.5 or IIS 8 running as services, and emulators for Azure and Windows Phone and VMs for Linux and suchlike, and a whole bunch of other cool beta stuff because I’m an incurable neophile, so I want a beefy CPU. I’m thinking <a href="http://www.cpu-world.com/CPUs/Core_i7/Intel-Core%20i7-3820QM%20(PGA)%20Mobile%20processor.html" target="_blank">Intel Core i7-3820QM</a>, which is supposed to be available next month and is based on the new 22nm Ivy Bridge architecture. Shouldn’t be too much of a problem to get that.</p>
<h3>Hard disk</h3>
<p>Needs to be solid-state, obviously. In pure fantasy-land, I’d have a pair of 512GB SSDs set up in RAID/0, but I’d settle for one 512GB SSD (which I already own) and a 750GB Seagate Momentus XT secondary drive. So two drive bays, obviously.</p>
<p>Before we move on, let me just suggest one extra thing: can I get an easily-accessible HDD/SDD caddy system for the primary drive (maybe a bit like a PCMCIA), so I can switch between operating systems by swapping drives? That would be <em>awesome</em>.</p>
<h3>Memory</h3>
<p>The <a href="http://www.lenovo.com/products/us/laptop/thinkpad/w-series/index.html" target="_blank">Lenovo ThinkPad W520</a> is the existing example here: you can spec that up with 32GB of RAM. That should do it. But can I please have that in a laptop that weighs less than <a href="http://hypertextbook.com/facts/2006/DmitriyGekhman.shtml" target="_blank">my head</a>? And a tip: if adding 24GB of RAM to your default 8GB spec in your “Configure your laptop” page costs more than buying 32GB of compatible RAM from Crucial, guess which I’m going to do? Yeah.</p>
<h3>GPU</h3>
<p>I don’t play games on PC, because I have an Xbox 360 and a PS3 and a Wii and a DS and a PS Vita so I’m really OK for that stuff. But there are other uses for GPUs these days: I want to play with <a href="http://channel9.msdn.com/Blogs/Charles/C-AMP-Daniel-Moth-Overview" target="_blank">C++ AMP</a>, and make backups of my Blu-ray and DVD discs, which takes much less time when you’ve got a few CUDA cores kicking around. So I’d like an nVidia GPU, preferably one of the <a href="http://uk.geforce.com/hardware/notebook-gpus/geforce-gt-555m/specifications" target="_blank">500M</a> series, although I’d accept an <a href="http://www.nvidia.co.uk/object/notebook-nvs-uk.html" target="_blank">NVS 4200M</a> (which appears to be the new Quadro). Obviously the GPU should be switchable, so it can fall back to the integrated graphics in the CPU when running unplugged.</p>
<p>Update: <a href="http://arstechnica.com/author/peter-bright/" target="_blank">Peter Bright</a> has pointed out that <a href="http://www.tomshardware.com/reviews/sandy-bridge-core-i7-2600k-core-i5-2500k,2833-5.html" target="_blank">Quick Sync is better than GPU for video encoding/transcoding</a>, which is true. I still want a GPU for playing with C++ AMP, though.</p>
<h3></h3>
<h3>Screen</h3>
<p><a title="MacRumors: Apple to Launch 2880x1800 Resolution 'Retina Display' MacBook Pro in Q2 2012?" href="http://www.macrumors.com/2011/12/14/apple-to-launch-2880x1800-resolution-retina-display-macbook-pro-in-q2-2012/" target="_blank">One of these, please.</a> 15”, and 16:10 (or 8:5) format. 16:9 is all very well for watching movies, but when you’re working on text, that extra height is really nice to have. Oh, and make it multi-touch with <a href="http://www.engadget.com/2012/01/10/corning-gorilla-glass-2-hands-on-video/" target="_blank">Gorilla Glass 2</a> while you’re at it. Ta.</p>
<h3></h3>
<h3>Keyboard</h3>
<p>A nice, backlit, chiclet keyboard, obviously. With a physical Insert key, because I use ReSharper and there’s a ton of neat things hiding under the Alt-Ins keyboard shortcut. Oh, and if you’re Apple, put bloody # on a key already. Seriously.</p>
<p>If you want to do the <a title="Warning: this page makes noise." href="http://www.razerzone.com/blade#/switchblade-ui" target="_blank">Razer</a> thing and bung some programmable OLED keys on there, that would be awesome, but stick them on the top row, not to one side where I’ll keep hitting them instead of Esc or Ctrl or Backspace.</p>
<h3>Track-pad</h3>
<p>A decent track-pad, which goes *click* when you click it, is essential, and it should support gestures like two-finger scrolling and… actually, just two-finger scrolling would be fine. Yes, I know the screen is touch, but it’s <em>all the way over there</em>; I can’t be reaching for that all the time. Again, Apple is the exemplar here.</p>
<h3>Connectivity</h3>
<p>A built-in VGA output would be useful for attaching to all those 1024&#215;768 projectors, but stick a Mini DisplayPort on there too, like HP have done on my Envy.</p>
<p>A decent set of USB 3.0 ports (at least two), maybe with a couple of 2.0 for keyboard and mouse.</p>
<p>Really good WiFi is more important than a physical Ethernet port, and frankly, I’m not that fussed about being able to fit a 3G SIM until I can find a carrier who will give me multiple SIMs for the same account/allowance. Until that frabjous day, I will make do with my MiFi thing. Bluetooth, though, I need Bluetooth for communicating with the Lego Mindstorms robots.</p>
<p>Personally, I don’t care whether it’s got an SD/XD/CF/BS slot or not, but people seem to like them, so I have no objection to there being one. Put one on, or don’t, it’s all good. Its presence, or lack thereof, is not going to stop me buying this thing, is what I’m saying.</p>
<h3>Docking station</h3>
<p>Now, what you could do here, Mr/Ms Laptop Manufacturer, is take a leaf out of Sony’s Vaio Z book and offer an optical-cable-connected docking station which has got a full desktop GPU in it and can drive 3 monitors. But for preference, make it an nVidia GPU. If you can do that, then the on-board graphics can be the NVS chip.</p>
<h3></h3>
<h3>Optical drive</h3>
<p>Yeah, <a href="http://blog.markrendle.net/2011/11/21/im-going-100percen-digital-in-2012/" target="_blank">no</a>.</p>
<h3>In summary, then:</h3>
<p>I want the moon on a stick. But if you build the moon on a stick, I will buy it, and so will others like me. And there are enough like me to justify building this. So go on. What are you waiting for?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/284/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=284&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2012/03/18/my-ideal-laptop/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>Learn Simple.Data &amp; Nancy at SkillsMatter</title>
		<link>http://blog.markrendle.net/2012/02/17/learn-simple-data-nancy-at-skillsmatter/</link>
		<comments>http://blog.markrendle.net/2012/02/17/learn-simple-data-nancy-at-skillsmatter/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 11:36:46 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Nancy]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Simple.Data]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[nancyfx]]></category>
		<category><![CDATA[simpledata]]></category>
		<category><![CDATA[skillsmatter]]></category>
		<category><![CDATA[training]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=275</guid>
		<description><![CDATA[I should have blogged about this ages ago, but I’ve been unbelievably busy. Still, better late-but-not-too-late than never-or-not-soon-enough. Following the well-received half-day Introduction to Nancy and Simple.Data that I presented with Steven Robbins (@Grumpydev) at the Progressive .NET Tutorials 2011, Wendy at SkillsMatter approached me and asked if I’d be interested in doing a full [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=275&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I should have blogged about this ages ago, but I’ve been unbelievably busy. Still, better late-but-not-too-late than never-or-not-soon-enough.</p>
<p>Following the well-received half-day <a href="http://skillsmatter.com/podcast/open-source-dot-net/introduction-to-nancy-and-simple-data">Introduction to Nancy and Simple.Data</a> that I presented with Steven Robbins (<a href="https://twitter.com/#!/Grumpydev">@Grumpydev</a>) at the Progressive .NET Tutorials 2011, Wendy at <a href="http://skillsmatter.com/">SkillsMatter</a> approached me and asked if I’d be interested in doing a full two-day course. I’ve always been very impressed with the courses they offer, so I jumped at the chance to get involved. So you can now sign up for <a href="http://skillsmatter.com/course/open-source-dot-net/mark-rendles-web-app-development-with-nancy-and-simple-data">a full-on, two day deep dive into building web applications with minimal code</a>.</p>
<p>The course will quickly cover the basics, such as View Engines, Dependency Injection, Nancy’s TDD/BDD test helpers and Simple.Data’s built-in data mocking functionality, then move on to more interesting things like: security, authentication (including OAuth) and authorisation; building RESTful web APIs (<a href="http://kellabyte.com/2011/09/04/clarifying-rest/">proper ones, not just HTTP web services</a>); using different data stores with Simple.Data; and different methods for validating data.</p>
<p>It’ll be a heavily interactive couple of days. You can either turn up with an idea for a web application that you want to get started on, or you can work on an app I’ve designed to exercise the skills you’ll be learning. Either way, at the end of the course, that code is yours to take away and use as a starting-off point or a useful reference.</p>
<p>The first instance of the course is on the 12th and 13th of March, and there are still places available. Lots of places. All of them, in fact. So <a href="https://skillsmatter.com/register-online/course/2429">go sign up for it</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/275/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=275&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2012/02/17/learn-simple-data-nancy-at-skillsmatter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>Simple.Data 1.0.0-beta1</title>
		<link>http://blog.markrendle.net/2012/02/16/simple-data-1-0-0-beta1/</link>
		<comments>http://blog.markrendle.net/2012/02/16/simple-data-1-0-0-beta1/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 22:23:02 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[Simple.Data]]></category>
		<category><![CDATA[simpledata]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=266</guid>
		<description><![CDATA[At last It’s taken me so much longer to get here than I originally expected, but I’ve released the first 1.0 beta version of Simple.Data. If this post is the first you’ve heard of Simple.Data, then head over to the GitHub page and browse back through previous posts to find out more. New features I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=266&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>At last</h2>
<p>It’s taken me so much longer to get here than I originally expected, but I’ve released the first 1.0 beta version of Simple.Data.</p>
<p>If this post is the first you’ve heard of Simple.Data, then head over to <a href="http://github.com/markrendle/simple.data">the GitHub page</a> and browse back through previous posts to find out more.</p>
<h2>New features</h2>
<p>I didn’t do a post for the 0.14 release, so I’ll cover the changes from that as well as what’s new in the 1.0 beta.</p>
<h3>Eager-loading with With</h3>
<p>Since very early on, Simple.Data has supported lazy-loading when you reference a joined property from the dynamic record type. There were two issues with that: firstly, if you assigned the record to a static type, the joined properties were not hydrated; secondly, multiple selects do not make DBAs happy, and should be avoided if possible.</p>
<p>Now you can use the <strong>With</strong> method to load the joined data at the same time as the main record.</p>
<pre class="code"><span style="color:blue;">var </span>db = <span style="color:#2b91af;">DatabaseHelper</span>.Open();
<span style="color:#2b91af;">Customer </span>actual = db.Customers.FindAllByCustomerId(1).WithOrders().FirstOrDefault();
</pre>
<p>This uses a single SQL select statement to pull all the Customer rows, plus the Order detail rows, and groups the data in-memory; generally, that’s more efficient than running two select operations. When the record is converted to the Customer type, it sets the ICollection&lt;Order&gt; property at the same time, either creating a new instance of List&lt;Order&gt;, or populating an existing instance if the property is readonly.</p>
<p>The inverse works too:</p>
<pre class="code"><span style="color:blue;">var </span>db = <span style="color:#2b91af;">DatabaseHelper</span>.Open();
<span style="color:#2b91af;">Order </span>actual = db.Orders.FindAllByOrderId(1).WithCustomer().FirstOrDefault();
</pre>
<p>If the property name is not the same as the database table name, you can use an alias to tweak it:</p>
<pre class="code"><span style="color:blue;">var </span>db = <span style="color:#2b91af;">DatabaseHelper</span>.Open();
<span style="color:blue;">var </span>actual = db.Orders.FindAllByOrderId(1).With(db.Orders.OrderItems.As("Items"));
</pre>
<p>And if there’s no referential integrity in the database, you can specify an explicit join separately:</p>
<pre class="code"><span style="color:blue;">dynamic </span>manager;
<span style="color:blue;">var </span>q = _db.Employees.All()
    .OuterJoin(_db.Employees.As(<span style="color:#a31515;">"Manager"</span>), <span style="color:blue;">out </span>manager)
    .On(Id: _db.Employees.ManagerId)
    .With(manager);
</pre>
<p>&nbsp;</p>
<p>(Oh, yeah, and check out the <strong>OuterJoin</strong> method. Finally.)</p>
<p>Of course, if there’s no referential integrity, it’s hard for Simple.Data to work out whether the joined property is a collection or a complex object, so you can specify <strong>WithOne</strong> or <strong>WithMany</strong> to help it out:</p>
<pre class="code"><span style="color:blue;">dynamic </span>manager;
<span style="color:blue;">var </span>q = _db.Employees.All()
    .OuterJoin(_db.Employees.As(<span style="color:#a31515;">"Manager"</span>), <span style="color:blue;">out </span>manager)
    .On(Id: _db.Employees.ManagerId)
    .WithOne(manager);
</pre>
<p>&nbsp;</p>
<p>And of course, you can mix and match all these. This test gives you a good idea of some of the heavy lifting that’s going on for you with this feature, just with the SQL:</p>
<pre class="code"><span style="color:blue;">public void </span>MultipleWithClauseJustDoesEverythingYouWouldHope()
{
    <span style="color:blue;">const string </span>expectedSql = 
        <span style="color:#a31515;">"select [dbo].[employee].[id],[dbo].[employee].[name]," </span>+
        <span style="color:#a31515;">"[dbo].[employee].[managerid],[dbo].[employee].[departmentid]," </span>+
        <span style="color:#a31515;">"[manager].[id] as [__withn__manager__id]," </span>+
        <span style="color:#a31515;">"[manager].[name] as [__withn__manager__name]," </span>+
        <span style="color:#a31515;">"[manager].[managerid] as [__withn__manager__managerid]," </span>+
        <span style="color:#a31515;">"[manager].[departmentid] as [__withn__manager__departmentid]," </span>+
        <span style="color:#a31515;">"[dbo].[department].[id] as [__with1__department__id]," </span>+
        <span style="color:#a31515;">"[dbo].[department].[name] as [__with1__department__name]" </span>+
        <span style="color:#a31515;">" from [dbo].[employee] left join [dbo].[employee] [manager] " </span>+
        <span style="color:#a31515;">"on ([manager].[id] = [dbo].[employee].[managerid])" </span>+
        <span style="color:#a31515;">" left join [dbo].[department] " </span>+
        <span style="color:#a31515;">"on ([dbo].[department].[id] = [dbo].[employee].[departmentid])"</span>;

    <span style="color:blue;">dynamic </span>manager;
    <span style="color:blue;">var </span>q = _db.Employees.All()
        .OuterJoin(_db.Employees.As(<span style="color:#a31515;">"Manager"</span>), <span style="color:blue;">out </span>manager)
        .On(Id: _db.Employees.ManagerId)
        .With(manager)
        .WithDepartment();

    GeneratedSqlIs(expectedSql);
}
</pre>
<p>(Never mind the logic involved in turning that result set into the correct in-memory object graphs.)</p>
<p>Now, this works on multi-record queries, but not on single-record ones such as FindById or the key-driven Get method, and that’s more problematic since those methods don’t return a query you can modify, just a record. In the past I did actually toy with having the SimpleRecord type do lazy self-evaluation, but the fact that the NUnit Assert.IsNull test wouldn’t accept that the object was null even when it swore black-was-blue that it was put me off. (It works for Nullable&lt;T&gt;; no fair.)</p>
<p>Instead of that, and this is only in the 1.0 beta release, you can specify your With clause before the Get or FindBy:</p>
<pre class="code"><span style="color:blue;">var </span>db = <span style="color:#2b91af;">DatabaseHelper</span>.Open();
<span style="color:#2b91af;">Customer </span>actual = db.Customers.WithOrders().Get(1);
</pre>
<p>So now you get all that goodness for single records, where it’s arguably more useful anyway.</p>
<h3>Upsert</h3>
<p>Inserting and updating is all very well, but sometimes you’ve got some data and you just don’t know whether it’s in the database already or not. If it is, you want to update the row with some new values; if it’s not, you want to insert it. Boring.</p>
<p>To save you the time and trouble, Simple.Data now provides the <strong>Upsert</strong> method. Give it a record, and it will do all the checking to see if it exists or not. And in beta2, there’ll be back-end database-specific optimizations; for example, if you’re using the SQL Server provider with SQL 2008 or later, it will use the MERGE operation.</p>
<p>Upsert returns the record as it is in the database following the operation, with any database-specified values intact.</p>
<pre class="code"><span style="color:blue;">var </span>db = <span style="color:#2b91af;">DatabaseHelper</span>.Open();
<span style="color:blue;">var </span>user = <span style="color:blue;">new </span><span style="color:#2b91af;">User </span>{Id = 2, Name = <span style="color:#a31515;">"Charlie"</span>, Password = <span style="color:#a31515;">"foobar"</span>, Age = 42};
<span style="color:blue;">var </span>actual = db.Users.Upsert(user);
</pre>
<p>&nbsp;</p>
<p>That’s one example, but there are plenty of other ways to use Upsert. Take a look at <a href="https://github.com/markrendle/Simple.Data/blob/master/Simple.Data.SqlTest/UpsertTests.cs">the tests</a> to see the others.</p>
<h2></h2>
<h2>NuGet and SemVer</h2>
<p>I’ve pushed this release to <a href="http://nuget.org/packages/simple.data.core">NuGet</a> using the <a href="http://semver.org">Semantic Version</a> number for pre-release (1.0.0-beta1), which NuGet added support for in 1.6. Using this form means that NuGet knows that it’s pre-release software, and you’ll have to explicitly tell it that that’s what you want. So to get the 1.0 beta releases, remember to use the –Pre flag for the Install-Package command. The great thing about this is that when we get to 1.0 RTW, I’ll start on 1.1.0-alpha1 and both package types will be available from the repository.</p>
<p>If you’re waiting for the Mono build, I hope to have it out as a tgz by the end of this weekend.</p>
<h2>What’s still to do?</h2>
<p>So with those two features, I’m drawing a temporary line in the sand and focusing on getting everything to release quality. That means implementing some optimizations around object creation and database tricks, but more importantly, working on test coverage, refactoring some messy code, and making <a href="http://simplefx.org/simpledata/docs">the documentation</a> comprehensive. Help on that last one would be much appreciated!</p>
<p>Come to that, if anybody wants to make a really nice website… <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/266/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=266&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2012/02/16/simple-data-1-0-0-beta1/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>Mark Rendle, Freelance Consultant</title>
		<link>http://blog.markrendle.net/2012/01/13/mark-rendle-freelance-consultant/</link>
		<comments>http://blog.markrendle.net/2012/01/13/mark-rendle-freelance-consultant/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 14:12:10 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[consulting]]></category>
		<category><![CDATA[professional]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=237</guid>
		<description><![CDATA[As some of you may know, for some time I have been considering starting my own venture, and I’m pleased to announce that I’m taking the first step on this journey. Starting in March 2012 I will be reducing my commitment to my current employer, Dot Net Solutions, and spending the remainder of my time [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=237&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As some of you may know, for some time I have been considering starting my own venture, and I’m pleased to announce that I’m taking the first step on this journey. Starting in March 2012 I will be reducing my commitment to my current employer, <a href="http://www.dotnetsolutions.co.uk/" target="_blank">Dot Net Solutions</a>, and spending the remainder of my time working as an independent software development consultant, focusing on both Cloud Computing and Software Quality. Work on a web site is underway, which will outline the full set of services I will be offering.</p>
<p>This does not, however, mark in any way an end to my relationship with Dot Net Solutions. I will remain in my current position as Principal Consultant and will continue to work closely on major projects and supporting Microsoft as an active member of the VTSP (Virtual Technology Specialist Program) performing consulting and conducting ADSs (Architecture Design Sessions).</p>
<p>From my perspective, there are things one cannot achieve as a singleton, and this continuing relationship will enable me to pursue potential work that would otherwise be out of reach.</p>
<p>Dot Net Solutions has been a great company to work for, and over the last two years they have been very supportive of my community and OSS work. I have learned a great deal, and I like to think that I have made a valuable contribution too. As a company, DNS are in an excellent position to grow this year and beyond, and I am very excited to remain part of that process.</p>
<p>If you would like to discuss what I can do for your project, team, or company, please use <a href="http://blog.markrendle.net/contact-me/">the Contact Me page</a> to get in touch.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/237/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=237&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2012/01/13/mark-rendle-freelance-consultant/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>Eager-loading RFC</title>
		<link>http://blog.markrendle.net/2011/12/01/eager-loading-rfc/</link>
		<comments>http://blog.markrendle.net/2011/12/01/eager-loading-rfc/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 14:53:06 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=227</guid>
		<description><![CDATA[There are two more features I want to get into Simple.Data before releasing 1.0beta1: upserts, and eager loading. Upserts are pretty straight-forward, but there are a few different approaches to eager loading and I want to get some input from the community before I pick one. In case you don’t know, eager loading is a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=227&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There are two more features I want to get into Simple.Data before releasing 1.0beta1: <a href="http://en.wikipedia.org/wiki/Upsert">upserts</a>, and eager loading. Upserts are pretty straight-forward, but there are a few different approaches to eager loading and I want to get some input from the community before I pick one.</p>
<p>In case you don’t know, eager loading is a pattern for getting data from the database in an optimal fashion, with the minimum number of requests or least-possible server load. It’s the opposite of <a href="http://en.wikipedia.org/wiki/Lazy_loading">lazy loading</a>, which Simple.Data already does.</p>
<p>The implementation syntax will look like this:</p>
<pre class="code"><span style="color:blue;">    IEnumerable&lt;Customer&gt; </span>customers = _db.Customers.FindAllByRegion(<span style="color:#a31515;">"South"</span>)
                .With(_db.Customers.Orders)<br />                .Cast&lt;Customer&gt;();<br /></pre>
<p>This will create the customer objects and populate an <strong>ICollection&lt;Order&gt; Orders</strong> property in each one, assuming there is one.</p>
<p>There are two directions in which a class may have relationships with other classes: it may have “parent” (or “lookup”) classes, where there is at most a single instance of that parent class within the instance of the class in question; and it may have “child” classes, where there is a collection of instances of the child class. Eager loading of parent classes is trivial; you just add the necessary join(s) to the master table(s) and marshal the data into the right places in code.</p>
<p>Eager loading of child classes is similarly easy when there is only a single child collection to be loaded; you join to the detail table and then process the results so that a single instance of the main table row is created, and instances of the detail table rows are grouped into collections.</p>
<p>For example, loading user objects with a list of phone numbers:</p>
<p>SELECT User.Id, User.Name, Phone.Number<br />FROM User<br />LEFT JOIN Phone ON User.Id = Phone.UserId</p>
<p>Returned rows:</p>
<table border="1" cellspacing="0" cellpadding="2" width="400">
<tbody>
<tr>
<td valign="top" width="133">User.Id</td>
<td valign="top" width="133">User.Name</td>
<td valign="top" width="133">Phone.Number</td>
</tr>
<tr>
<td valign="top" width="133">1</td>
<td valign="top" width="133">Alice</td>
<td valign="top" width="133">0123456789</td>
</tr>
<tr>
<td valign="top" width="133">1</td>
<td valign="top" width="133">Alice</td>
<td valign="top" width="133">0738473284</td>
</tr>
<tr>
<td valign="top" width="133">2</td>
<td valign="top" width="133">Bob</td>
<td valign="top" width="133">0129934845</td>
</tr>
<tr>
<td valign="top" width="133">2</td>
<td valign="top" width="133">Bob</td>
<td valign="top" width="133">0729478594</td>
</tr>
</tbody>
</table>
<p>From this we create a User object for Alice with her two phone numbers, and an object for Bob with his. Even if there are a lot of rows in the detail table, this is still the preferred way of handling eager loading for this scenario as it involves the fewest round-trips to the database. Often, you can handle a parent-child-child relationship using this algorithm, too, although beyond that point you’re getting a bit scary.</p>
<p>The complexity arises when you want to load two unrelated child collections, say, load Customers with their Invoices and Orders:</p>
<p>SELECT Customer.*, Invoice.*, Order.*<br />FROM Customer<br />LEFT JOIN Invoice ON Customer.Id = Invoice.CustomerId<br />LEFT JOIN Order ON Customer.Id = Order.CustomerId</p>
<p>This creates what is technically called an “outer <a href="http://db.grussell.org/section010.html#_Toc67114480">Cartesian product</a>”, where a row is returned for every possible combination of the rows from the two outer-joined tables. So if you’re grabbing the details for a single valuable customer who has placed a thousand orders and generated a thousand invoices, you get a million rows back from the database. I have a hunch this might not be optimal.</p>
<p>So this is my <a href="http://en.wikipedia.org/wiki/Request_for_Comments">Request for Comments</a>: what would you like to see done here?</p>
<p>The options are:</p>
<ol>
<li>Only allow one detail-table With clause to be specified per query. Throw an exception if there is more than one.</li>
<li>Allow multiple detail-table With clauses, and use additional SELECT operations for all except the first.</li>
<li>Add a parameter to the With method <em>allowing</em> the developer to specify the technique on a per-detail-table basis:</li>
<pre class="code"><span style="color:blue;">    var </span>customers = _db.Customers.FindAllByRegion(<span style="color:#a31515;">"South"</span>)
                .With(_db.Customers.Orders, <span style="color:#2b91af;">WithUsing</span>.Join)
                .With(_db.Customers.Orders.Items, <span style="color:#2b91af;">WithUsing</span>.Join)
                .With(_db.Customers.Invoices, <span style="color:#2b91af;">WithUsing</span>.ExtraQuery);
</pre>
<p>If only one detail table is specified, or one detail with a detail below it (e.g. _db.Customers.Orders.Items), the default behaviour when no <strong>WithUsing</strong> parameter is supplied will be to use JOIN. Multiple detail tables without a <strong>WithUsing</strong> will cause the ADO adapter to throw an exception (other adapters, such as <a href="https://github.com/craiggwilson/Simple.Data.MongoDB">the one for MongoDB</a>, can use the With clause as they see fit).</ol>
<p>I think I’ve <a href="http://c2.com/cgi/wiki?RubberDucking">rubber ducked</a> here a bit, as Option 3 is looking like a no-brainer, but I’ve typed it all now, so if you do have any comments or suggestions, please do leave them below. I’m planning on starting code for this on Sunday morning, so there’s plenty of time to change my mind.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/227/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=227&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2011/12/01/eager-loading-rfc/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>Yes, Simple.Data protects against SQL Injection</title>
		<link>http://blog.markrendle.net/2011/12/01/yes-simple-data-protects-against-sql-injection/</link>
		<comments>http://blog.markrendle.net/2011/12/01/yes-simple-data-protects-against-sql-injection/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 12:24:35 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=225</guid>
		<description><![CDATA[Several people who weren’t following the show at the inception of Simple.Data have asked whether it does anything to prevent SQL Injection attacks. Those of you who remember the start of the project will understand why I’m kind of amused by the question. I originally built Simple.Data as a proof-of-concept when there was a big [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=225&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Several people who weren’t following the show at the inception of Simple.Data have asked whether it does anything to prevent <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL Injection</a> attacks. Those of you who remember the start of the project will understand why I’m kind of amused by the question.</p>
<p>I originally built Simple.Data as a proof-of-concept when there was a big web-scuffle over what was then called Microsoft.Data (now <a href="http://msdn.microsoft.com/en-us/library/webmatrix.data%28v=vs.99%29.aspx">WebMatrix.Data</a>). <a href="http://weblogs.asp.net/davidfowler/default.aspx">David Fowler</a>, a developer I have since come to <a href="http://www.codeplex.com/site/users/view/dfowler">respect</a> <a href="https://github.com/SignalR/SignalR">greatly</a>, posted an example on his blog which used concatenated SQL, and everybody lined up to tear him a new one. I’m a big fan of code over cockfights, so I had a go at implementing a simple data access library which made SQL Injection impossible by eliminating SQL strings. Thus Simple.Data. You told it what you wanted, and provided the necessary values, and then it wrapped them safely up in parameters and executed them. I stuck it on <a href="http://github.com/markrendle/Simple.Data">GitHub</a>, and <a href="http://blog.markrendle.net/2010/08/05/introducing-simple-data/">posted about it on my blog</a>.</p>
<p>(In fact, the first version did allow you to execute SQL strings, much like Dapper and Massive, because the functionality was extremely limited otherwise. As I’ve iterated on it, I’ve been able to expose nearly all the required functionality using the dynamic approach, so the only way you can execute SQL directly now is by getting an IDbConnection object from the AdoAdapter and using ADO.NET against it.)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/225/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=225&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2011/12/01/yes-simple-data-protects-against-sql-injection/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>Macro-optimisations</title>
		<link>http://blog.markrendle.net/2011/12/01/macro-optimisations/</link>
		<comments>http://blog.markrendle.net/2011/12/01/macro-optimisations/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 00:36:23 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[Simple.Data]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=210</guid>
		<description><![CDATA[I&#8217;ve used Simple.Data in a few production projects now (and it&#8217;s doing a great job so far). It&#8217;s not often you actually get to use the software that you write, but when you do, it&#8217;s a great opportunity to see it through users&#8217; eyes, and I&#8217;ve made a few changes and improvements over the past [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=210&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve used Simple.Data in a few production projects now (and it&#8217;s doing a great job so far). It&#8217;s not often you actually get to use the software that you write, but when you do, it&#8217;s a great opportunity to see it through users&#8217; eyes, and I&#8217;ve made a few changes and improvements over the past year as a result.</p>
<p>The most recent project that we&#8217;ve used it on at Dot Net Solutions is the Met Office open data thing that was announced on Tuesday. And that forced me to bring forward an optimisation that&#8217;s been way down my to-do list, partly because I didn&#8217;t really just how much of an optimisation it would be.</p>
<p>The Met Office project involves inserting something like 8 million records a day into a SQL Azure database, which isn&#8217;t a huge amount, but enough to need you to be smart about how you do it. The version of Simple.Data that was on NuGet when we started supported bulk inserts, but it wasn&#8217;t friendly to the error handling we needed and it assumed it needed to return the inserted records, doing that whole &#8216;select just-inserted-record&#8217; thing, which is often completely unnecessary.</p>
<p><em>(So it turns out that when you&#8217;re handling TryInvokeMember in a DynamicObject, you can actually find out whether the return value is used by the caller, and not bother if it isn&#8217;t. But that&#8217;s another blog post.)</em></p>
<p>Anyway, I tweaked a couple of things and shaved off a fraction of the time it was taking, but it was a small fraction, and things were still far too slow. So we did what we should have done in the first place, and used <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx" target="_blank">SqlBulkCopy</a>.</p>
<p>If you haven&#8217;t used this (SqlClient-specific) method, you should read up on it and keep it in your mental list of &#8220;things that are good that I might need some day&#8221;. It lets you prepare a big batch of rows in a DataTable (turns out they&#8217;re still good for something) and then insert them in a single operation, and man, it&#8217;s quick.</p>
<p>But it&#8217;s SQL Server specific, so I couldn&#8217;t support it in the generic ADO adapter code.</p>
<p>I&#8217;ve exposed a few interfaces in the Simple.Data.Ado assembly which providers can optionally implement if they need to do something a little differently or can do something better. The first instance was ICustomInserter, which is implemented in the Oracle provider to handle fetch-backs in a world without IDENTITY columns. Since then I&#8217;ve added more as I went along, and IBulkInserter was one of them because, as I said earlier, I had half a mind to implement this. And now I have.</p>
<p>Anyway, I&#8217;ll stop blathering now and just post the comparison code I wrote (measures time to insert 10,000 records, five times) and the before and after results.</p>
<p><strong>Code:</strong></p>
<p><pre class="brush: csharp;">
namespace BulkInsertComparison
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using Simple.Data;

    class Program
    {
        static void Main(string[] args)
        {
            var db = Database.OpenConnection(&quot;data source=.;initial catalog=BulkInsertTest;integrated security=true&quot;);

            for (int i = 0; i &lt; 5; i++)
            {
                Console.WriteLine(TimeInsert(db));
            }
        }

        private static TimeSpan TimeInsert(dynamic db)
        {
            var stopwatch = Stopwatch.StartNew();
            db.Target.Insert(GenerateItems(10000));
            stopwatch.Stop();
            return stopwatch.Elapsed;
        }

        static IEnumerable&lt;Item&gt; GenerateItems(int number)
        {
            for (int i = 0; i &lt; number; i++)
            {
                var guid = Guid.NewGuid();
                yield return new Item(0, guid, guid.ToString(&quot;N&quot;));
            }
        }
    }

    class Item
    {
        private readonly int _id;
        private readonly Guid _guid;
        private readonly string _text;

        public Item(int id, Guid guid, string text)
        {
            _id = id;
            _guid = guid;
            _text = text;
        }

        public string Text { get { return _text; } }
        public Guid Guid { get { return _guid; } }
        public int Id { get { return _id; } }
    }
}
</pre></p>
<p><strong>Before:</strong></p>
<pre>00:00:16.9799819
00:00:17.1971797
00:00:18.0744958
00:00:19.1514537
00:00:17.3798541</pre>
<p><strong>After:</strong></p>
<pre>00:00:00.4616911 (First run includes MEFing IBulkInserter)
00:00:00.2757802
00:00:00.2852119
00:00:00.2504587
00:00:00.2453277</pre>
<p>Totally worth it.</p>
<p>0.12.2 on NuGet now. <em>Mini-roadmap: eager-loading (0.14) and upserts (0.15).</em></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/210/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=210&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2011/12/01/macro-optimisations/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
		<item>
		<title>Simple.Data for Mono</title>
		<link>http://blog.markrendle.net/2011/11/27/simple-data-for-mono/</link>
		<comments>http://blog.markrendle.net/2011/11/27/simple-data-for-mono/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 14:44:10 +0000</pubDate>
		<dc:creator>markrendle</dc:creator>
				<category><![CDATA[Simple.Data]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[simpledata]]></category>

		<guid isPermaLink="false">https://markrendle.wordpress.com/?p=208</guid>
		<description><![CDATA[TL;DR I&#8217;ve got Simple.Data running on Mono 2.10.6. Most tests pass. YMMV. Download it here. Ritalin version Simple.Data on Mono is something that people have been asking about, and I&#8217;ve been meaning to sort out, pretty much since the project went from a proof-of-concept to an actual OSS product. One way or another I&#8217;ve never [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=208&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>TL;DR</h3>
<p>I&#8217;ve got <a href="https://github.com/markrendle/Simple.Data" target="_blank">Simple.Data</a> running on <a href="http://www.mono-project.com/Release_Notes_Mono_2.10.6" target="_blank">Mono 2.10.6</a>. Most tests pass. YMMV. <a href="https://github.com/downloads/markrendle/Simple.Data/mono-release-0.11.4.tgz" target="_blank">Download it here</a>.</p>
<h3>Ritalin version</h3>
<p>Simple.Data on Mono is something that people have been asking about, and I&#8217;ve been meaning to sort out, pretty much since the project went from a proof-of-concept to an actual OSS product. One way or another I&#8217;ve never gotten round to it, but a couple of things have made it seem more relevant. Firstly, there are providers for lots of OSS databases now (<a href="https://github.com/Vidarls/Simple.Data.Mysql" target="_blank">MySQL</a>, <a href="https://github.com/NotMyself/Simple.Data.Sqlite" target="_blank">SQLite</a>, <a href="https://github.com/ChrisMH/Simple.Data.PostgreSql" target="_blank">PostgreSQL</a>); secondly, a certain <a href="https://twitter.com/#!/fekberg" target="_blank">@fekberg</a> has been very persistent in his status update requests, so I&#8217;ve taken the time this weekend to make it work.</p>
<h4>The challenges</h4>
<p>For the most part, I&#8217;ve been pleasantly surprised by how easy it&#8217;s been. I&#8217;ve found what I think is a bug in the Mono implementation of either dynamic or LINQ or the combination of the two, which I&#8217;m going to file with <a href="http://xamarin.com/" target="_blank">Xamarin</a> once I&#8217;ve created a simple repro project. I&#8217;ve come up with a workaround involving old-school class-based IEnumerable/IEnumerator implementations, and the performance doesn&#8217;t seem to be affected, so that&#8217;s fine.</p>
<p>The hardest thing about the whole process is that <a href="http://monodevelop.com/" target="_blank">MonoDevelop</a> just isn&#8217;t Visual Studio 2010 + ReSharper. It&#8217;s not a bad IDE by any standards – I&#8217;d still take it over Eclipse any day – but I work day in, day out with VS and jumping into any other IDE just feels like somebody moved all the cheese. Add to that the fact that I&#8217;m running it under OSX, so even the standard Windows keyboard shortcuts don&#8217;t work, and it&#8217;s a bit like running in treacle. As I understand it, the Mono Tools for Visual Studio don&#8217;t support 2.10; Miguel de Icaza tells me that they&#8217;re working on some awesome new VS tooling, so I&#8217;m really looking forward to that.</p>
<p>The other big challenge was testing the ADO adapter against a real database. I only own the SQL Server and SQL Compact providers, so I really wanted to test with SQL Server to keep things simple and let me step-debug if necessary. I was expecting not to have fun with this, but it turned out fine. I run my Windows development environment on my MacBook using <a href="http://www.parallels.com/products/desktop/" target="_blank">Parallels 7</a>, so I set up the Host-Guest networking (easy) and opened inbound port 1433 in Windows Firewall (also easy) and that was it. There were a couple of failing tests, one calling a stored procedure with a DataTable and one involving a scalar function, but the rest just passed. I&#8217;m guessing that the majority of people who want to use Simple.Data on Mono will be using one of the OSS DB providers, so hopefully this won&#8217;t be a problem.</p>
<h4>Releases</h4>
<p>I don&#8217;t know what the Mono NuGet situation is, so I&#8217;ll be releasing Mono builds as tgz downloads from the GitHub project page. For the time being, there are differences between the Mono build of Simple.Data.SqlServer and the Microsoft .NET build, so if you want to use that provider, don&#8217;t use the NuGet version.</p>
<p>Right now, there&#8217;s <a href="https://github.com/markrendle/Simple.Data/downloads" target="_blank">a 0.11.4 build in the Downloads section</a> which I hope works. However, I haven&#8217;t really exercised it to any great degree, so if you encounter any problems please <a href="https://github.com/markrendle/Simple.Data/issues?sort=created&amp;direction=desc&amp;state=open" target="_blank">raise an issue</a> if you think it&#8217;s a bug, or ask on <a href="http://groups.google.com/group/simpledata?pli=1" target="_blank">the mailing list</a> if you aren&#8217;t sure.</p>
<p>If you are one of the developers of an adapter or provider, you might want to test against Mono. If, for any reason, that&#8217;s not an option, then let me know and I&#8217;ll try to find time to test it for you.</p>
<p>Going forward, I will support (in the OSS sense of the word) both Microsoft .NET and Mono for all releases.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/markrendle.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/markrendle.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/markrendle.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/markrendle.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/markrendle.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/markrendle.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/markrendle.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/markrendle.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/markrendle.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/markrendle.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/markrendle.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/markrendle.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/markrendle.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/markrendle.wordpress.com/208/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.markrendle.net&#038;blog=16759552&#038;post=208&#038;subd=markrendle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.markrendle.net/2011/11/27/simple-data-for-mono/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/cc060db2b5331d8cbbfe080cec4add6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">markrendle</media:title>
		</media:content>
	</item>
	</channel>
</rss>
