<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DEMARHcycSp7ImA9WxBUE00.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669</id><updated>2010-02-27T22:34:05.999+01:00</updated><title>A World Full of Sharp Objects</title><subtitle type="html">Random thoughts on anything slightly related to software development in general - and .NET in specific.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.kjetilk.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.kjetilk.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/AWorldFullOfSharpObjects" /><feedburner:info uri="aworldfullofsharpobjects" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/2.0/" /><feedburner:emailServiceId>AWorldFullOfSharpObjects</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;CE8NQXk-fCp7ImA9WxBVEUg.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-613256665141605405</id><published>2010-02-14T14:05:00.001+01:00</published><updated>2010-02-14T14:08:10.754+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-14T14:08:10.754+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ddd" /><category scheme="http://www.blogger.com/atom/ns#" term="cqrs" /><title>Option Explicit On – Commands in CQRS</title><content type="html">&lt;p&gt;The idea behind commands in a CQRS architecture is that they should be very explicit and very specific about their intention. You would try to shed away from generic CRUD operations and rather try to capture the essence of &lt;em&gt;what the user is trying to accomplish&lt;/em&gt;. Meaning; instead of a ‘one form to save all data’ you would rather let the user explicitly tell what (s)he wants to achieve.&lt;/p&gt;  &lt;p&gt;Ok, example. Say you have an application for car dealers. In here you have the possibility to set the price of the car you want to sell. Now, you can either put this as a ‘price field’ among a bunch of other car related data like registration number, brand, model, horsepower, etc, and save it along the rest of the data. &lt;em&gt;Or&lt;/em&gt; you can make sure that the changing of a car’s price is a operation of it’s own. &lt;/p&gt;  &lt;p&gt;In CQRS you would typically go for the second option. You would make sure that the user’s intent is expressed very explicit by giving this operation it’s own command. That is; instead of putting it inside some big &lt;em&gt;SaveCar&lt;/em&gt; method, you make it a method of its own. Something like &lt;em&gt;ChangeCarPrice,&lt;/em&gt; or even &lt;em&gt;LowerCarPrice&lt;/em&gt; and &lt;em&gt;RaiseCarPrice&lt;/em&gt;. &lt;/p&gt;  &lt;p&gt;Wouldn’t that be an awful lot of commands, you say? Will you be making a command for every change of value in the application? Hell, no. That &lt;em&gt;would &lt;/em&gt;be a lot of commands. And that’s why we don’t do that. We’re making a specific command for ‘car price’ value because the change of this very value is something that has a specific meaning in this domain. &lt;img style="margin: 10px 0px 10px 10px; display: inline" align="right" src="http://z.about.com/d/classicfilm/1/0/G/C/-/-/command_decision.jpg" width="374" height="530" /&gt;&lt;/p&gt;  &lt;p&gt;Lowering the price of car is probably an action you need to do because nobody is willing to pay the price you set earlier on. And it can be one of several other marketing actions you can take in order to make the car more saleable. Adding more equipment or freshening up the sales description can be other ‘marketing actions’. &lt;/p&gt;  &lt;p&gt;Tracking these specific actions can be very valuable for the car dealer, because having a car taking up space in your warehouse for a longer period of time is bad for profit. Having cars in stock for a minimum amount of time is good for profit. And so tracking which marketing actions that are most effective over time can be very lucrative for a car dealer (or any kind of dealer I guess).&lt;/p&gt;  &lt;h4&gt;Behave!&lt;/h4&gt;  &lt;p&gt;Another way of looking at commands is that they should capture the behavior expressed in your domain model. Patterns like &lt;em&gt;Table Module &lt;/em&gt;are arguably more focused on data than behavior, which makes them very well suited for systems where complexity is not that high. And contrary for complex domains; &lt;em&gt;Domain Model&lt;/em&gt; is more focused on behavior and less data centric.&lt;/p&gt;  &lt;p&gt;I would argue that your average Customer Relationship Management system (CRM) or Content Management System (CMS) are examples of systems were data is more important, or rather more valuable, than the behavior of the system. As to all things in life there’s exceptions, but from my own experience the typical CRM and CMS system would make a good fit for a &lt;em&gt;Table Module&lt;/em&gt; or &lt;em&gt;Record Set &lt;/em&gt;pattern.&lt;/p&gt;  &lt;p&gt;Systems built using data centric models are far easier to build and maintain. That is off course until you start having too much logic – too much behavior – sprinkled around the code. In that case you’re probably better off using using something like the &lt;em&gt;Domain Model&lt;/em&gt; pattern.&lt;/p&gt;  &lt;p&gt;So let’s focus on the Domain Model again, because in a CQRS architecture there will typically be a Domain Model that contains the essential business logic. The core of the business so to speak. &lt;/p&gt;  &lt;p&gt;In a sufficiently complex system there will be a lot of behavior and complex rules attached to those behaviors. Let’s take for instance the aforementioned &lt;em&gt;ChangeCarPrice. &lt;/em&gt;Larger car dealers can have hundreds of cars for sale, and all cars will have a designated ‘responsible salesman’. Each salesman can have several cars which they are responsible for and they probably will have some kind of bonus arrangement tied to how many cars they sell. &lt;/p&gt;  &lt;p&gt;&lt;img style="margin: 10px 0px 10px 10px; display: inline" align="right" src="http://cache.finn.no/mmo/6/209/346/36_1251535183.jpg" width="240" height="181" /&gt;Imagine a scenario where a potential car buyer walks into the shop. Let’s call our potential customer ‘Johnny’.&amp;#160; Johnny has some preferences to what car he want, but for the most part he’s pretty open to which exact car he’ll end up buying. He’s looking for a 4x4 station wagon, preferably black or dark gray, with diesel engine and leather seats. Johnny’s got about $50.000 to spend on the car - which by the way is a mid-priced car here in Norway. (Yes, I know. It’s an expensive country and everything cost more than it should and blah, blah, blah. It’s a whole other story.)&lt;/p&gt;  &lt;p&gt;The salesman of this story, let’s call him Bob, doesn’t have any cars that fits within Johnny’s preferences. At least non that appeals enough to make him leave his $50.000 in the shop. Johnny did however spot a BMW at $55.000 that he really liked, but the extra $5.000 is more than Johnny can afford at the moment. And Bob is not willing to let the BMW go for as little as $50.000, so no business is done. &lt;/p&gt;  &lt;p&gt;4 weeks go by and the BMW is still in the shop, but now it’s starting to be costly to having it just standing there, and so the price is lower to $50.000. Wouldn’t it be nice if the Bob’s software were smart enough to notify Johnny about this event? &lt;/p&gt;  &lt;p&gt;Yes, it would, but building a system that can handle these kind of events is actually very tricky. Having an explicit command that triggers when the car price changes makes it a whole lot easier to add a business rule like ‘notify customer if price drops to or below $50.000’, because you know exactly were to put that behavior.&lt;/p&gt;  &lt;p&gt;If you have a system where business logic has been randomly added from the UI all the way down to the database, this will be a lot tougher job to get done. &lt;/p&gt;  &lt;h4&gt;So what about the CRUD?&lt;/h4&gt;  &lt;p&gt;I believe you can still have your ‘store these 30 fields to the database’-operations in a domain driven CQRS architecture. You can have your &lt;em&gt;SaveData&lt;/em&gt; command. But commands like that, CRUD commands, were you don’t care about anything but persisting the data, will not trigger any behavior in you domain model. They will just persist data into your relational database, file system, blob storage, or whatever medium that holds your data.&lt;/p&gt;  &lt;p&gt;Then when new requirements arrive and you need to attach behavior to some of the data in that &lt;em&gt;SaveData&lt;/em&gt; command, you will just extract those properties out into their own command and you make that new behavior explicit. &lt;/p&gt;  &lt;p&gt;Maybe even all the way from UI and down to the domain model. That way you will capture the user’s intent and you will have means to encapsulate that precious domain knowledge inside your model.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h5&gt;&lt;strong&gt;Further Reading&lt;/strong&gt;&lt;/h5&gt;  &lt;p&gt;For more background and resources on CQRS you can take a look at my previous post &lt;a href="http://www.kjetilk.com/2010/02/growth-is-optional-choose-wisely.html"&gt;“Growth is optional. Choose wisely.”&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I mentioned the &lt;em&gt;Domain Model, Table Module&lt;/em&gt; and &lt;em&gt;Record Set &lt;/em&gt;patterns and there’s no better way to learn about these – and other patterns – than to read Martin Fowler’s excellent &lt;a href="http://martinfowler.com/books.html#eaa"&gt;“Patterns of Enterprise Application Architecture”&lt;/a&gt;. A short description of the patterns can be found in the &lt;em&gt;P of EAA Catalog’s &lt;/em&gt;&lt;a href="http://martinfowler.com/eaaCatalog/domainModel.html"&gt;&amp;quot;Domain Model&amp;quot;&lt;/a&gt;&lt;em&gt;,&lt;/em&gt;&amp;#160;&lt;a href="http://martinfowler.com/eaaCatalog/tableModule.html"&gt;&amp;quot;Table Module&amp;quot;&lt;/a&gt; and &lt;a href="http://martinfowler.com/eaaCatalog/recordSet.html"&gt;&amp;quot;Record Set&amp;quot;&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I also touched &lt;em&gt;Domain Driven Design&lt;/em&gt; a bit, and again; No better source than the source itself. If you haven’t already – go read Eric Evans &lt;a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215"&gt;“Domain Driven Design – Tackling Complexity in the Heart of Software”&lt;/a&gt;. Just do it. And you can come back and thank me for the tip afterwards :)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-613256665141605405?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/MJBRw5snZio" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/613256665141605405/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=613256665141605405&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/613256665141605405?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/613256665141605405?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/MJBRw5snZio/option-explicit-on-commands-in-cqrs.html" title="Option Explicit On – Commands in CQRS" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2010/02/option-explicit-on-commands-in-cqrs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIARn8yeip7ImA9WxBWGU8.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-89199479022040969</id><published>2010-02-11T23:15:00.001+01:00</published><updated>2010-02-11T23:15:47.192+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-11T23:15:47.192+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ddd" /><category scheme="http://www.blogger.com/atom/ns#" term="cqrs" /><title>Growth is optional. Choose Wisely.</title><content type="html">&lt;p&gt;Command Query Responsibility Segregation, or CQRS for short, is an architectural pattern based on the idea of Command Query Separation, CQS. It’s a pattern currently advocated by people like Udi Dahan, Greg Young, Mark Nijhof and Pål Fossmo (see below for links and resources). &lt;a href="http://lh4.ggpht.com/_hlZzgPJTEUM/S3SBj92E8OI/AAAAAAAAAmM/8nFeJMDIjhA/s1600-h/sw_fake_ballot_sa03045%5B7%5D.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="sw_fake_ballot_sa03045" border="0" alt="sw_fake_ballot_sa03045" align="right" src="http://lh3.ggpht.com/_hlZzgPJTEUM/S3SBkerZnII/AAAAAAAAAmQ/55DrCSMZlfs/sw_fake_ballot_sa03045_thumb%5B9%5D.jpg?imgmax=800" width="420" height="287" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The background for CQRS is a mathematical theorem called the &lt;em&gt;CAP Theorem&lt;/em&gt; put forward by Eric Brewer. It states that;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;“You can have &lt;strong&gt;at most two&lt;/strong&gt; of these properties for any shared-data system:&lt;/em&gt;&lt;em&gt; Consistency, Availability, and tolerance of network Partitions.”&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;You can only get two out of three, which basically means that you have to choose between scalability and continuous consistent data. CQRS is an architectural approach that let’s you scale out and deliver high availability, but is a bit more relaxed on the consistency. Meaning that Consistency has to step aside for Availability and Scalability. &lt;/p&gt;  &lt;p&gt;Wouldn’t inconsistent data be a bad thing and something we would really strive to avoid? Yes, it would – if data were to be permanently inconsistent. But as long as the data &lt;em&gt;eventually&lt;/em&gt; becomes consistent, this is no longer such a bad thing. &lt;/p&gt;  &lt;p&gt;After all; how long are data in a multiuser application 100% consistent anyway? Think about it; As soon as the data has left the database – or whatever storage you might have – and is heading up to the user’s screen, someone else could have updated or even deleted the records. The data can be inconsistent even before they hit the screen!&lt;/p&gt;  &lt;p&gt;Making a clear separation of commands (writes) from queries (reads) in an application gives you the ability to better scale out the parts that turns out to be bottlenecks. In most applications there are far more reads than writes, and so scaling out the read part will for most scenarios give a performance boost. &lt;/p&gt;  &lt;p&gt;Now, calling it ‘eventual consistency’ might sound like it will take ‘forever’ before data is consistent, but just as you can scale the command and query parts of the system, you can also scale out the transport mechanism between them. &lt;/p&gt;  &lt;p&gt;The transport is typically some kind of queue, for instance MSMQ-based, and so the time before data is consistent is coherent to the speed of the transport. Throw in some more power on the queuing machinery, and you get more up-to-date data.&lt;/p&gt;  &lt;h5&gt;Further reading&lt;/h5&gt;  &lt;p&gt;Udi Dahan’s &lt;a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/"&gt;“Clarified CQRS”&lt;/a&gt; is a good and thorough intro to CQRS. &lt;/p&gt;  &lt;p&gt;More introductory on CQRS and how it relates to DDD by Pål Fossmo here; &lt;a href="http://blog.fossmo.net/post/Command-and-Query-Responsibility-Segregation-(CQRS).aspx"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Greg Young gives some clarifications on CQS vs CQRS in &lt;a href="http://codebetter.com/blogs/gregyoung/archive/2009/08/13/command-query-separation.aspx"&gt;&amp;quot;Command Query Separation?&amp;quot;&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;For some more practical samples check out Mark Nijhof’s blog post &lt;a href="http://blog.fohjin.com/blog/2009/11/12/CQRS_a_la_Greg_Young"&gt;&amp;quot;CQRS à la Greg Young&amp;quot;&lt;/a&gt;, were he introduces his demo app on CQRS and Event Sourcing. &lt;/p&gt;  &lt;p&gt;Jonathan Oliver has a run-through of CQRS vs Active Record vs Traditional Domain Model in &lt;a href="http://jonathan-oliver.blogspot.com/2009/10/dddd-why-i-love-cqrs.html"&gt;&amp;quot;DDDD: Why I Love CQRS&amp;quot;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If you’re in the mood for some more background material on &lt;em&gt;Brewer’s CAP Theorem&lt;/em&gt;, Julian Browne has an excellent article called &lt;a href="http://www.julianbrowne.com/article/viewer/brewers-cap-theorem"&gt;&amp;quot;Brewer's CAP Theorem – The cool aid Amazon and Ebay have been drinking&amp;quot;&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;And just when you’re all pumped up and high on CQRS; Read the &lt;a href="http://blog.robustsoftware.co.uk/2009/12/cqrs-crack-for-architecture-addicts.html"&gt;“CQRS: Crack for architecture addicts”&lt;/a&gt; by Gary Shutler. It might get you down on the ground again. I might not agree with him, but he makes some valid points.&lt;/p&gt;  &lt;p&gt;And of course, for all DDD-related topics; The &lt;a href="http://tech.groups.yahoo.com/group/domaindrivendesign/"&gt;Yahoo Group for Domain Driven Design&lt;/a&gt;. Lot’s of good discussion there – including CQRS.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-89199479022040969?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/4-KLR7i3xPk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/89199479022040969/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=89199479022040969&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/89199479022040969?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/89199479022040969?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/4-KLR7i3xPk/growth-is-optional-choose-wisely.html" title="Growth is optional. Choose Wisely." /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.kjetilk.com/2010/02/growth-is-optional-choose-wisely.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08CSHw_eCp7ImA9WxBREU8.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-3684307003388111934</id><published>2009-12-29T11:40:00.001+01:00</published><updated>2009-12-29T22:24:29.240+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-29T22:24:29.240+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><title>So you think you can Host?</title><content type="html">&lt;a title="Photo by sylvar (Flickr Creative Commons)" href="http://www.flickr.com/photos/sylvar/31436964/"&gt;&lt;img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Flickr CC by 2.0" border="0" alt="Flickr CC by 2.0" align="right" src="http://lh3.ggpht.com/_hlZzgPJTEUM/SzncrZTMnxI/AAAAAAAAAmA/zoNWlVuMcuU/image%5B7%5D.png?imgmax=800" width="234" height="307" /&gt;&lt;/a&gt;   &lt;p&gt;Through out my career I’ve often come across small-sized dev-shops that believe…&lt;/p&gt;  &lt;p&gt;a) That being their own Application Service Provider (ASP) and hosting their product on their own servers is cheaper, easier and safer than letting a third-party handle it&lt;/p&gt;  &lt;p&gt;b) That any dev with a bit of interest for servers and hardware is capable of filling the roles of a full-fledge developer &lt;em&gt;and &lt;/em&gt;an&lt;em&gt; &lt;/em&gt;IT Pro&lt;/p&gt;  &lt;p&gt;Through out my career I’ve never seen this work out particularly well. &lt;/p&gt;  &lt;p&gt;The reason why it never works is seldom the lack of talent for the poor dev who ‘stood closest to the server when the last dev-slash-it-guy left’ (freely quoted from &lt;a href="http://twitter.com/richcampbell"&gt;Richard Campbell&lt;/a&gt; of &lt;a href="http://www.dotnetrocks.com/"&gt;DotNetRocks&lt;/a&gt;). It’s just that being a IT Pro is just as much of a full-day job as being a professional programmer.&lt;/p&gt;  &lt;p&gt;In this crazy world of new technologies, languages, frameworks, tools and methodologies that pops up every five minutes, there’s just NO WAY a poor soul can handle two full-time jobs like that and still be GOOD AT BOTH. Some things just got to suffer.&lt;/p&gt;  &lt;p&gt;Being a developer by heart – and by job description – it’s pretty obvious which one of those jobs that will suffer. The problem is that you can probably live with this situation for a while before it really hits you. But be sure; it &lt;em&gt;will &lt;/em&gt;hit you.&lt;/p&gt;  &lt;p&gt;You can have 99,5% uptime for 3 years in a row. But when that server goes up in flames and the backup system won’t restore your last 3 months worth of data, you’ve ruined your uptime numbers for the next 3 decades.&lt;/p&gt;  &lt;p&gt;Being a IT Pro means being pro-active. It’s a constant fight to stay ahead of any troubles. And to be prepared and having fail-over when trouble hits you. &lt;/p&gt;  &lt;p&gt;Being a dev-slash-it-guy means you won’t have neither time nor devotion to being pro-active. Instead you’re being post-active; you’re putting out small fires every now and then, but you’re seldom doing much to prevent them from catching on.&lt;/p&gt;  &lt;p&gt;If you’re a startup company with most customers on beta-programs and not much paying customers yet, that might be ok. But someday you’ll hopefully find yourself with a nice list of paying customers that depends on that nice little piece of software that you &lt;strike&gt;hacked together&lt;/strike&gt; wrote. &lt;/p&gt;  &lt;p&gt;They might not expect your software to be flawless (even though they probably should), but they expect it to be there when they need it. They start demanding uptime guarantees and Service Level Agreements, SLAs (or at least they &lt;em&gt;should&lt;/em&gt; demand guarantees and SLAs). And you better take steps to make sure that you can provide a level of expected professionalism when it comes to hosting your own services. &lt;/p&gt;  &lt;p&gt;Do you think you can deliver that with a (at most) half-time IT pro? My best guess is ‘probably not’. &lt;a href="http://www.everystockphoto.com/photo.php?imageId=3774884"&gt;&lt;img style="border-right-width: 0px; margin: 10px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_hlZzgPJTEUM/SzncsfeY8jI/AAAAAAAAAmE/4zSqesgJmgc/image%5B12%5D.png?imgmax=800" width="446" height="299" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;From my experience in the field, here’s some questions you should start asking yourself if you find yourself at this stage;&lt;/p&gt;  &lt;p&gt;(Now, here comes a full disclosure up front; I’m definitely no IT Pro myself – and I have no intentions what-so-ever to become one. This list might therefore not be 100%-water-and-bulletproof, but if you find some misjudgments or something you’d like to add to the list, please feel free to correct me or give suggestions in the comments below)&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;How many ports are open and how many services are running and available from the outside on your public server(s)? (The server(s) that hosts your software that is). Do you for instance allow remote desktop connections to your public server(s) to be able to troubleshoot it? &lt;/li&gt;    &lt;li&gt;What happens if someone from the outside takes control over your public server? Do they get access to your local network and domain as well? &lt;/li&gt;    &lt;li&gt;How many servers are actually accessible from the outside? &lt;/li&gt;    &lt;li&gt;Do you have a working Virtual Private Network, VPN, that anyone in your business can use? And if so; Is it secure enough? &lt;/li&gt;    &lt;li&gt;How many times in the last 6 months have you verified that you can actually restore all the data from your backup device? And how sure are you that you’re actually backing up everything you need? Or put it this way; if your office burns down today, will you have all the necessary data available to do business-as-usual tomorrow? &lt;/li&gt;    &lt;li&gt;How often do you scan your network for suspicious activities? Are you sure you’re alone on your network? &lt;/li&gt;    &lt;li&gt;Do you have a wireless network available in your office? If so; what minimum level of security does it demand? Do you have just a pre-shared key which then gives you full access to the domain, or do you have something that is actually secure enough to prevent teenage hackers to access your file servers? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I’m not saying that any 3-5 man shops must hire a full time IT Pro to handle this. This is off course a question of cost. But just like you’re probably out-sourcing accounting to some professional book-keeper, you should also out-source other areas that is just as critical for your business. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.everystockphoto.com/photo.php?imageId=1679"&gt;&lt;img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="right" src="http://lh3.ggpht.com/_hlZzgPJTEUM/SznctDg9ZrI/AAAAAAAAAmI/bHbN_1yuhjw/image%5B16%5D.png?imgmax=800" width="397" height="299" /&gt;&lt;/a&gt;If you’re a small- or medium-sized dev-shop, hosting is in my experience always handled better by professional ASPs. And the same goes for securing and managing your IT infrastructure.&lt;/p&gt;  &lt;p&gt;Don’t get blinded by your luck so far; sooner or later your luck &lt;em&gt;will&lt;/em&gt; run out. Then it will no longer be neither cheaper, easier nor safer to handle hosting and infrastructure by yourself – and there’s nothing you can do about it.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-3684307003388111934?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/SpWInftM-Ds" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/3684307003388111934/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=3684307003388111934&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/3684307003388111934?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/3684307003388111934?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/SpWInftM-Ds/so-you-think-you-can-host.html" title="So you think you can Host?" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/12/so-you-think-you-can-host.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EARn86eip7ImA9WxNaGEo.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-6477808988679284607</id><published>2009-12-03T23:25:00.001+01:00</published><updated>2009-12-03T23:34:07.112+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-03T23:34:07.112+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tips" /><title>My favorite Windows 7 Hotkeys</title><content type="html">&lt;p&gt;I’ve been using Win7 since beta 2 and I like it a lot. It’s in my opinion by far the best Windows operating system – a lot better than both Vista and XP. Not that it’s such an enormous change from Vista. It’s just the sum of all the small things. Like the perceived overall UI performance. The improved task bar. The speed of the start menu. The search on the start menu (I just can’t remember the last time I actually needed to click my way through the start menu to start a program. I just type in whatever app or feature I need to start or open, and 99 out of 100 it comes up among the top 3-4 items). And not at least; the hotkeys:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Win + Arrow&lt;/strong&gt;: Docks the active window to the left or right, or minimizes (down arrow) or maximizes (up arrow) it. Or if the window is maximized and you hit &lt;em&gt;Win + Down Arrow&lt;/em&gt;, the window will be restored. If you hit the same &lt;em&gt;Win + Down Arrow&lt;/em&gt; again it will be minimized. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + Shift + Left/Right Arrow&lt;/strong&gt;: Moves a window to the monitor on the left or right keeping the same position as it had on the monitor you moved it from. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + Home&lt;/strong&gt;: Hides all open windows except the active (you can do the same by grabbing hold of the window title bar with the left mouse button (just as if you’d want to move the window around) and ‘shake’ the window you want to leave open) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + T&lt;/strong&gt;: Puts focus on the taskbar so that you can use the arrow keys to move between the programs on the task bar and then &lt;em&gt;Enter &lt;/em&gt;to activate them, &lt;em&gt;Shift+Enter&lt;/em&gt; to open a new instance, or the ‘right menu button’ to get up the menu for each program. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + Number&lt;/strong&gt;: Opens the program on the given index on your taskbar. For instance if you have pinned Outlook to the first position on the task bar, &lt;em&gt;Win + 1&lt;/em&gt; will start Outlook (or maximize it and bring it to the front if it’s minimized or behind some other windows). &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + P&lt;/strong&gt;: Opens up the “Connect to a projector/external display” dialog with the options to show your desktop on the computer only, duplicate it, extend it or show it on the projector (external display) only. &lt;img style="border-bottom: 0px; border-left: 0px; margin: 10px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="The &amp;#39;Connect to a projector&amp;#39; dialog" border="0" alt="The &amp;#39;Connect to a projector&amp;#39; dialog" src="http://lh4.ggpht.com/_hlZzgPJTEUM/Sxg6uTz66PI/AAAAAAAAAlk/mfzBfe1rGqc/image%5B13%5D.png?imgmax=800" width="597" height="130" /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + X&lt;/strong&gt;: Opens up the “Windows Mobility Center” where you can adjust display brightness, volume, battery mode, wireless connectivity, external display, sync connected devices, and presentation settings. &lt;a href="http://lh5.ggpht.com/_hlZzgPJTEUM/Sxg6uznN4zI/AAAAAAAAAlo/XOU0NGujP9s/s1600-h/image%5B14%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 10px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="Windows Mobility Center" border="0" alt="Windows Mobility Center" src="http://lh6.ggpht.com/_hlZzgPJTEUM/Sxg6veLoDGI/AAAAAAAAAlw/f29C7R0yUv0/image_thumb%5B6%5D.png?imgmax=800" width="595" height="299" /&gt;&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + Space&lt;/strong&gt;: Peek at the desktop – that is; make all windows transparent so that you can see the desktop. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + E&lt;/strong&gt;: Opens the Windows Explorer &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Ctrl + Shift + Esc&lt;/strong&gt;: Opens the Task Manager &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Win + R&lt;/strong&gt;: Opens the &lt;em&gt;Run&lt;/em&gt; dialog &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Ctrl + Shift (&lt;/strong&gt;when launching apps): Runs the program as administrator. For instance; open the &lt;em&gt;Run&lt;/em&gt; dialog and type ‘cmd.exe’ (or just ‘cmd’). If you just hit &lt;em&gt;Enter&lt;/em&gt; you will open the command prompt under the privileges of the user you’re currently logged in as. But if you instead hit &lt;em&gt;Shift+Enter&lt;/em&gt;, you will open the command prompt with Administrator privileges. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Some of these are not really new to Win7, but I just threw them in there anyway because they’re just so incredibly useful :)&lt;/p&gt;  &lt;p&gt;These hotkeys (or shortcut keys) just makes my working day a little better and a little bit more productive. Mix these in with some of the new features of the Windows Explorer and it can just make your day a bit brighter;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Shift + Right-click&lt;/strong&gt; on a folder gives you some extra options compared to just right-click. For instance the “Open command window here” and “Open in new process”. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Ctrl + Shift + N&lt;/strong&gt;: Creates a new folder &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Right-click + Drag &lt;/strong&gt;folder to the Windows Explorer icon on the taskbar pins the folder, so that you can right-click on the Windows Explorer icon on the taskbar and get direct access to the folder from the jump list. &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-6477808988679284607?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/usHAEbRGXIU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/6477808988679284607/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=6477808988679284607&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/6477808988679284607?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/6477808988679284607?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/usHAEbRGXIU/my-favorite-windows-7-hotkeys.html" title="My favorite Windows 7 Hotkeys" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/12/my-favorite-windows-7-hotkeys.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUANRno4eyp7ImA9WxNaGE4.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-5183728828052987024</id><published>2009-11-17T13:05:00.001+01:00</published><updated>2009-12-03T11:56:37.433+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-03T11:56:37.433+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wcf" /><title>Configure WCF to run on Windows 7</title><content type="html">&lt;p&gt;When you’ve installed Windows 7 and installed all the appropriate IIS features, WCF will still not be available on your box by default. I’ve had this little note to myself laying around somewhere on the file system, but I just keep forgetting where it is every time I need it. So I’ll put it up here, just to make the search a bit easier :)&lt;/p&gt;  &lt;p&gt;Open up the command prompt in &lt;strong&gt;Administrator mode&lt;/strong&gt;, and run the following command;&lt;/p&gt;  &lt;p&gt;c:\…&amp;gt;&lt;strong&gt;&amp;quot;%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe&amp;quot; -r&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This will map the s&lt;em&gt;vc&lt;/em&gt; file type to &lt;em&gt;aspnet_isapi.dll&lt;/em&gt;&amp;#160; and will make IIS recognize WCF services and startup the ServiceHost for you. In other words; the &lt;em&gt;svc&lt;/em&gt; MIME type will be registered with IIS. The parameters on the end is;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;-r: &lt;/strong&gt;&lt;em&gt;Re-registers this version of WCF and updates scriptmaps at the IIS metabase root and for all scriptmaps under the root. Existing scriptmaps are upgraded to this version regardless of the original versions.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;(copied from the official docs on the “&lt;a href="http://msdn.microsoft.com/en-us/library/ms732012.aspx"&gt;ServiceModel Registration Tool&lt;/a&gt;”)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;If you’ll be running integration tests against your services and the test will do WCF self hosting (instead of IIS), you also need to authorize the urls that your self-hosting service will be using;&lt;/p&gt;  &lt;p&gt;c:\…&amp;gt;&lt;strong&gt;netsh http add urlacl url=http://+:[port]/ user=&amp;quot;[windows user name]&amp;quot;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;As for the ServiceModelReg command, this one will also need administrator privileges on your command prompt. Replace the &lt;em&gt;[windows user name]&lt;/em&gt; with the account you’ll be running the test under. Usually this will be the account you’re logged in with, e.g. “domain\user”. The [port] parameter will be the port number you’ve configured on your WCF endpoint (typically 8000 for testing).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;And just to be sure; restart the IIS after you’ve run these commands; &lt;/p&gt;  &lt;p&gt;c:\…&amp;gt;&lt;strong&gt;iisreset&lt;/strong&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-5183728828052987024?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/AD4QZp8hlbI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/5183728828052987024/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=5183728828052987024&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/5183728828052987024?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/5183728828052987024?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/AD4QZp8hlbI/configure-wcf-to-run-on-windows-7.html" title="Configure WCF to run on Windows 7" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/11/configure-wcf-to-run-on-windows-7.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8HQ3g8eSp7ImA9WxJUEkg.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-3710292411476615821</id><published>2009-07-10T21:40:00.001+02:00</published><updated>2009-07-10T21:40:32.671+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-10T21:40:32.671+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="source control" /><title>The Great Git In The Sky</title><content type="html">&lt;p&gt;Every developer should know that having a good versioning system for your source files is crucial. Having the possibilities to go back in time and see what your class or module or project looked like is indispensible. And if you’re more than one developer on a project, having a common place – a repository – to store all files is even more indispensible. &lt;/p&gt;  &lt;p&gt;Throughout the years I’ve tried a couple of different source control systems. Being a .Net developer on the Microsoft platform, I’ve tried both Visual SourceSafe (VSS) and Team Foundation Server (TFS) and I’ve also used the open source alternative SubVersion (SVN). Lately there’s a new source control system that has drawn my attention, namely Git.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; is a fairly new source control system and was originally developed by Linus Torvalds to be used developing the Linux kernel. The first version of Git came in 2005, but wasn’t available on the Windows platform until late 2007 through the open source project &lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt; (unless you were running the unix emulator &lt;a href="http://www.cygwin.com/"&gt;cygwin&lt;/a&gt;, that is).&lt;/p&gt;  &lt;p&gt;Git has a bit different take on how you manage source control than what I’ve been used to from the previous tools I’ve used. TFS, VSS and SVN lets you setup a centralized repository where you store all your files, keep track of version history, do branching, etc. But Git is a bit different in the sense that the repository is now localized on your machine and when several people are working on the same project, all repositories are essentially synchronized across all development machines – a so called &lt;em&gt;distributed source control system&lt;/em&gt;. Which means that you have access to the full history of your source files locally. You can also have a remote Git-repository which local repositories can push and pull changes to and from, but all local histories still have the full version history.&lt;/p&gt;  &lt;h4&gt;Creating a Git repository using msysgit&lt;/h4&gt;  &lt;p&gt;For each project you want to put under source control, you just add a Git repository to the root folder of your project. Say you have some code laying on ‘C:\Code\Work\MyProject’. If you want to place this under Git’s source control and you’ve installed &lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt; with the integration to Windows Explorer, then you just right click on the folder and choose ‘Git GUI Here’ (or ‘Git Bash Here’ if you’d rather use the command prompt). You have to choose ‘Create New Repository’ and then put in the directory ‘C:\Code\Work\MyProject’ in the textbox that follows (a little glitch in the UX design there; it would have been friendlier if it actually had remembered where I opened the GUI from and then put in that directory by default). &lt;/p&gt;  &lt;p&gt;In the list of ‘Unstaged Changes’ in the upper right corner you can now choose the files you want to include in the repository. Select the appropriate files and then press Ctrl+T (Or &lt;em&gt;Commit &lt;/em&gt;&amp;gt; &lt;em&gt;Stage to commit&lt;/em&gt;). Then you can commit these into the repository with Ctrl+Return (&lt;em&gt;Commit &amp;gt; Commit&lt;/em&gt;).&lt;/p&gt;  &lt;p&gt;Alternatively you can do the same from the command line, and in fact there are a couple of things you should do on the command line before you start committing to the repository. First of all you should enter your name and email, as this will be used on all commits;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_hlZzgPJTEUM/SleZE9W9ezI/AAAAAAAAAjc/6t82rG_nLw8/s1600-h/image16.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Configure name and email" border="0" alt="Configure name and email" src="http://lh4.ggpht.com/_hlZzgPJTEUM/SleZFZQbjQI/AAAAAAAAAjg/BHBLQKkFdoE/image_thumb10.png?imgmax=800" width="451" height="102" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The ‘—global’ parameter hints that this is a configuration setting that will be effective across all Git repositories on this machine. You could also have done this through the &lt;em&gt;Git GUI&lt;/em&gt; (Edit &amp;gt; Options…), but the next thing I’ll setup I couldn’t find a way to do in the current version (v 0.12.0.23); adding ignore patterns. In a typical .net project you wouldn’t want to add for instance the &lt;em&gt;bin &lt;/em&gt;and &lt;em&gt;obj &lt;/em&gt;folders to the repository, and the way to ignore these files is to add a ‘.gitignore’ file to the root folder of your project. You can try to do this in Windows Explorer, but I think you’ll quickly find that this is actually not possible. But through the bash it’s a walk in the park.&lt;/p&gt;  &lt;p&gt;To make my point I’ve created a console app called &lt;em&gt;GitExample&lt;/em&gt; and I’ve open the bash in the root directory. I can now issue a &lt;em&gt;git init&lt;/em&gt; command that will initialize a Git repository here, and by calling &lt;em&gt;git status&lt;/em&gt; I can list all files and folders that are currently not under source control:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_hlZzgPJTEUM/SleZGHCGttI/AAAAAAAAAjk/HJWGw-EsDUA/s1600-h/image15.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Initialize git repository" border="0" alt="Initialize git repository" src="http://lh4.ggpht.com/_hlZzgPJTEUM/SleZGl32oeI/AAAAAAAAAjo/pzP36JFpkOc/image_thumb9.png?imgmax=800" width="583" height="284" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And as we can see there are a lot of things here that I really don’t want to add to the repository. Let’s be ignorant;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_hlZzgPJTEUM/SleZGwCu2pI/AAAAAAAAAjs/FsInjeFZxwY/s1600-h/image43.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Create ignore file" border="0" alt="Create ignore file" src="http://lh3.ggpht.com/_hlZzgPJTEUM/SleZHTrSdII/AAAAAAAAAjw/w_FraDQ5QTo/image_thumb25.png?imgmax=800" width="153" height="21" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The &lt;em&gt;touch &lt;/em&gt;command will create the file and you can now edit it in your favorite text editor. The following list shows my ignorance;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_hlZzgPJTEUM/SleZHlBVXyI/AAAAAAAAAj0/Zey_tVRPZL8/s1600-h/image35.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Ignore pattern" border="0" alt="Ignore pattern" src="http://lh6.ggpht.com/_hlZzgPJTEUM/SleZIOI21MI/AAAAAAAAAj4/RiP7goHUxOM/image_thumb21.png?imgmax=800" width="121" height="115" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;With this in place we can now run the &lt;em&gt;status&lt;/em&gt; command and we’ll see that there’s a lot less to care about for our Git commit process;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_hlZzgPJTEUM/SleZIYdM-iI/AAAAAAAAAj8/wZZrN8prSv8/s1600-h/image40.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="List of files without the ignored ones" border="0" alt="List of files without the ignored ones" src="http://lh5.ggpht.com/_hlZzgPJTEUM/SleZIwxif-I/AAAAAAAAAkA/cbV9OwZOHAc/image_thumb24.png?imgmax=800" width="563" height="186" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now it’s time to add the files to the repository, which you off course can do either through the GUI or the command line, but since we’re already in Unix mode let’s do it the hard core way. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_hlZzgPJTEUM/SleZJcv2lwI/AAAAAAAAAkE/FyL1D6jtxqg/s1600-h/image47.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Add to staging area and commit to repository" border="0" alt="Add to staging area and commit to repository" src="http://lh6.ggpht.com/_hlZzgPJTEUM/SleZJxevIzI/AAAAAAAAAkI/mItEGNKyktU/image_thumb27.png?imgmax=800" width="551" height="441" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The procedure around committing files to the repository is 2-phased. We do a “&lt;em&gt;add .”&lt;/em&gt; to add all untracked files in our working directory into the staging area of the repository. The staging area is set of files that are ready to be committed and you can do a lot of &lt;em&gt;add&lt;/em&gt; (and &lt;em&gt;remove&lt;/em&gt;) before you finally decide to commit all changes into the actual repository. And to commit the files you call the &lt;em&gt;commit&lt;/em&gt; command with a “-m” parameter to add a comment to the files you’re committing. And as you can see from the screenshot above, after we’ve moved the files from the working directory to the staging area and then from the staging area to the repository, our working directory is now clean.&lt;/p&gt;  &lt;h4&gt;Mesh It Up!&lt;/h4&gt;  &lt;p&gt;I mentioned a bit earlier that if you want to share the repository with someone you can setup a remote repository. A popular repository host is &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; which let you store up to 300mb free of charge (unlimited storage for public repositories). You can then push and pull changes to and from this location (take a look at &lt;a href="http://www.lostechies.com/blogs/jason_meridth/archive/2009/06/04/git-for-windows-developers-git-series-part-2.aspx"&gt;this excellent blog post by Jason Meridth&lt;/a&gt; to see how you can do this). &lt;/p&gt;  &lt;p&gt;Another alternative is to use your &lt;a href="http://www.mesh.com"&gt;Live Mesh&lt;/a&gt; account as the remote repository. Pål Fossmo did a great blog on how you can &lt;a href="http://blog.fossmo.net/post/Ten-steps-on-how-to-store-Git-repositories-in-Live-Mesh!.aspx"&gt;setup Git together with Mesh&lt;/a&gt; which shows you how to configure your mesh folders. To initialize the Mesh repository you can use the &lt;i&gt;clone&lt;/i&gt; command as shown below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_hlZzgPJTEUM/SleZKbooGsI/AAAAAAAAAkM/CYLR9x-x1us/s1600-h/image52.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_hlZzgPJTEUM/SleZK9An4FI/AAAAAAAAAkQ/sVPRyEV98BU/image_thumb30.png?imgmax=800" width="534" height="52" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The &lt;i&gt;clone&lt;/i&gt; command does what you think it does; it makes a copy of your repository and the &lt;i&gt;bare&lt;/i&gt; parameter tells Git to strip down the repository to only what is necessary for the change tracking. That means no working copy of the source files – only the binaries, diffs, etc, that the Git database needs. You can then &lt;i&gt;push&lt;/i&gt; and &lt;i&gt;pull&lt;/i&gt; between local repositories and the Mesh repository which then will be synced with the cloud.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_hlZzgPJTEUM/SleZLUH-0MI/AAAAAAAAAkU/L9SiyfCJi-I/s1600-h/image3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_hlZzgPJTEUM/SleZLwDl9dI/AAAAAAAAAkY/3vYh_a7411Q/image_thumb1.png?imgmax=800" width="549" height="127" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Why use Git?&lt;/h4&gt;  &lt;p&gt;“Git – the fast version control system”. I guess that the slogan will make a solid statement by itself, and if you’ve worked with source control systems before you’ll definitely appreciate the speed of Git. Visual SourceSafe is notoriously slow on just about every operation you perform (especially over http(s)). SubVersion is pretty fast on check-ins, but not that fast on check-outs. And TFS is pretty fast overall and also gives you the possibility to setup local proxies if you have distributed teams. But for a more quantified view on Git’s performance you can check out Scott Chacon which has &lt;a href="http://whygitisbetterthanx.com/#git-is-fast"&gt;compared the speed of Git to Mercurial and Bazaar&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;TFS might compete to a certain extent on speed, but when it comes to the install footprint and not at least the effort it takes to actually install TFS 2008, Git will outperform TFS any day of the week. That said; TFS is a lot more than just a version control system. But if you plan on using TFS solely for the purpose of tracking your precious source files, my advice is pretty clear; Don’t! It’s not worth it – neither in time nor money. &lt;/p&gt;  &lt;p&gt;Compared to SubVersion it strikes me that the merging capabilities of Git are a bit better. Git tracks the content of files – not the files itself, and so merging operations seams more likely to be correct in Git. In my opinion the merge operations in SVN is probably one of its weakest point; doing large merge operations in SVN is just pain and you just &lt;i&gt;know &lt;/i&gt;you’re about to get burned. TFS on the other hand seems a bit better on the merging than SVN, but then again; time and money…&lt;/p&gt;  &lt;p&gt;I guess it’s time for a little disclaimer here; I haven’t really used Git much yet, and so I haven’t done any large merge operations and so I might be wrong here. But from what I’ve read and from how Git is built as a distributed source control system, I have a strong feeling that merging is really one of Git’s sweat spots. &lt;/p&gt;  &lt;p&gt;Anyways, if you have any other opinions on the subject – or to anything else in this post – please feel free to speak your mind in the comments below :) &lt;/p&gt;  &lt;h4&gt;Resources&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git.html"&gt;“Git Manual Page”&lt;/a&gt; is the official documentation on Git and it’s actually quit good. Lot’s of good examples and pretty well written. RTFM, right?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.kernel.org/pub/software/scm/git/docs/everyday.html"&gt;“Everyday GIT With 20 Commands Or So”&lt;/a&gt; from the official tutorial will give you a head start on the most used commands.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://gitready.com/"&gt;“Git Ready”&lt;/a&gt; has put some of the commands into 3 categories; beginner, intermediate, and advanced.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/blogs/jason_meridth/archive/2009/06/01/git-for-windows-developers-git-series-part-1.aspx"&gt;“Git For Windows Developers”&lt;/a&gt; – the title says it all I guess. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://git.or.cz/course/svn.html"&gt;“Git – SVN Crash Course”&lt;/a&gt; will give you a head start on using Git if you’re already familiar to SubVersion.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://whygitisbetterthanx.com/"&gt;“Why Git is better than X”&lt;/a&gt; has done some (slightly biased?) comparisons against other source control systems.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt; is the tool to download and install if you need Git to run on a Windows box.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://code.google.com/p/tortoisegit/"&gt;TortoiseGit&lt;/a&gt; is another client for Git repositories. If you’re familiar with &lt;a href="http://tortoisesvn.net/"&gt;TortoiseSVN&lt;/a&gt; for SubVersion, the learning curve will be close to zero.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://github.com/plans"&gt;GitHub&lt;/a&gt; lets you store up to 300mb in private repositories (unlimited storage for public repositories).&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-3710292411476615821?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/akPxcW4jFBU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/3710292411476615821/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=3710292411476615821&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/3710292411476615821?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/3710292411476615821?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/akPxcW4jFBU/great-git-in-sky.html" title="The Great Git In The Sky" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/07/great-git-in-sky.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UDQXs7eSp7ImA9WxJVFU4.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-4400924859988550553</id><published>2009-06-23T08:56:00.001+02:00</published><updated>2009-07-02T12:41:10.501+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-02T12:41:10.501+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><title>NDC 2009 Highlights</title><content type="html">&lt;p&gt;The &lt;a href="http://www.ndc2009.no/"&gt;Norwegian Developers Conference 2009&lt;/a&gt; took place in Oslo last week and I was lucky enough to be one of the around 1000 attendees. That’s about half the crowd the organizer was hoping for, but I guess we’ll have to blame the ongoing financial turbulence for that. It was definitely not due to the speaker list, because that was straight out impressing. And the pricing seemed very reasonable too. Or maybe calling it the &lt;em&gt;Norwegian&lt;/em&gt; Developers Conference scared away any foreigners? I don’t know, but those who weren’t there really missed out on a great event.&lt;a href="http://www.flickr.com/photos/grothaug/3639721848/in/set-72157619854994646/"&gt;&lt;img style="border-right-width: 0px; margin: 10px auto 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Photo by Rune Grothaug" border="0" alt="Photo by Rune Grothaug" src="http://lh3.ggpht.com/_hlZzgPJTEUM/SkB8qiLshqI/AAAAAAAAAi8/uQ2mILM---o/image%5B36%5D.png?imgmax=800" width="466" height="319" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’ll try to summarize some of my thoughts and impressions from this 3 day conference in this post, so let’s start with the most important part; the sessions. Most of the sessions was taped and will be available online in the (hopefully) near future. I had already studied the agenda in detail before I went, but as always when attending conferences like this; &lt;a href="http://www.kjetilk.com/2009/05/my-ndc-2009-agenda.html"&gt;the plan&lt;/a&gt; was due to change. But I’ll try to list some of my favorite sessions from the conference and I really recommend taking a look at these when they come online. So here’s my top 5 in descending order;&lt;/p&gt;  &lt;h5&gt;1. Michael Feathers: “Working Effectively with the Legacy Code: Taming the Wild Code Base” &lt;/h5&gt;  &lt;p&gt;I’ve watched a couple of talks by Feathers up on &lt;a href="http://www.infoq.com/presentations/error-prevention-ethics"&gt;InfoQ&lt;/a&gt; and he’s a really skilled speaker as well as writer. I haven’t had time to read his book “Working Effectively with the Legacy Code” yet, but it’s definitely one I will pick up soon. The talk was great and he had lots of good tips if you’re faced with a codebase that is not built to be testable.&lt;/p&gt;  &lt;h5&gt;2. Kevlin Henney: “The Uncertainty Principle”&lt;/h5&gt;  &lt;p&gt;On day 3 of NDC my original plan was to attend Scott Bellware’s whole day workshop on testing, but I was too late for the registration so the workshop filled up before I got to sign up. Instead I spend the whole day with Kevlin, which really was a great alternative. I was lucky enough to get to hear him doing a talk here in Trondheim about a month prior to the conference, so I knew that this was going to be good. Kevlin has done some great work on design patterns and his talks are both informative and entertaining. I really recommend all of his talks, but if I were to pick one favorite I’d go for “The uncertainty principle”. &lt;/p&gt;  &lt;h5&gt;3. Glenn Block: “Building Maintainable Enterprise Applications with Silverlight and WPF”&lt;/h5&gt;  &lt;p&gt;I’m a big fan of the &lt;a href="http://compositewpf.codeplex.com"&gt;PRISM&lt;/a&gt; and we’re using it on our current project. The talk was mainly about PRISM, but he also had some great tips on how to ease some of the pain in regards to databinding the ViewModel to the View. Now, don’t get me wrong here; I love databinding in WPF, but there’s some pain points regarding refactoring when it comes to the string-based databinding against properties in the ViewModel. Glenn showed off some interesting tools that he’s working on to make this easier, and it will be up on CodePlex in not so long (I hope!). The essence of the tool was that if you name your controls in the View the same as the corresponding property in the ViewModel, and then it could perform an auto-mapping between the View and ViewModel. Anyway; it was a great talk and I got some valuable tips to take with me. Unfortunately this was one of the none-taped sessions, so this will not be available online as far as I know.&lt;/p&gt;  &lt;h5&gt;4. Udi Dahan: “Designing High Performance, Persistent Domain Models”&lt;/h5&gt;  &lt;p&gt;Design patterns are in many ways lessons learned over the mere 50 years of developing software. PRISM is, among other things, a set of design patterns to apply if you’re building composite applications and is focused mainly on the presentation layer. Domain-driven design on the other hand are design patterns that focus on the core of the business; the domain model. Udi gave an excellent talk on the performance perspective of DDD.&lt;/p&gt;  &lt;h5&gt;5. Peter Provost: “Code First Analysis and Design with Visual Studio Team System 2010 Arch Ed Microsoft Visual”&lt;/h5&gt;  &lt;p&gt;It’s just amazing to see what the architect edition of VS10 contains and I really look forward to some of the features that Peter showed off here. He’s a joy to listen to and it just reeks knowledge of this guy. If you like a quick tour of VS10 architect edition and see how you can read code in a new dimension, I highly recommend this session.&lt;/p&gt;  &lt;h5&gt;Runners Up &lt;/h5&gt;  &lt;p&gt;&lt;a title="Left to right; Phil Haack, Scott Hanselman, Richard Campbell, and Carl Franklin" href="http://www.flickr.com/photos/grothaug/3639842316/in/set-72157619854994646/"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Photo by Rune Grothaug" border="0" alt="Photo by Rune Grothaug" align="left" src="http://lh4.ggpht.com/_hlZzgPJTEUM/SkB8rfpisQI/AAAAAAAAAjA/N8axVeccTFo/image%5B17%5D.png?imgmax=800" width="369" height="259" /&gt;&lt;/a&gt; Other memorable sessions to watch will be the &lt;em&gt;.NET Rocks!&lt;/em&gt; episode recorded live [&lt;strong&gt;Update:&lt;/strong&gt; Download the &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=458"&gt;podcast here&lt;/a&gt;]. As always hosted by the &lt;a href="http://www.laurel-and-hardy.com/"&gt;Hardy &amp;amp; Hardy&lt;/a&gt; of the .Net community, Carl Franklin and Richard Campbell, and this time they had invited the HaaHa Brothers (Scott Hanselman and Phil Haack) to do a show. And what a show! Porn, beer and Bing – I say no more…&lt;/p&gt;  &lt;p&gt;And the HaaHa Brothers show was also a blast. Haack showed some nice tricks to hack Hanselman’s “secure” bank application and the two of them just put together a great show. Put Hanselman on stage and you’re guaranteed a good time!&lt;/p&gt;  &lt;p&gt;If you’re into DDD you’ll also find Jimmy Nilsson’s sessions quit interesting. Among other things he showed how one could use the upcoming Entity Framework 4 as the O/R-mapper in a DDD scenario. The way he turned user stories into BDD-ish unit tests was also quit interesting and definitely something I will try out myself.&lt;/p&gt;  &lt;h4&gt;The social side of it&lt;/h4&gt;  &lt;p&gt;Going to conferences like this is off course not only about the talks and the technical stuff. The social aspect of it is also a great part of it, and the NDC organizers had really put a lot of effort into making that part as equally successful as the technical side. The geek beer on Wednesday started off with an unforgettable jam session with Carl Franklin and Roy Osherove. Anyone who’s attended one of Roy’s talks knows that he has some amusing “alternative lyrics” on familiar songs. But what most people might not know is that Carl Franklin is a fantastic guitar player with an impressive voice. Where can we get your CD, Mr Franklin? Great gig! [&lt;strong&gt;UPDATE:&lt;/strong&gt; Some guys from TypeMock recorded the jam session and they’ve &lt;a href="http://blog.typemock.com/2009/07/videos-from-typemocks-unit-testing-open.html"&gt;published some clips here&lt;/a&gt;]&lt;/p&gt;  &lt;p&gt;After a couple of beers we headed towards the city and some place to eat. Scott Hanselman’s got this ‘thing’ where he just got to dig up an Ethiopian restaurant in every city he visits. And so we joined Hanselman, Phil Haack, and some other guys for an exotic dinner at &lt;em&gt;Mama Africa&lt;/em&gt;. Scott and Phil are just some incredibly nice guys and it was a memorable dinner – both the food and the company :)&lt;/p&gt;  &lt;p&gt;The Big Party started with a decent dinner on Thursday evening. I mean; you really don’t expect much when you sit down with a cardboard plate filled with some sort of &lt;a href="http://www.flickr.com/photos/grothaug/sets/72157619854994646/"&gt;&lt;img style="border-right-width: 0px; margin: 10px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Photo by Rune Grothaug" border="0" alt="Photo by Rune Grothaug" align="right" src="http://lh6.ggpht.com/_hlZzgPJTEUM/SkB8rzPSOQI/AAAAAAAAAjE/7xIwKWd9EAw/image%5B37%5D.png?imgmax=800" width="379" height="279" /&gt;&lt;/a&gt;stew’ish dinner at a conference like this, but it really wasn’t that bad this time. And as the dinner had sunk in and the beer was starting to function, &lt;a href="http://www.datarockmusic.com/"&gt;Datarock&lt;/a&gt; entered the stage. I must admit that electronica is not my favorite genre, but the performance that Datarock delivered was impressive. And how could you possibly go wrong with lyrics like this at NDC?&lt;/p&gt;  &lt;p&gt;&lt;em&gt;I ran into her on computer camp      &lt;br /&gt;(Was that in 84?)       &lt;br /&gt;Not sure       &lt;br /&gt;I had my commodore 64       &lt;br /&gt;Had to score&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;-- Datarock, Computer Camp Love&lt;/p&gt;  &lt;p&gt;And after the Datarock concert we headed up to the geek bar. &lt;a href="http://www.loveshack.no/"&gt;Loveshack&lt;/a&gt; had tuned in some never-dying 80ies classics that really got the geeks rocking. Great show!&lt;/p&gt;  &lt;p&gt;Once again I was impressed that some of the speakers choose to hang out with us mere mortals. Phil Haack, Peter Provost, Scott Bellware, and Udi Dahan were all hanging around and took the time to socialize. Much appreciated!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/grothaug/sets/72157619854994646/"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Photo by Rune Grothaug" border="0" alt="Photo by Rune Grothaug" src="http://lh4.ggpht.com/_hlZzgPJTEUM/SkB8sittFRI/AAAAAAAAAjI/LYsLxF4jtvg/image%5B38%5D.png?imgmax=800" width="496" height="317" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;A picture speaks more than the 1332 words on this page; NDC 2009 was just a big smile! Too bad it’s a whole year ‘till next time…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-4400924859988550553?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/G-3PBH3n5Dg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/4400924859988550553/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=4400924859988550553&amp;isPopup=true" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/4400924859988550553?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/4400924859988550553?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/G-3PBH3n5Dg/ndc-2009-highlights.html" title="NDC 2009 Highlights" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/06/ndc-2009-highlights.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMESXo9fyp7ImA9WxJQFEs.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-2763328494137350720</id><published>2009-05-28T00:30:00.001+02:00</published><updated>2009-05-28T00:30:08.467+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-28T00:30:08.467+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><title>My NDC 2009 Agenda</title><content type="html">&lt;p&gt;The &lt;a href="http://www.ndc2009.no/"&gt;Norwegian Developer Conference 2009&lt;/a&gt; will take place in Oslo from June 17th to 19th. I’ve been lucky enough to get my hands on a full 3-day ticket and I’m really looking forward to this event. I attended both TechEd Barcelona in 2007 and PDC last year in LA, but I can’t help thinking that NDC 2009 has got an even more impressive speaker lineup than both of those – at least if you’re in to agile practices and software craftsmanship. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.ndc2009.no/index.aspx?cat=1069&amp;amp;id=43583"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" align="right" src="http://lh4.ggpht.com/_hlZzgPJTEUM/Sh2-7edNE5I/AAAAAAAAAi0/8VCVRQo0y8w/image%5B9%5D.png?imgmax=800" width="154" height="216" /&gt;&lt;/a&gt;If you’re thinking pure technology NDC might not be &lt;em&gt;that&lt;/em&gt; impressive, but I personally believe that&amp;#160; the quality of a conference is a lot more about the quality of the speakers and how they present their thoughts and ideas, and less about the technological content. I’d rather spend an hour reading some good articles and try out some new technology hands on, than spending an hour on a bad chair in a room that always seem to lack oxygen listening to a mediocre speaker reading out loud every word on his/her powerpoint slides. &lt;/p&gt;  &lt;p&gt;Going to conferences is about getting inspired. It’s about getting that tickling feeling of neurons going amok and new ideas swirl around in your head. It’s about triggering activity in your &lt;a href="http://www.memory-key.com/news/2004/news_2004Apr.htm#insight"&gt;anterior superior temporal gyrus&lt;/a&gt;. And it’s all about the speakers. Skilled speakers with a lot of experience and confidence on stage giving a talk on a topic dear and near to their heart can really make a difference. And with a speaker lineup with names like Feathers, Rahien, Hanselman, Bolognese, Miller, Haack, Dahan, Osherove, Block, Provost, Bustamente, C. Martin, Lhotka… It’s just no way that this is going to be a mediocre event. It’s destined for success!&lt;/p&gt;  &lt;p&gt;The worst part of this conference will actually be to pick which sessions to attend. It’s just impossible to not miss a great session, but hopefully they will all be videotaped and available online shortly after the conference. But the sessions are always best live, and one got to choose something. As it looks right now I believe this will be my agenda;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.ndc2009.no/"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_hlZzgPJTEUM/Sh2-73U_tbI/AAAAAAAAAi4/BRp-H3MMPW0/image%5B10%5D.png?imgmax=800" width="645" height="108" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="637"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="137"&gt;         &lt;h5&gt;DAY 1&lt;/h5&gt;       &lt;/td&gt;        &lt;td valign="top" width="153"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="345"&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="137"&gt;Ayende Rahien&lt;/td&gt;        &lt;td valign="top" width="153"&gt;Building Multi Tenant Apps&lt;/td&gt;        &lt;td valign="top" width="345"&gt;Haven’t had a chance to see Rahien live yet, but I’ve read and used some of his works&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="137"&gt;         &lt;p&gt;Michael Feathers&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="153"&gt;         &lt;p&gt;Working Effectively with the Legacy Code: Taming the Wild Code Base&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="345"&gt;I’ve seen some videos of Feathers up on &lt;a href="http://www.infoq.com"&gt;InfoQ&lt;/a&gt; and I highly recommend his sessions&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="137"&gt;         &lt;p&gt;Juval Löwy&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="153"&gt;         &lt;p&gt;Productive Windows Communication Foundation&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="345"&gt;Don’t know much about Löwy to be honest, but getting productive with WCF is never bad.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="137"&gt;         &lt;p&gt;Rockford Lhotka&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="153"&gt;         &lt;p&gt;Implementing Permission-based Authorization in a Role-based World&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="345"&gt;Got to have &lt;em&gt;some&lt;/em&gt; technical sessions to, and though I’ve never used Rocky’s &lt;a href="http://www.lhotka.net/cslanet/"&gt;CSLA&lt;/a&gt; framework, I’ve listen to a couple of the &lt;a href="http://www.dotnetrocks.com/"&gt;DotNetRocks&lt;/a&gt; episodes he has attended. Besides; the content suits the project I’m currently working on perfectly :)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="137"&gt;         &lt;p&gt;Udi Dahan&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="153"&gt;         &lt;p&gt;Intentions and Interfaces - Making Patterns Complete&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="345"&gt;Yet another one of those gurus you just read and hear a lot about. &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="137"&gt;         &lt;p&gt;Michael Feathers&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="153"&gt;         &lt;p&gt;Design Sense Deep Lessons in Software Design&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="345"&gt;Feathers again; he’s just that good.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="636"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="142"&gt;         &lt;h5&gt;DAY 2&lt;/h5&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="350"&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="142"&gt;         &lt;p&gt;Jeremy D. Miller&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;         &lt;p&gt;Convention over Configuration applied to .NET&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="350"&gt;Been following his blog for some time and I like his involvement with the Alt.Net community. Great interview with him on &lt;a href="http://www.altnetpodcast.com/episodes/18-talking-with-jeremy-miller-about-alt-net"&gt;the Alt.Net podcast&lt;/a&gt;. And besides; CoC is facinating.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="142"&gt;         &lt;p&gt;Roy Osherove&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;         &lt;p&gt;Unit Testing Best Practises&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="350"&gt;Went to Osherove’s sessions at TechEd in 2007 and it was well worth it. Hope he brings his guitar :)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="142"&gt;         &lt;p&gt;Ted Neward&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;         &lt;p&gt;Extend the Customization Possibilities of your .NET App with Script&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="350"&gt;Ted is a great speaker and the scripting possibilities is something I’d really like to look more into.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="142"&gt;         &lt;p&gt;Robert C. Martin&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;         &lt;p&gt;Clean Code: Functions&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="350"&gt;One of the most energetic speakers out there and &lt;a href="http://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1243461137&amp;amp;sr=8-1"&gt;Clean Code&lt;/a&gt; will be read in the upcoming weeks.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="142"&gt;         &lt;p&gt;Rafal Lukawiecki&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;         &lt;p&gt;Architectual use of Business Intelligence in Application Design&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="350"&gt;BI has always been one of those fields that were interesting, but never had the time to really dig into. And from what I’ve heard Rafal was one of the top rated speakers at TechEd 2007 (or was it 2008?).&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="142"&gt;         &lt;p&gt;Jimmy Nilsson&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;         &lt;p&gt;Entity Framework + Domain-Driven Design = true?&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="350"&gt;I’ve read Nilsson’s &lt;a href="http://www.amazon.co.uk/Applying-Domain-Driven-Design-Patterns-Using/dp/0321268202/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1243461687&amp;amp;sr=8-1"&gt;book on DDD&lt;/a&gt; and seen his &lt;a href="http://www.oredev.org/topmenu/video/ddd.4.5a2d30d411ee6ffd28880002148.html"&gt;session at Øredev&lt;/a&gt; last year. I’m currently working on a project were we try to follow the guidelines of DDD, and so it will be interesting to see his take on EF + DDD.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="142"&gt;         &lt;p&gt;Richard Campbell&lt;/p&gt;          &lt;p&gt;Carl Franklin&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;         &lt;p&gt;.NET Rocks! Live&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="350"&gt;I’ve followed the .NET Rocks podcast for quite some time and the live recordings are never dull. Will be interesting to see who they gather at their panel this time.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="634"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="145"&gt;         &lt;h5&gt;DAY 3&lt;/h5&gt;       &lt;/td&gt;        &lt;td valign="top" width="142"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="345"&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="145"&gt;Scott Bellware&lt;/td&gt;        &lt;td valign="top" width="142"&gt;Full Day Tutorial: Good Test, Better Code&lt;/td&gt;        &lt;td valign="top" width="345"&gt;I’m a strong believer in TDD and Bellware is certainly one of the gurus in this field.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;As you might have noticed from my list of speakers I try to spread my sessions to cover as many different as possible. That way I know which one I can spend time with when the videos come online. &lt;/p&gt;  &lt;p&gt;And a little tip if you’re going to NDC (or any other conference); do not hesitate to leave a session that you find boring or uninteresting. It’s your time and you’d better spend it right!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-2763328494137350720?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/IdnI7PkEvuQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/2763328494137350720/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=2763328494137350720&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/2763328494137350720?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/2763328494137350720?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/IdnI7PkEvuQ/my-ndc-2009-agenda.html" title="My NDC 2009 Agenda" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/05/my-ndc-2009-agenda.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEEQXoyeCp7ImA9WxJQE0w.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-1757067939989035378</id><published>2009-05-26T08:00:00.000+02:00</published><updated>2009-05-26T08:00:00.490+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-26T08:00:00.490+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wpf" /><category scheme="http://www.blogger.com/atom/ns#" term="prism" /><title>PRISM: Your guide to a well-structured UI layer in WPF/SilverLight – Part 2</title><content type="html">&lt;p&gt;In &lt;a href="http://www.kjetilk.com/2009/04/prism-your-guide-to-well-structured-ui.html"&gt;Part 1&lt;/a&gt; I talked a bit about testability as one of the major drivers for why you would choose to use &lt;a href="http://compositewpf.codeplex.com"&gt;Prism&lt;/a&gt; as your guidance for a composite application. In this post I’ll try to give you some hints on how Prism address common challenges like separation of concerns, single responsibility and supporting multiple platforms.&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://lh6.ggpht.com/_hlZzgPJTEUM/ShsOHo84QiI/AAAAAAAAAic/IKv1U30ESmw/s1600-h/image%5B21%5D.png"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Lego Bricks" border="0" alt="Lego Bricks" align="left" src="http://lh6.ggpht.com/_hlZzgPJTEUM/ShsOIOuiFUI/AAAAAAAAAig/pxHycQTjAgw/image_thumb%5B13%5D.png?imgmax=800" width="209" height="240" /&gt;&lt;/a&gt; Modularity&lt;/h4&gt;  &lt;p&gt;Modularity is what makes composite applications composite. Modularity is one of those design principles that has been around ‘forever’, and it’s just as relevant today as ever. “Modules”, “Packages”, and “Components” are all naming of the same concept; grouping related functionality together. That means that &lt;em&gt;cohesion &lt;/em&gt;inside a module should be high; the objects within a module should work within the same context and address a common problem. If the grouping of functionality is done right then the &lt;em&gt;coupling &lt;/em&gt;between modules should be low, because it shouldn’t be any need to reference objects that are unrelated. &lt;/p&gt;  &lt;p&gt;The concept of modules in Prism will guide you towards the goal of high cohesion / low coupling. Modules in Prism don’t tell you how far up or down the architectural layers you should or could go, but it typically will include at least the presentation layer. Whether you choose to implement a complete, vertical slice of your application all the way down to the database, or you choose to stop right below the presentation layer is up to you. What is important to keep in mind is that a module should preferably reference neither any other modules nor the host application itself. The module must be kept as separate and isolated as possible. And because these modules are independent of its surroundings, they should be pretty easy to load into the application and by that make it possible to compose an application from these building blocks.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://lh3.ggpht.com/_hlZzgPJTEUM/ShsOI26UZ7I/AAAAAAAAAik/59n7XbrGDPA/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Wrench" border="0" alt="Wrench" align="left" src="http://lh5.ggpht.com/_hlZzgPJTEUM/ShsOJszjqdI/AAAAAAAAAio/J71WZh6a0_Y/image_thumb%5B3%5D.png?imgmax=800" width="244" height="165" /&gt;&lt;/a&gt; Maintainability&lt;/h4&gt;  &lt;p&gt;The biggest maintenance problems I’ve found myself in have usually been due to either large, difficult to follow code-behind files. Large classes and methods with a lot of functionality are in general hard to maintain, but my code-behind files from the pre-TDD-era had a distinct tendency of getting bloated. And not only were they big; they also had a lot of different responsibilities; from UI-logic and validation to business rules and data flow. And even data access in those early days (after all; that was what those on-stage demos and MSDN documentation thought us, right?). &lt;/p&gt;  &lt;p&gt;Prism tackles the code-behind problem by showing you how to use UI design patterns to separate out functionality into presenter and presentation model classes. These classes do not have any graphical components related to them and so they lend themselves really nice to unit testing. The &lt;a href="http://www.microsoft.com/practices"&gt;Patterns &amp;amp; Practices team&lt;/a&gt; chose to implement what Martin Fowler calls the &lt;a href="http://martinfowler.com/eaaDev/PresentationModel.html"&gt;Presentation Model&lt;/a&gt; pattern. The more WPF-specific implementation of this pattern is often referred to as a &lt;a href="http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx"&gt;Model-View-ViewModel&lt;/a&gt; pattern coined by John Gossman, but because there’s no “official” documentation of the MVVM pattern (just a whole lot of blog posts), P&amp;amp;P chose to refer to the well-documented Presentation Model. But if you want to google your way to more intel on the UI pattern used in Prism, enter MVVM or Model-View-ViewModel as your search criteria. That way you’ll have a better shot at getting WPF or SilverLight related search results. A good start would be the &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;MSDN article by Gossman&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/dancre/archive/2006/10/11/datamodel-view-viewmodel-pattern-series.aspx"&gt;Dan Crevier’s early series on DM-V-VM&lt;/a&gt;, &lt;a href="http://joshsmithonwpf.wordpress.com/category/mvvm/"&gt;various blog posts on the MVVM-subject by Josh Smith&lt;/a&gt;, and &lt;a href="http://karlshifflett.wordpress.com/mvvm/"&gt;Karl Shifflet’s M-V-VM articles&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://lh5.ggpht.com/_hlZzgPJTEUM/ShsOKHHZp_I/AAAAAAAAAis/8i-fg8zxudw/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Winnie-the-Pooh" border="0" alt="Winnie-the-Pooh" align="left" src="http://lh5.ggpht.com/_hlZzgPJTEUM/ShsOK4bKvZI/AAAAAAAAAiw/N0ER3f2xYQA/image_thumb%5B1%5D.png?imgmax=800" width="184" height="191" /&gt;&lt;/a&gt;Multi-Targeting&lt;/h4&gt;  &lt;p&gt;Should you choose WPF or SilverLight? The short and evasive answer is off course; it depends. I’m not going to elaborate on when you should choose either, but if your answer is &lt;a href="http://en.wikipedia.org/wiki/Winnie-the-Pooh"&gt;both&lt;/a&gt;, then the guidance in Prism can show you how you can do this in a very smooth way. In fact; the difference between the WPF and the SilverLight version in Prism’s reference application, is 95% xaml. That is; everything but the Views are the exact same code. And by &lt;i&gt;exact&lt;/i&gt; I literally mean the same code; instead of having the Presenter/PresentationModel-code duplicated, they actually link the SilverLight files to the corresponding WPF-files. The SilverLight projects therefore contain mostly Views, and the shared code lies in the WPF projects. &lt;/p&gt;  &lt;p&gt;The last 5% difference implies that you can’t get all the way by changing the xaml alone; there is still some tweaking to get the WPF and SilverLight working nicely together. Since there are some subtle differences between WPF and SilverLight when it comes to functionality (SilverLight is not a pure subset, since it contains some functionality that not (yet) exists in WPF), the P&amp;amp;P team has used &lt;a href="http://msdn.microsoft.com/en-us/library/ed8yd1ha(vs.71).aspx"&gt;preprocessor directives&lt;/a&gt; on those places where they’ve had to customize specifically for the platforms. &lt;/p&gt;  &lt;h4&gt;Wrapping It Up&lt;/h4&gt;  &lt;p&gt;Building applications that are highly testable and maintainable is key for long-lived software. Splitting functionality into well-defined modules that can be developed in parallel by separate teams is key for scaling out the development process. But keep in mind that not all application will benefit from the Composite Application Guidance. Prism is not a silver bullet and it &lt;i&gt;will&lt;/i&gt; bring more complexity into your development process. But if your needs justifies the added complexity and you know that your must ‘embrace change’ for years to come, Prism can really lay the foundation for a successful development story. And remember that Prism is guidelines, not framework. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-1757067939989035378?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/5ziwZgRdcEM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/1757067939989035378/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=1757067939989035378&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/1757067939989035378?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/1757067939989035378?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/5ziwZgRdcEM/prism-your-guide-to-well-structured-ui.html" title="PRISM: Your guide to a well-structured UI layer in WPF/SilverLight – Part 2" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/05/prism-your-guide-to-well-structured-ui.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcNRHk4eip7ImA9WxJTEks.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-73388696638937659</id><published>2009-04-20T22:41:00.001+02:00</published><updated>2009-04-20T22:41:35.732+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-20T22:41:35.732+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wpf" /><category scheme="http://www.blogger.com/atom/ns#" term="prism" /><title>PRISM: Your guide to a well-structured UI layer in WPF/SilverLight</title><content type="html">&lt;p&gt;I’ve had the opportunity to work with &lt;a href="http://www.codeplex.com/compositewpf"&gt;Composite Application Guidance for WPF and SilverLight&lt;/a&gt; (codenamed “PRISM”) for a couple of months now, and I’m really impressed with what the Patterns &amp;amp; Practices team has shipped this time. The forefather of Prism is in many senses the CAB framework (Composite UI Application Block) and even though I never worked with the CAB Framework myself, I’ve heard that it is a quite large and not that easy to grasp. Prism on the other hand, is quite light weight and the documentation is very concise and well written. &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://lh5.ggpht.com/_hlZzgPJTEUM/Sezd95lJj_I/AAAAAAAAAiM/mhtyGhIn9YA/image5.png?imgmax=800" width="244" height="108" /&gt;The feedback from CAB has also been that it’s too intrusive; it’s an all or nothing application block and it’s hard to take advantage of the UI composition patterns in existing applications. CAB is from what I have found, meant to be built upon – not with (remember, I haven’t worked with CAB myself, so if you’d like to correct me, please feel free to do so in the comments below). With Prism P&amp;amp;P has taken quite another approach; you’re free to use (or not use) any part of the Composite Application Library in Prism. And you can switch out whatever part that doesn’t suite your needs. For instance, a core principle in Prism is to use an IoC container to make the application highly testable and loosely coupled. And since P&amp;amp;P has developed an IoC container themselves, namely the Microsoft Unity, the examples and the reference application in Prism uses Unity. But if you’d rather use Windsor, StructureMap, Ninject, Autofac, or any other IoC you’re definitely free to do so. &lt;/p&gt;  &lt;p&gt;The big difference here’s that where CAB is an application &lt;b&gt;block&lt;/b&gt;, Prism is an application &lt;b&gt;guidance&lt;/b&gt;. And it guides you towards building applications that are testable, maintainable, multi-targeted and modularized. I’ll dive into these concepts in more details, so let’s start with;&lt;/p&gt;  &lt;h3&gt;Testability&lt;/h3&gt;  &lt;p&gt;Everybody tests their code and there are two ways to do it; &lt;/p&gt;  &lt;p&gt;a) Manually; set some breakpoints, fire up the app, input some data and push some buttons, let the debugger hit the breakpoints, inspect some variables, and check that everything works as expected (or more often; try to find out why it doesn’t work as expected)&lt;/p&gt;  &lt;p&gt;b) Automated; use a testing framework like NUnit, xUnit, or MSTest, write some tests, and then let the machines do the tedious work of verifying that you didn’t break anything you didn’t mean to&lt;/p&gt;  &lt;p&gt;If you enjoy your time with the debugger, I won’t try to convince you that automation is good. But I consider myself a pretty lazy programmer and whenever I see an opportunity to automate boring, repetitive tasks, I always try to do so. I prefer to code, not debug, and therefore I automate my testing. Therefore I write unit, integration and UI tests that can be run by an unattended build machine whenever I check in some code changes. &lt;b&gt;I’m a coder, not a debugger&lt;/b&gt;. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_hlZzgPJTEUM/Sezd-8FwTaI/AAAAAAAAAiQ/4h1QQfVfwTI/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="right" src="http://lh4.ggpht.com/_hlZzgPJTEUM/Sezd_klhqeI/AAAAAAAAAiY/XLUjorjC0HY/image_thumb%5B1%5D.png?imgmax=800" width="174" height="244" /&gt;&lt;/a&gt;But writing unit tests can be hard if you haven’t architected you’re classes and methods in a way that opens up for testing. If you instantiate objects inside your classes or in other ways are tightly coupled to other classes, mocking out those classes that are not in the scope of the current unit test will be hard. It’s not impossible, it’s just hard. One of the areas that are notoriously hard to unit test is the “code behind” of graphical components. Because when you instantiate a GUI component, it makes you dependent on a GUI thread when you run the test. On a build machine that’s going to run your tests without any interactive user logged in, this is just not the case; there’s no GUI thread available. And besides; it is bloody annoying and time consuming to have those forms and windows pop up whenever you run your test suite.&lt;/p&gt;  &lt;p&gt;Opening your class for dependency injection and using an IoC container to manage the wiring of dependent objects is a well-proven and easy way to solve this problem. Prism explains and shows you how to write your application using an IoC container for the hot-wiring. And as I’ve already mentioned; if you prefer any other IoC Container, it’s totally up to you. But if you choose to not use Unity, you’ll have to be prepared to write some wiring code when initializing your application. Prism comes with the wiring code in form of a class called &lt;i&gt;UnityBootstrapper. &lt;/i&gt;And there’s no surprise to the naming here; this class takes care of booting up your application with the Unity IoC container. So if you want to use any other container, you’ll need to rewrite the &lt;i&gt;UnityBootstrapper&lt;/i&gt; to suite your choice. Or if you’re lucky; use the source code from someone who’s already done it (like the Castle Windsor adapter and bootstrapper that you can find in the &lt;a href="http://compositewpfcontrib.codeplex.com/"&gt;Composite WPF Contrib&lt;/a&gt; project over at CodePlex).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;All right! I think that’s enough for one post. I promised to write about maintainability, multi-targeting and modularity as well, so these will be the subjects for my next post. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-73388696638937659?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/P6nW2R3B_dg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/73388696638937659/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=73388696638937659&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/73388696638937659?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/73388696638937659?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/P6nW2R3B_dg/prism-your-guide-to-well-structured-ui.html" title="PRISM: Your guide to a well-structured UI layer in WPF/SilverLight" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/04/prism-your-guide-to-well-structured-ui.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EBQn4-fyp7ImA9WxVUFEQ.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-1423989952601217815</id><published>2009-03-19T22:35:00.001+01:00</published><updated>2009-03-19T22:54:13.057+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-19T22:54:13.057+01:00</app:edited><title>MSDN Live: Slides &amp; Demo Code from “WPF Done Right!”</title><content type="html">&lt;p&gt;Me and my colleague &lt;a href="http://blog.fossmo.net"&gt;Pål Fossmo&lt;/a&gt; was invited to give a talk on the &lt;a href="http://www.codeplex.com/CompositeWPF"&gt;Composite Application Guidance&lt;/a&gt; (codenamed &lt;i&gt;Prism) &lt;/i&gt;on the MSDN Live March 2009 tour. It was great fun, but man we spent many hours preparing for this event! Given the fact that there were 2 of us given the talk, one could assume that this meant just half the work. But, no. So many hours of discussing what to include, how to do the talk, who does what, synchronizing the talk, rehearsal…&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_hlZzgPJTEUM/ScK8LdADglI/AAAAAAAAAiE/cQHOZ9q1obk/s1600-h/image%5B34%5D.png"&gt;&lt;img style="border-right-width: 0px; margin: 10px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Pål talking about IoC Containers" border="0" alt="Pål talking about IoC Containers" src="http://lh4.ggpht.com/_hlZzgPJTEUM/ScK8NasUxSI/AAAAAAAAAiI/i1IaUN7gVt8/image_thumb%5B30%5D.png?imgmax=800" width="420" height="295" /&gt;&lt;/a&gt;And we thought we had it all figured out as we started out in Stavanger on March 5th. But the feedback from the session suggested that maybe we ought to change the talk a bit. The score wasn’t as good as we’d hoped and we knew we could do better. So we spent the weekend adjusting the talk for Bergen on March 10th. The tip from MSDN General &lt;a href="http://blogs.msdn.com/grothaug/"&gt;Rune G&lt;/a&gt; was clear; more code equals higher score. So we added some quality time in Visual Studio to the talk and the score went up. I must admit that I was perhaps the one that resisted to take “live coding” into the talk in the first place, but seeing the score from Stavanger and Bergen made it pretty clear that this was a bad call. The reason for my resistance was perhaps the fear of ‘something’ going wrong during live coding; staying in PowerPoint is safe, jumping around in Visual Studio is a lot more risky. So many things can go wrong and to stand in front of the crowd with an app that crash and burn is just not much fun. Believe me; I’ve tried it. The demo-God was nice to us though, and I think we got away with some nice demos on how to get started with Prism.&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://tinyurl.com/wpfdoneright"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Download slides &amp;amp; code" border="0" alt="Download slides &amp;amp; code" align="left" src="http://lh6.ggpht.com/_hlZzgPJTEUM/ScK6uNFXbUI/AAAAAAAAAh4/RPIOV7rlEbE/image%5B16%5D.png?imgmax=800" width="227" height="176" /&gt;&lt;/a&gt;The Slides&lt;/h3&gt;  &lt;p&gt;We spent about half of the talk in PowerPoint and rest was demo. The slides focus on the &lt;i&gt;what&lt;/i&gt; and &lt;i&gt;why&lt;/i&gt; of Prism, while the &lt;i&gt;how&lt;/i&gt; was in Visual Studio. Since one of the key concepts of Prism is the use of an IoC/D I-container, we decided to spend about 8-10 minutes explaining the concepts of &lt;i&gt;Dependency Injection &lt;/i&gt;and &lt;i&gt;Inversion of Control&lt;/i&gt; using some example code in PowerPoint. Rune Grothaug will publish a screen-recording of the session we did in Oslo, and I guess will be available in a couple of days (I’ll update this article with a link to the recording when it’s available). If you want to take a look on the slides, you can &lt;a href="http://tinyurl.com/wpfdoneright"&gt;download them here&lt;/a&gt; (for you non-Norwegian speaking out there; sorry, the slides are (mostly) in Norwegian, but if you’d like a copy in English just let me know and I’ll translate and upload it).&amp;#160;&amp;#160; &lt;/p&gt;  &lt;h3&gt;&lt;a href="http://tinyurl.com/wpfdoneright"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Download slides &amp;amp; code" border="0" alt="Download slides &amp;amp; code" align="left" src="http://lh5.ggpht.com/_hlZzgPJTEUM/ScK6up0cygI/AAAAAAAAAh8/2Lv7kaX4lvw/image%5B24%5D.png?imgmax=800" width="158" height="275" /&gt;&lt;/a&gt;The Code&lt;/h3&gt;  &lt;p&gt;The goal of the demo was to show off some of the key concepts in Prism; modules, regions, views and communication. As we started to prepare for this talk, we quickly found the need of a very lightweight and small app that we could demo. The reference application that comes with Prism is really good, and I highly recommend everyone to take a walk around the code from the Patterns &amp;amp; Practices team. It’s nicely done and I think most of us can learn a lot just be reading this code. But alas the reference app is nice and well done; we still wanted something smaller and more fit to our purpose, so we decided to roll our own little composite application. And since Pål is a big fan of &lt;a href="http://www.kjetilk.com/www.twitter.com"&gt;Twitter&lt;/a&gt;, he built a nice little Twitter client using the concepts from Prism. The demo app, called ‘Kvittre’, consists of a shell with 4 regions and in the main app we had 3 modules; one for the login view, one for posting tweets, and one for listing tweets from those you follow. &lt;/p&gt;  &lt;p&gt;For the live demo we wanted to show how to build a module, and since &lt;a href="http://tinyurl.com"&gt;TinyUrl&lt;/a&gt; is a popular service to shorten down url’s in tweets we decided to build a module that could take an url, ask the TinyUrl service for a shortened version, and then insert the tiny url into the message. And to demo that you could build a module separate from the ‘main solution’, we coded the module in a separate solution. To test-run the module we added a ‘host application’ project that contained a &lt;i&gt;bootstrapper&lt;/i&gt; and a region to host the view from the module. When the module was tested and looked okay, we deployed it back to Kvittre. Kvittre was set up with a &lt;i&gt;DirectoryModuleCatalog&lt;/i&gt; that would load any module in a given catalog. Since the 4th region in the Kvittre shell was set up to host the TinyUrl module, the module was loaded and displayed in Kvittre. Then we used an &lt;i&gt;EventAggregator&lt;/i&gt; for communicating between modules and wrapped it up by demoing some unit testing of the &lt;i&gt;Login&lt;/i&gt; method in &lt;a href="http://tinyurl.com/wpfdoneright"&gt;&lt;/a&gt;&lt;a href="http://tinyurl.com/wpfdoneright"&gt;&lt;img style="border-right-width: 0px; margin: 10px 0px 0px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Download slides &amp;amp; code" border="0" alt="Download slides &amp;amp; code" align="right" src="http://lh3.ggpht.com/_hlZzgPJTEUM/ScK6vOg4mVI/AAAAAAAAAiA/FECanmP044Y/clip_image002%5B4%5D%5B3%5D.gif?imgmax=800" width="164" height="79" /&gt;&lt;/a&gt;&lt;a href="http://tinyurl.com/wpfdoneright"&gt;&lt;/a&gt;the &lt;i&gt;Presenter &lt;/i&gt;class of the &lt;i&gt;LoginView&lt;/i&gt;. If you want to check out the code, it’s all wrapped up and ready for &lt;a href="http://tinyurl.com/wpfdoneright"&gt;download right here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://tinyurl.com/wpfdoneright"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-1423989952601217815?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/_uqGxKHTELA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/1423989952601217815/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=1423989952601217815&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/1423989952601217815?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/1423989952601217815?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/_uqGxKHTELA/msdn-live-slides-demo-code-from-wpf.html" title="MSDN Live: Slides &amp;amp; Demo Code from “WPF Done Right!”" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/03/msdn-live-slides-demo-code-from-wpf.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIERH84eip7ImA9WxVWFEs.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-2379497426900103402</id><published>2009-02-24T08:21:00.001+01:00</published><updated>2009-02-24T08:28:25.132+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-24T08:28:25.132+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tdd" /><title>“Legacy Code is Code Without Tests”</title><content type="html">&lt;p&gt;I wish I’d come up with that phrase first, but it was Michal Feathers who stated this in his “&lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052" target="_blank"&gt;Working effectively with legacy code&lt;/a&gt;”. It’s a great statement, and it pretty much sums up what testing is all about; if you’re not covered by tests, it is hard to refactor and change the code and at the same time know that you didn’t break anything. And if you have code that is resistant to change or that makes you nervous every time you touch it, then you have code that won’t be changed. You have legacy code. And you can try to wrap it, hide it, and forget it, but someday it will blow up. And someday you’ll have to go in there and make it work. But you won’t have any safety net. You’ll have to change something you do not know the reach of, and you’ll have to do it blindfolded and pray that your changes aren’t going to break something somewhere else. But I promise you; it will. &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://lh3.ggpht.com/_hlZzgPJTEUM/SaOf9UCimhI/AAAAAAAAAhY/EG-e1A5a1O4/image%5B5%5D.png?imgmax=800" width="244" height="164" /&gt; And man I can tell you; it is good to be a consultant with skills in a technology where the software industry hasn’t had time to produce that much legacy code yet! That alone should be a good enough reason for you to invest some of your time into learning new skills. Skills that make you more valuable in the projects that produce new code, instead of maintaining legacy code that someone else hacked together years ago. It’s those green field projects that are fun! &lt;/p&gt;  &lt;p&gt;And because there’s not that much WPF-based apps out there yet, there can still be time to save some poor souls from aiming at that same old pit of failure. The pit of strongly coupled, untestable, monolithic monsters. There’s hope and I believe in the goodness of coders. I believe that we &lt;i&gt;want&lt;/i&gt; to make solid code. I believe that we &lt;i&gt;want&lt;/i&gt; to produce code that is maintainable and changeable. And I believe that we, the residents of the software community, can make the leap into software craftsmanship. It’s just a matter of making those right choices. And I believe that loose couplings, testability and modularity are definitely the right choices in most cases. These are the key principles that will make you a better person (or at least a better developer).&lt;/p&gt;  &lt;p&gt;Loose couplings and testability are tightly coupled (touché!). If you’re doing test-driven development, or behavior-driven development, or any other development practice that use tests to drive the design, you will end up with code that is loosely coupled. And if you’re building an app with loose couplings between modules and classes, you’ll end up with code that lends itself to testing very well. And testable, loosely coupled systems will be easier to maintain and change than a tightly coupled system with no tests to verify your code.&lt;/p&gt;  &lt;p&gt;Modularity is another beast though. Modularity is about splitting the application in to pieces that multiple teams can work on in parallel - without getting in the way of each other. Modularity is about scalability and maintainability. Adding new functionality without ending up with a logarithmic&lt;img style="border-right-width: 0px; margin: 10px 0px 0px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="right" src="http://lh6.ggpht.com/_hlZzgPJTEUM/SaOf-GyytxI/AAAAAAAAAhc/feCKEa0TuN8/image%5B16%5D.png?imgmax=800" width="170" height="184" /&gt; time/functionality curve is an important factor in software development (maybe not for you and me, but for those white collars* that are deciding whether to fund or close down your project, predictability is extremely important). And modularity is about mastering complexity. How do you master too complex challenges? You break it down in to smaller, more manageable parts. And in software terms those parts are modules.&lt;/p&gt;  &lt;p&gt;So if you take these 3 ingredients – loose couplings, testability, and modularity – and you shake it together with WPF (shake, not stir), you’ll have a fantastic opportunity to do WPF right. You’ll end up with code, not legacy code.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/norge/msdn_technet_live/agenda.aspx"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" align="left" src="http://lh4.ggpht.com/_hlZzgPJTEUM/SaOf_X735uI/AAAAAAAAAho/j3Kc3KT3Hcs/image%5B21%5D.png?imgmax=800" width="106" height="67" /&gt;&lt;/a&gt;If you’re in Stavanger on the 5&lt;sup&gt;th&lt;/sup&gt; of March, Bergen on the 10&lt;sup&gt;th&lt;/sup&gt;, Trondheim on the 12&lt;sup&gt;th&lt;/sup&gt; or in Oslo on the 19&lt;sup&gt;th&lt;/sup&gt; of March, you can hear me and my colleague &lt;a href="http://blog.fossmo.net" target="_blank"&gt;Pål Fossmo&lt;/a&gt; give a talk on this topic at the &lt;a href="http://www.microsoft.com/norge/msdn_technet_live/agenda.aspx" target="_blank"&gt;MSDN Live&lt;/a&gt; event. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;* Which btw just managed to bankrupt Iceland and is about to break the back of some of the strongest economies in the world… how the he** did they do that?!&lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-2379497426900103402?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/ASdFAK20xSA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/2379497426900103402/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=2379497426900103402&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/2379497426900103402?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/2379497426900103402?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/ASdFAK20xSA/legacy-code-is-code-without-tests.html" title="“Legacy Code is Code Without Tests”" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/02/legacy-code-is-code-without-tests.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkAFQ3c4fip7ImA9WxVREE8.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-8718347423566658857</id><published>2009-01-15T14:05:00.000+01:00</published><updated>2009-01-15T14:05:12.936+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-15T14:05:12.936+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><title>“A desk is a dangerous place from which to view the world”</title><content type="html">&lt;p&gt;A while ago a colleague of mine posted a &lt;a target="_blank" href="http://www.timeexpander.com/blog/index.php?itemid=256"&gt;blog about his desk&lt;/a&gt; at work. He used the words of &lt;em&gt;Gunnery Sgt Hartman&lt;/em&gt;, and so I will be no less of a man;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_hlZzgPJTEUM/SWvDOVY1LXI/AAAAAAAAAhE/VT4qHG-WcsU/s1600-h/DSC_0180-1%5B15%5D.jpg"&gt;&lt;img style="border-width: 0px; margin: 0px 10px 0px 0px; display: inline;" title="DSC_0180-1" alt="DSC_0180-1" src="http://lh4.ggpht.com/_hlZzgPJTEUM/SWvDO6JlbxI/AAAAAAAAAhI/mlvNkl4a6GE/DSC_0180-1_thumb%5B13%5D.jpg?imgmax=800" align="left" border="0" height="244" width="350" /&gt;&lt;/a&gt;“The Desk is a system. That system is our enemy. But when you're inside, you look around, what do you see? Businessmen, teachers, lawyers, carpenters. The very minds of the people we are trying to save. But until we do, these people are still a part of that system and that makes them our enemy.”&lt;/p&gt;  &lt;p&gt;(&lt;em&gt;almost&lt;/em&gt; a quote from the great &lt;em&gt;Morpheus&lt;/em&gt;)&lt;/p&gt;  &lt;p&gt;This &lt;em&gt;desk fetish&lt;/em&gt; was picked up by &lt;a target="_blank" href="http://anders.hammervold.com/2008/12/you-are-my-one-and-only-desk.html"&gt;Anders Hammervold&lt;/a&gt;, which again challenged &lt;a target="_blank" href="http://www.joaroyen.com/2008/12/how-my-desk-at-work-looks-like.html"&gt;Joar Øyen&lt;/a&gt;, which again challenged me… And since Joar also challenged &lt;a target="_blank" href="http://blog.fossmo.net/"&gt;Pål Fossmo&lt;/a&gt; – who still haven’t published his desk – the pressure is now on &lt;em&gt;The Reverend…&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Oh, and before I forget; that quote in the title is by John Le Carré. A fabulous quote if I may say so.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_hlZzgPJTEUM/SWvDOVY1LXI/AAAAAAAAAhM/7vh-TfLoSdo/s1600-h/DSC_0180-1%5B12%5D.jpg"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-8718347423566658857?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/6UAxNo47twU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/8718347423566658857/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=8718347423566658857&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/8718347423566658857?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/8718347423566658857?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/6UAxNo47twU/desk-is-dangerous-place-from-which-to.html" title="“A desk is a dangerous place from which to view the world”" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/01/desk-is-dangerous-place-from-which-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMNSHY_fip7ImA9WxVSF0w.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-2657043693358749227</id><published>2009-01-11T23:45:00.001+01:00</published><updated>2009-01-11T23:54:59.846+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-11T23:54:59.846+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tips" /><category scheme="http://www.blogger.com/atom/ns#" term="ipod" /><title>Custom iTunes installation</title><content type="html">&lt;p&gt;I love my iPod and I use it almost every day. Mostly I'm listening to podcasts, but also music off course. But I hate iTunes. Or maybe that's a bit strong. I hate the iTunes &lt;em&gt;installer&lt;/em&gt;. I think it’s all too intrusive and it doesn't give me all the choices I feel that it should. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_hlZzgPJTEUM/SWp3IZ9WA2I/AAAAAAAAAg8/Qlyj2Pc3Ouw/s1600-h/ipod%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; display: inline; border-top: 0px; border-right: 0px" title="ipod" border="0" alt="ipod" align="right" src="http://lh3.ggpht.com/_hlZzgPJTEUM/SWp3Jc2blzI/AAAAAAAAAhA/CQk20gs_jEI/ipod_thumb%5B2%5D.png?imgmax=800" width="240" height="240" /&gt;&lt;/a&gt; If you go to the &lt;a target="_blank" href="http://www.apple.com/itunes/download/"&gt;download page on iTunes’ web site&lt;/a&gt; and download the iTunes 8 version suited for your operating system, you’ll get an &lt;em&gt;iTunesSetup.exe&lt;/em&gt; file. If you’ve tried to run this file, you might have noticed that you also end up with a bunch of apps and services that you didn’t asked for. This includes;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Bonjour&lt;/strong&gt; – Apple’s take on implementing the &lt;i&gt;Zeroconf&lt;/i&gt; for discovery of services on a local network. The only reason why I might need the Bonjour service, is if I want to share my iTunes library on my LAN. But for now, running iTunes on a single machine, there’s no reason to have this service running around wasting resources.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Apple Mobile Device Support &lt;/strong&gt;and &lt;strong&gt;Mobile Me &lt;/strong&gt;– Both of these are meant for synchronization between a computer and an iPhone/IPod Touch. I only have an iPod Nano, so why would I need a service to sync between my pc and something I don’t have?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Apple Software Update &lt;/strong&gt;– This service will check for new updates on regular intervals, just like Windows Update. Luckily it won’t install anything automatically, it will only notify you if there’s a new iTunes version and let you decide if you want to download and install. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;QuickTime &lt;/strong&gt;– I’m not even going to start elaborating why I dislike QuickTime so much. It would just make me angry. Luckily, &lt;a target="_blank" href="http://www.free-codecs.com/download/quicktime_alternative.htm"&gt;there are alternatives&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The last one in the package is off course &lt;strong&gt;iTunes&lt;/strong&gt; itself. &lt;/p&gt;  &lt;p&gt;As you might have guess by now, there are only one or two out of six that I actually want to have running on my pc. And it’s really not that hard to actually get it that way. It turns out that the &lt;em&gt;iTunesSetup.exe &lt;/em&gt;is just a self-extracting package that contains installers for all of the apps and services above. So if you’d like to have a custom install of iTunes without the nagging apps and services that comes out of this black box, you’ll need a packaging-app like &lt;a target="_blank" href="http://www.rarlab.com/"&gt;WinRAR&lt;/a&gt; or &lt;a target="_blank" href="http://www.7-zip.org/"&gt;7-Zip&lt;/a&gt;. Then you can just extract the &lt;em&gt;iTunesSetup.exe &lt;/em&gt;and delete the parts you don’t need/like. The only thing to be aware of is that iTunes requieres QuickTime, but if you’ve installed QuickTime Alternative before running the iTunes installer, you’ll be safe and sound. So to make a short-list of how to install iTunes &lt;em&gt;only &lt;/em&gt;and keep your system a bit less cluttered;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Download and install &lt;a target="_blank" href="http://www.free-codecs.com/download/quicktime_alternative.htm"&gt;QuickTime Alternative&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Download, but &lt;b&gt;don’t install&lt;/b&gt; &lt;a target="_blank" href="http://www.apple.com/itunes/download/"&gt;iTunes&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Extract ‘iTunesSetup.exe’ &lt;/li&gt;    &lt;li&gt;Delete the files you want need. For me that means everything except &lt;i&gt;iTunes.msi&lt;/i&gt; and &lt;i&gt;AppleSoftwareUpdate.msi&lt;/i&gt;. &lt;/li&gt;    &lt;li&gt;Open the command prompt, navigate to the folder where you extracted &lt;i&gt;iTunes.msi&lt;/i&gt;, and run the following command; &lt;strong&gt;msiexec /i iTunes.msi /passive&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;If you’d like to be reminded of new updates (which you definitely should), run the same command for the updater service; &lt;strong&gt;msiexec /i AppleSoftwareUpdate.msi /passive&lt;/strong&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;(If you want the regular GUI-based installation, you can just skip the “/passive” parameter (or just double-click the msi-file in Windows Explorer).)&lt;/p&gt;  &lt;p&gt;Now, I didn’t figure out all this by myself. Google helped me find &lt;a target="_blank" href="http://blogs.zdnet.com/Bott/?p=554"&gt;this article by Ed Bott&lt;/a&gt; and &lt;a target="_blank" href="http://forums.pcpitstop.com/index.php?showtopic=155105&amp;amp;st=0&amp;amp;p=1487399&amp;amp;#entry1487399"&gt;this thread&lt;/a&gt; over at the &lt;em&gt;PC Pitstop&lt;/em&gt; forum.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-2657043693358749227?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/06k3ckC-V-4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/2657043693358749227/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=2657043693358749227&amp;isPopup=true" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/2657043693358749227?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/2657043693358749227?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/06k3ckC-V-4/custom-itunes-installation.html" title="Custom iTunes installation" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://www.kjetilk.com/2009/01/custom-itunes-installation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08EQXc6fCp7ImA9WxVTFEQ.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-6291992359511618700</id><published>2008-12-28T22:30:00.000+01:00</published><updated>2008-12-28T22:30:00.914+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-28T22:30:00.914+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tdd" /><title>Effectively teaching test-first: Make it go green!</title><content type="html">When you’re producing quality code using Test Driven Development you’re likely to use either the &lt;span style="font-style: italic;"&gt;test first &lt;/span&gt;or &lt;span style="font-style: italic;"&gt;test last &lt;/span&gt;approach (or more likely; a mix of those). &lt;span style="font-style: italic;"&gt;Test first &lt;/span&gt;means that you write your test before you implement the method you’re testing (i.e. the functionality). If you’re following the &lt;span style="font-style: italic;"&gt;test last &lt;/span&gt;mantra, you would implement the functionality first and then add test(s) to verify the behavior of the method. Strictly speaking, the latter approach will IMO not be a test driven development. If you want your tests to drive the architecture of your application, you should definitely go for the &lt;span style="font-style: italic;"&gt;test first&lt;/span&gt;. It’s not that the &lt;span style="font-style: italic;"&gt;test last &lt;/span&gt;won’t give you a testable application, it’s just that writing the test first makes it far easier to get your test actually be an unit test and not an integration test. &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hlZzgPJTEUM/SU7G7XpgfCI/AAAAAAAAAgo/IDeLxG1FdLA/s1600-h/Matrix+-+Neo+through+Morpheus+glasses.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 269px; height: 160px;" src="http://2.bp.blogspot.com/_hlZzgPJTEUM/SU7G7XpgfCI/AAAAAAAAAgo/IDeLxG1FdLA/s320/Matrix+-+Neo+through+Morpheus+glasses.jpg" alt="" id="BLOGGER_PHOTO_ID_5282378136214862882" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"I'm trying to free your mind, Neo. But I can only show you the door. You'&lt;/span&gt;&lt;span style="font-style: italic;"&gt;re the one that has to walk through it."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I must confess; I felt that writing tests first was really hard in the beginning. Before you start mastering the art of unit testing, you cannot really write the tests first unless you get some good guidance doing it. I’ve been doing TDD for a while now and I feel quite confident about it, and so I try to teach my team members the same philosophy. And the method I found that really helped getting them on the right track was to just sit down and do some pair-programming with them. We start out the session with me behind the keyboard. According to XP-ists the time between switching the roles of the &lt;span style="font-style: italic;"&gt;driver &lt;/span&gt;(the one typing on the keyboard) and the &lt;span style="font-style: italic;"&gt;observer &lt;/span&gt;(the one reviewing the code) should be around 30 minutes or so. But what I really find effective when it comes to teaching &lt;span style="font-style: italic;"&gt;test first, &lt;/span&gt;is to do the switching after I’ve written the unit test. When writing the unit test itself, I do this while thinking out loud and discussing the code with my fellow dev. That way I practically show him/her how I think when I write the test and (s)he will have a good starting point for implementing the functionality. After I’ve finished writing the test, I just hand over the keyboard saying; “Make it go green!”&lt;br /&gt;&lt;br /&gt;Would this method work in all circumstances? Certainly not! If (s)he was totally new to testing and I were to give an intro to unit testing, I’d probably choose another way. I’d probably show how to do some integration or unit testing on existing code before introducing the &lt;span style="font-style: italic;"&gt;test first &lt;/span&gt;approach. Doing this exercise with someone who’s never seen a unit test before would probably be too much to grasp at once.  When I’m coding the unit test in the &lt;span style="font-style: italic;"&gt;Make-It-Go-Green&lt;/span&gt;-method I often have to use mocks to isolate the method under test and to introduce mocking to developers who have never seen unit test before will probably not be a good idea. In that case I’d rather let them do some integration tests before teaching them some real TDD. But maybe that’s just me…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-6291992359511618700?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/B2JYsoH0Gbg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/6291992359511618700/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=6291992359511618700&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/6291992359511618700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/6291992359511618700?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/B2JYsoH0Gbg/effectively-teaching-test-first-make-it.html" title="Effectively teaching test-first: Make it go green!" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_hlZzgPJTEUM/SU7G7XpgfCI/AAAAAAAAAgo/IDeLxG1FdLA/s72-c/Matrix+-+Neo+through+Morpheus+glasses.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kjetilk.com/2008/12/effectively-teaching-test-first-make-it.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4EQ34-fip7ImA9WxRaGEQ.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-6455794118926301824</id><published>2008-12-21T22:10:00.001+01:00</published><updated>2008-12-21T22:11:42.056+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-21T22:11:42.056+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tips" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title>MemberAccessException</title><content type="html">Exceptions are meant for those exceptional conditions that never should happened during your programs lifetime, but that you cannot guarantee won't happen. As you might expect from this statement, I'm not a big fan of sprinkling the code with unnecessary exception throws. I find it more useful to test those exceptional cases using unit and integration tests.&lt;br /&gt;&lt;br /&gt;Anyway; while studying the source code from the excellent CodeProject article "&lt;a href="http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx"&gt;NHibernate Best Practices with ASP.NET&lt;/a&gt;" by &lt;a href="http://devlicio.us/"&gt;Billy McCafferty&lt;/a&gt;, I came across this quite interesting use of &lt;a href="http://msdn.microsoft.com/en-us/library/system.memberaccessexception.aspx"&gt;MemberAccessException&lt;/a&gt;;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; IOrderDao OrderDao&lt;br /&gt;{&lt;br /&gt;get&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (orderDao == &lt;span class="kwrd"&gt;null&lt;/span&gt;) {&lt;br /&gt;&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; MemberAccessException(&lt;span class="str"&gt;"OrderDao has not yet been initialized"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; orderDao;&lt;br /&gt;}&lt;br /&gt;set { orderDao = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If it were me coding this, I’d probably just throw the far more general ApplicationException or something (if I'd throw it all, mind my words in the intro to this post). But I definitely see that the MemberAccessException would be a lot better fit for this exceptional case.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-6455794118926301824?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/ef4K9mnwChE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/6455794118926301824/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=6455794118926301824&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/6455794118926301824?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/6455794118926301824?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/ef4K9mnwChE/memberaccessexception.html" title="MemberAccessException" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kjetilk.com/2008/12/memberaccessexception.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MGQXg6cCp7ImA9WxRbF0s.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-3890757091011414166</id><published>2008-12-08T11:43:00.009+01:00</published><updated>2008-12-08T20:43:40.618+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-08T20:43:40.618+01:00</app:edited><title>Excellent blogposts on DDD and NHibernate</title><content type="html">&lt;p&gt;I'm in the process of setting up NHibernate on a new project and we've decided to try to let the domain model drive our development. Meaning; we're trying to follow the &lt;a href="http://en.wikipedia.org/wiki/Domain_driven_design"&gt;Domain Driven Design &lt;/a&gt;mindset. And as I'm quite new to both NHibernate and DDD, reading the 9-parts series called "A Journey with Domain Driven Design (and NHibernate)" by Ben Scheirman really gave me a good start. But unfortunately there's no summary post for his article series, so for my own reference I'll add it here;&lt;br /&gt;&lt;/p&gt;&lt;a href="http://flux88.com/blog/a-journey-with-nhibernate-part-1/"&gt;Part 1&lt;/a&gt;: Intro and project structure: &lt;span style="font-style: italic;"&gt;"In the first few articles, we will see how to start projects using NHibernate, go over some basic topics, and then get progressively more complex as we explore the many features of the ORM tool."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flux88.com/blog/a-journey-with-nhibernate-part-2/"&gt;Part 2&lt;/a&gt;: Domain model: &lt;span style="font-style: italic;"&gt;"This time I am going to start off creating a pet project to demonstrate how to implement these ideas.  First we’ll implement a simple domain model to support our features.  We will combine these with unit tests to verify behavior."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flux88.com/blog/a-journey-with-nhibernate-and-ddd-part-3/"&gt;Part 3&lt;/a&gt;: Unit testing:&lt;span style="font-style: italic;"&gt; "When testing, whether you practice test-driven development (TDD) or not, it is important that your tests and your code follow each other closely. (...) I’m not a TDD purist, but I try to write the tests first to let the consumer (the calling code) drive the design."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flux88.com/blog/a-journey-with-domain-driven-design-and-nhibernate-part-4/"&gt;Part 4&lt;/a&gt;: Unit testing with transactions: &lt;span style="font-style: italic;"&gt;"Let’s get on with the more interesting tests.  Another thing I’d like to note is that, the tests here pass, but only after I write the appropriate code in the model to satisfy the test.  I am purposefully omitting the domain model code at this time because it is unimportant.  You should be able to understand what the code does without looking inside the class. "&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flux88.com/blog/a-journey-with-domain-driven-design-and-nhibernate-part-5/"&gt;Part 5&lt;/a&gt;: Database schema and NHibernate config/initialization (ISessionFactory, ISession): &lt;span style="font-style: italic;"&gt;"Let’s create a database structure to support persistence of our domain model."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flux88.com/blog/a-journey-with-domain-driven-design-and-nhibernate-part-6/"&gt;Part 6&lt;/a&gt;: NHibernate mapping: &lt;span style="font-style: italic;"&gt;"We’ll dive in deeper with NHibernate and mapping in this article."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flux88.com/blog/a-journey-with-domain-driven-design-and-nhibernate-part-7/"&gt;Part 7&lt;/a&gt;: NHibernate mapping with associations/relations: &lt;span style="font-style: italic;"&gt;"We introduced some simple mapping concepts, and this time we’ll dig in a bit deeper."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flux88.com/blog/a-journey-with-domain-driven-design-and-nhibernate-part-8/"&gt;Part 8&lt;/a&gt;: NHibernate split mapping files, building a Repository and saving to the database: &lt;span style="font-style: italic;"&gt;"We left off last time with our first association mapped and tested.  Let’s dig in a bit deeper with NHibernate mapping.(...) Repository takes advantage of generics to avoid a lot of duplicate code.  This is a quick implementation of the Repository pattern (...)"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flux88.com/blog/a-journey-with-domain-driven-design-and-nhibernate-part-9/"&gt;Part 9&lt;/a&gt;: Higher level tests: &lt;span style="font-style: italic;"&gt;"In this article, part 9 of the series, we’re going to wrap up our initial feature list and focus on building a user-interface for our video store, named Videocracy."&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-3890757091011414166?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/3QvORdlBhCM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/3890757091011414166/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=3890757091011414166&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/3890757091011414166?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/3890757091011414166?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/3QvORdlBhCM/excellent-blogposts-on-ddd-and.html" title="Excellent blogposts on DDD and NHibernate" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kjetilk.com/2008/12/excellent-blogposts-on-ddd-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQBQH4-eip7ImA9WxRbF0o.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-8895507203486111725</id><published>2008-11-16T22:45:00.018+01:00</published><updated>2008-12-08T22:05:51.052+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-08T22:05:51.052+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tips" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title>Empty delegate makes event raising easy and thread-safe</title><content type="html">I'm currently working on a project that will use some of the guidelines from the &lt;a href="http://www.codeplex.com/CompositeWPF"&gt;WPF Composite Application Guidance&lt;/a&gt;. And as I was studying the source code I kept seeing a strange&lt;br /&gt;initialization of events that looked something like this;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EventHandler EmptyDelegateEvent = &lt;span class="kwrd"&gt;delegate&lt;/span&gt; { };&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I mean; I &lt;i&gt;do&lt;/i&gt; know my way around delegates, but these empty delegates puzzled me. After &lt;a href="http://kristofverbiest.blogspot.com/2008/08/even-better-pattern-to-raise-events.html"&gt;googling around&lt;/a&gt; a bit I found that this was a just a clever way of avoiding null reference exception when raising the event. So instead of this;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EventHandler CheckForNullEvent;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; RaiseEvent()&lt;br /&gt;{&lt;br /&gt; &lt;span class="rem"&gt;// the usuall way&lt;/span&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (CheckForNullEvent != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;     CheckForNullEvent(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; EventArgs());&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;...you can simply do this;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EventHandler EmptyDelegateEvent = &lt;span class="kwrd"&gt;delegate&lt;/span&gt; { };&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; RaiseEvent()&lt;br /&gt;{&lt;br /&gt;   &lt;span class="rem"&gt;// the easy way&lt;/span&gt;&lt;br /&gt;   EmptyDelegateEvent(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; EventArgs());&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;When using empty delegates you can simply raise the event without checking for null. Note though, that performance wise it will be better to do the "if not null" check than a "delegate {}". But I ran some performance testing to compare the two, and the performance hit is really not that big of an issue. Even though the performance of the empty delegate was 20-30% slower than the null check, the time it takes to do either of them is miniscule. This is really not where you should put your performance tuning effort. A 'null reference exception', which is much more likely to happen if you forget to check for the null, will have a much bigger impact on the overall performance of your application. Or even worse; if a raise condition occurs. Which again reminds me that the correct way of checking the event for null and at the same time making sure it's thread-safe, is this;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; RaiseEvent()&lt;br /&gt;{&lt;br /&gt;   &lt;span class="rem"&gt;// the thread-safe way&lt;/span&gt;&lt;br /&gt;   EventHandler copyOfEvent = CheckForNullEvent;&lt;br /&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt; (copyOfEvent != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;       copyOfEvent(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; EventArgs());&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;And how many does actually do that? And talking of performance; what about 'developer performance'? Instantiating an empty delegate and no need for null checking or possible raise conditions, means faster coding and less bugs - e.g. better developer performance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-8895507203486111725?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/MJOIL0HxEFI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/8895507203486111725/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=8895507203486111725&amp;isPopup=true" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/8895507203486111725?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/8895507203486111725?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/MJOIL0HxEFI/empty-delegate-makes-event-raising-easy.html" title="Empty delegate makes event raising easy and thread-safe" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://www.kjetilk.com/2008/11/empty-delegate-makes-event-raising-easy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4ARX0-cCp7ImA9WxBVEEs.&quot;"><id>tag:blogger.com,1999:blog-3258074296776382669.post-66312182344167948</id><published>2008-11-16T21:32:00.003+01:00</published><updated>2010-02-13T14:15:44.358+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-13T14:15:44.358+01:00</app:edited><title>Kjetil.Klaussen.ToString()</title><content type="html">Hi, and welcome to my blog! &lt;br /&gt;
&lt;br /&gt;
I’m a .NET developer working as a consultant for Trondheim-based and Swedish owned company &lt;u&gt;&lt;a href="http://www.acando.no/"&gt;Acando&lt;/a&gt;&lt;/u&gt;. I started out in this geekie world as a database/web developer on Microsoft SQL Server 2000 and classic ASP. And even though I still enjoy programming intricate joins in T-SQL, since I was introduced to .NET and C# in 2001 I have &lt;em&gt;never &lt;/em&gt;missed classic ASP. &lt;br /&gt;
&lt;br /&gt;
In my early days as a .NET-developer I mainly worked on ASP.NET WebForms. Later I moved over on the desktop and starting building WinForms, but still with some ASP.NET work occasionally. Since late 2007 I've been fortunate enough to work on WPF and I must say that I'm immensely pleased with this framework and hopefully I’m all done with WinForms.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Strongly influenced by my colleague &lt;a href="http://blog.fossmo.net/"&gt;Pål Fossmo&lt;/a&gt; I’ve also developed a strong feeling for &lt;em&gt;Test Driven Development&lt;/em&gt;. My experience in TDD is - at the time of writing (november 2008) - still somewhat novice and I still struggle to follow the &lt;em&gt;Test-First&lt;/em&gt; approach. But I try hard and feel like I get closer to a TDD mindset every day. What I really enjoy about TDD is the confidence that testing gives me. It makes me sleep better at night knowing that the code I wrote today has been proven to work and I didn’t mess up any other parts of the application writing it. &lt;br /&gt;
&lt;br /&gt;
Closely related to the awakening experience of testable code is my interest in design patterns and beautiful code. These three pillars – testable, pattern based, well-written code – are what I consider the very core of developing good, maintainable software. Working as a consultant I believe that one of my main responsibilities is to make whatever code I write understandable and thereby maintainable to the guy or gal next to me. Because when I move on to the next project, (s)he is the one who’s going to maintain and build on to the code I just left behind. Taking pride in making that an as easy job as possible is always my number one priority. Not that this should only relate to consultants, but I do believe that we have an extra liability in making this effort.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3258074296776382669-66312182344167948?l=www.kjetilk.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AWorldFullOfSharpObjects/~4/tJ0_TLUaWZA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.kjetilk.com/feeds/66312182344167948/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=3258074296776382669&amp;postID=66312182344167948&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/66312182344167948?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3258074296776382669/posts/default/66312182344167948?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AWorldFullOfSharpObjects/~3/tJ0_TLUaWZA/kjetilklaussentostring.html" title="Kjetil.Klaussen.ToString()" /><author><name>Kjetil Klaussen</name><uri>http://www.blogger.com/profile/15985372289245420671</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15743109626535357258" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.kjetilk.com/2008/11/kjetilklaussentostring.html</feedburner:origLink></entry></feed>
