<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4093944831568090072</id><updated>2012-01-18T19:23:35.473+01:00</updated><category term='Coding'/><category term='Visual Studio'/><category term='Sterling'/><category term='RavenDB'/><category term='xsl'/><category term='Karvonite'/><category term='iTunes'/><category term='MVVM'/><category term='tools'/><category term='Git'/><category term='agile'/><category term='NHibernate'/><category term='UI'/><category term='UML'/><category term='F#'/><category term='SVN'/><category term='Exceptions'/><category term='IIS'/><category term='WPF'/><category term='.NET'/><category term='ASP.NET'/><category term='Testing'/><title type='text'>Travelling through development</title><subtitle type='html'>My experiences while discovering the various aspects of software development I encounter.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>36</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-4470280914450672973</id><published>2012-01-18T19:22:00.000+01:00</published><updated>2012-01-18T19:23:35.481+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>How to use NHibernate's SQLCriterion - take 2</title><content type='html'>After having an interesting discussion with &lt;a href="https://twitter.com/#!/BastinStef"&gt;Stefaan &lt;/a&gt;(colleague, friend, ex-colleague and now colleague again) about my previous post on &lt;a alt="How to use NHibernate SQLCriterion" href="http://petermorlion.blogspot.com/2012/01/how-to-use-nhibernates-sqlcriterion.html"&gt;NHibernate's SQLCriterion&lt;/a&gt;, I decided to have another look at my usage of SQLCriterion.&lt;br /&gt;&lt;br /&gt;He argued that with SQLCriterion, you're more or less working around the ORM, which I can agree with.After putting it on &lt;a href="http://stackoverflow.com/questions/8807187/how-to-query-a-foreign-key-column-with-nhibernate-without-retrieving-the-relate"&gt;StackOverflow&lt;/a&gt;, I got three answers and tried all three.&lt;br /&gt;&lt;br /&gt;This is what I went with in the end:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ISessionFactory sessionFactory = GetSessionFactory();&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ISession session = sessionFactory.GetCurrentSession();&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ICriteria criteria = session.CreateCriteria&lt;customer&gt;();&amp;nbsp;&lt;/customer&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;return session.QueryOver&lt;customer&gt;().Where(c =&amp;gt; c.Group.Id == groupId).List&lt;customer&gt;();&amp;nbsp;&lt;/customer&gt;&lt;/customer&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A more elegant solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-4470280914450672973?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/4470280914450672973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=4470280914450672973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/4470280914450672973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/4470280914450672973'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2012/01/how-to-use-nhibernates-sqlcriterion_18.html' title='How to use NHibernate&apos;s SQLCriterion - take 2'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-1796653586426620775</id><published>2012-01-08T15:50:00.002+01:00</published><updated>2012-01-08T15:52:47.722+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>How to use NHibernate's SQLCriterion</title><content type='html'>I recently needed to use &lt;b&gt;NHibernate's SQLCriterion&lt;/b&gt;, but lost some time on finding out how to use it. Once you've found it, it's quite simple actually:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ISessionFactory sessionFactory = GetSessionFactory();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ISession session = sessionFactory.GetCurrentSession();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ICriteria criteria = session.CreateCriteria&amp;lt;Customer&amp;gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;var sqlString = new SqlString("{alias}.GroupId = " + groupId);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;criteria.Add(new SQLCriterion(sqlString, new object[0], new IType[0]));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;return criteria.List&amp;lt;Customer&amp;gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;The &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;{alias}&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;is there so NHibernate knows where to put the table name. I'm not so sure about the second and third argument of the SQLCriterion constructor, but in my case, I didn't need them. Just don't pass in &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;null&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;or you'll get an exception.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;If you need a more advanced SQLCriterion, check out &lt;a href="http://blogs.rawsoft.nl/remco/post/2009/07/23/A-better-SQLCriterion-for-NHibernate.aspx"&gt;this post by Remco Ros&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-1796653586426620775?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/1796653586426620775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=1796653586426620775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/1796653586426620775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/1796653586426620775'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2012/01/how-to-use-nhibernates-sqlcriterion.html' title='How to use NHibernate&apos;s SQLCriterion'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-5556437331782803866</id><published>2011-10-07T17:33:00.001+02:00</published><updated>2011-10-07T17:33:17.838+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Git'/><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><title type='text'>Trunk based development</title><content type='html'>&lt;p&gt;In our team, we’ve recently changed our source control strategy to what’s now being called ‘&lt;strong&gt;trunk based development&lt;/strong&gt;’. This has reduced the amount of merge-headaches we were having.&lt;/p&gt; &lt;p&gt;In the past, we used a form of branch-per-feature with only one branch. We would have a trunk and a development branch (we’re using &lt;strong&gt;Subversion&lt;/strong&gt;). Coding would be done on the development branch, and when a story/feature was finished, it would be merged to the trunk. After the merge, a new development branch was made. The trunk was, in effect, always releaseable.&lt;/p&gt; &lt;p&gt;At least, that was the theory. This didn’t really work in practice:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;sometimes a feature can’t really be released without the next story  &lt;li&gt;bits and pieces of the next story would have been implemented before the previous story had been finished (otherwise developers would be sitting around, waiting for the merge before committing)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;More importantly, this &lt;strong&gt;slowed us down&lt;/strong&gt; because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;there were conflicts when merging (when a fixes branch touching the same code had been merged in the trunk)  &lt;li&gt;it takes some time to merge, build, commit, delete the old branch and make a new branch (meanwhile, teammembers can’t commit code to the old branch)  &lt;li&gt;this is inherently error-prone, as conflicts could be resolved wrongly, (re-)introducing bugs, often only discovered when the code was already in production&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Finally, there was no need for our trunk to always be releasable, because we know when we’re going to release and with any modern source control system, you can jump back to certain revisions.&lt;/p&gt; &lt;h4&gt;Curing headaches&lt;/h4&gt; &lt;p&gt;Switching to &lt;strong&gt;trunk-based development&lt;/strong&gt; is easy and we haven’t looked back since. The point is:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Develop and commit to the trunk  &lt;li&gt;Make tags from the trunk  &lt;li&gt;Bugfix branches are made from the tag, but are merged to the trunk again of course &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The only problem you can have, is at that moment just before a release. There are two smaller tasks that need to be finished for the tag, but other developers want to start with the next story. This next story is not allowed to be included in the tag. &lt;/p&gt; &lt;p&gt;The solution is simple: make a branch to finish the work for the tag. Finish the job, make the tag from this branch en merge the changes back into the trunk. No need to remove this branch as it can serve as a bugfix branch.&lt;/p&gt; &lt;p&gt;Here’s a colorful diagram to make this post look professional:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-T9LM7L2xQPk/To8bu8JPCKI/AAAAAAAAAII/_w8yvdp8ZJU/s1600-h/Trunk%252520based%252520development%25255B5%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Trunk based development" border="0" alt="Trunk based development" src="http://lh4.ggpht.com/-MjMx3yROrxY/To8bvQTXGlI/AAAAAAAAAIM/9fgwzTBg1IA/Trunk%252520based%252520development_thumb%25255B3%25255D.png?imgmax=800" width="672" height="239"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In the end, this makes our development track more fluent, less stressful, less complicated, and hasn’t given us any problems.&lt;/p&gt; &lt;p&gt;At the moment we researched this, there wasn’t very many information to be found. But these are the articles we based our decision on:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://martinfowler.com/bliki/FeatureBranch.html"&gt;Feature Branch&lt;/a&gt; – by Martin Fowler&lt;/li&gt; &lt;li&gt;&lt;a href="http://paulhammant.com/blog/branch_by_abstraction.html"&gt;Branch By Abstraction&lt;/a&gt; – By Paul Hammant&lt;/li&gt; &lt;li&gt;&lt;a href="http://jawspeak.com/2010/11/07/some-problems-with-branch-based-development-and-recommendations/"&gt;Some Problems with Branch Based Development, And Recommendations&lt;/a&gt; – By Jonathan Andrew Walker&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.slideshare.net/carlosaml/trunk-based-development-explored"&gt;Trunk Based Development Explored&lt;/a&gt; – Slideshow by Agile Brazil&lt;/li&gt; &lt;li&gt;&lt;a href="http://udhaaranam.blogspot.com/2010/07/branch-vs-trunk-based-development.html"&gt;Branch vs Trunk Based Development&lt;/a&gt;&amp;nbsp;&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/4093944831568090072-5556437331782803866?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/5556437331782803866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=5556437331782803866' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5556437331782803866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5556437331782803866'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2011/10/trunk-based-development.html' title='Trunk based development'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-MjMx3yROrxY/To8bvQTXGlI/AAAAAAAAAIM/9fgwzTBg1IA/s72-c/Trunk%252520based%252520development_thumb%25255B3%25255D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-5890558625751693627</id><published>2011-08-24T18:47:00.001+02:00</published><updated>2011-08-24T18:47:08.457+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><title type='text'>Coding pet peeves</title><content type='html'>&lt;p&gt;This was a blog post I had lying around, waiting to be posted. This post on &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2011/08/24/code-smells-and-other-problems.aspx"&gt;code smells&lt;/a&gt; on the All Your Base Are Belong To Us blog reminded me of it. So here goes.&lt;/p&gt; &lt;p&gt;Everyone has coding pet peeves. Pieces of code they can’t resist the urge to change when they see it. Of course, there will be exceptions, or cases where it’s impossible to change the code, or just not worth it. But not that often. Apart from &lt;a href="http://petermorlion.blogspot.com/"&gt;wrapping all your methods in try-catch blocks&lt;/a&gt;, here are two other of my &lt;strong&gt;coding pet peeves&lt;/strong&gt;.&lt;/p&gt; &lt;h2&gt;Helper classes&lt;/h2&gt; &lt;p&gt;Helper classes are classes whose names end in 'Helper’. In my line of work (hospitals): PatientHelper, AnamnesisHelper, etc. Sometimes they might end in ‘Utilities’. They all have several things in common, starting the the &lt;strong&gt;too general name&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;The &lt;a title="Single-Responsibility-Principle" href="http://en.wikipedia.org/wiki/Single_responsibility_principle" target="_blank"&gt;Single-Responsibility-Principle&lt;/a&gt; requires that a class has one responsibility. This, to me, implies that it shoud have a clear and unambiguous name. Helper or Utilities is not clear.&lt;/p&gt; &lt;p&gt;The biggest danger with classnames like this, is that these classes can become too big, with all sorts of methods dumped in them.&lt;/p&gt; &lt;p&gt;There are several ways you can get rid of these classes. Remove them method by method. I’ve been able to move methods to repositories, domain objects, controllers, extension methods, etc. All classes that are loud and clear in what they do (extension methods are a bit special).&lt;/p&gt; &lt;h2&gt;One file per class&lt;/h2&gt; &lt;p&gt;Why would you put &lt;strong&gt;multiple classes in one file&lt;/strong&gt;? Usually, it’s because it’s a small class, an enum probably. The advantage is laziness, I believe. The advantage of one class-one file, is that you can easily see all classes in your IDE of choice. Which is a small advantage, maybe. But it is a pet peeve, so it doesn’t always have to be fully rational, no?&lt;/p&gt; &lt;p&gt;Also, files are cheap, so no need to ration them.&lt;/p&gt; &lt;p&gt;A bigger advantage becomes apparent when you’re using source control. When opening the log file, you can more easily search for changes to a class, because a class and a file are the same. You don’t have to inspect the diff to know if your class changed, or it was just something added to the enum.&lt;/p&gt; &lt;h2&gt;Pet Peeves&lt;/h2&gt; &lt;p&gt;I guess everyone has their personal style of coding, and their personal coding pet peeves. What are yours? What small things make you cringe when looking at code?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-5890558625751693627?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/5890558625751693627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=5890558625751693627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5890558625751693627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5890558625751693627'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2011/08/coding-pet-peeves.html' title='Coding pet peeves'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-5061071979510027862</id><published>2011-06-25T10:18:00.002+02:00</published><updated>2011-06-25T10:19:25.979+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Exceptions'/><title type='text'>Exceptions everywhere</title><content type='html'>On two projects I have worked on, I’ve seen a lot of this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoSomething()&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span class="rem"&gt;// actually do something here&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Exception(&lt;span class="str"&gt;"Unable to do something"&lt;/span&gt;, ex);&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I’ve seen this in various differing styles:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;not including the original exception in the newly thrown one (&lt;a href="http://www.scribd.com/doc/53986677/61/Back-to-Basics-Exceptions" target="_blank" title="Back to Basics - Karl Seguin"&gt;ouch&lt;/a&gt;!) &lt;/li&gt;&lt;li&gt;having a custom Exception type, indicating where in the code/assemblies the exception happened. &lt;/li&gt;&lt;/ul&gt;Reasons seem to be a desire to easily see where the exception occurred. So a DomainException would indicate the exception happened in the Domain DLL. Another reason was to easily see the methods called. In the log of an exception, you can then see all the “sub-exceptions”.&lt;br /&gt;&lt;br /&gt;Of course, this can all be seen in the stacktrace, and I believe it has its origins in the old days of coding, where you would have to set up your exception handling manually. But in .NET, this all happens automatically, and you’ve got a full stacktrace to help you find the problem.&lt;br /&gt;&lt;br /&gt;Even more, wrapping each method in a try-catch construction gives for more code-noise when you’re scanning a class. More for your brains to process, harder to find what you’re looking for, etc.&lt;br /&gt;&lt;br /&gt;So: no advantages, only disadvantages. &lt;strong&gt;Only catch an exception if you’ll do something with/about it&lt;/strong&gt;. Log it, swallow it, mention it to the user. But if you’re only going to rethrow it, don’t. Just don’t. Catch your exceptions at the top-most level.&lt;br /&gt;&lt;br /&gt;Oh, and never do this:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt; (myObject == &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&lt;span class="kwrd"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Excpetion(&lt;span class="str"&gt;"myObject is null"&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Yes, I’ve seen this. It’s no shame if you’ve ever coded this, but remove it when you see it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-5061071979510027862?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/5061071979510027862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=5061071979510027862' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5061071979510027862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5061071979510027862'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2011/06/exceptions-everywhere.html' title='Exceptions everywhere'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-6836228352818462100</id><published>2011-05-10T20:16:00.001+02:00</published><updated>2011-05-10T20:16:59.162+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Sterling'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>A repository with Sterling for a desktop WPF application</title><content type='html'>&lt;p&gt;Well, I’ve switched databases again. After briefly trying NHibernate, then &lt;a title="Switching from NHibernate to RavenDB" href="http://petermorlion.blogspot.com/2010/06/switching-from-nhibernate-to-ravendb.html"&gt;switching to RavenDB&lt;/a&gt;, then looking at &lt;a title="Karvonite as alternative to RavenDB" href="http://petermorlion.blogspot.com/2011/01/alternative-to-ravendb.html"&gt;Karvonite&lt;/a&gt;, I think I’ve found what I was looking for in &lt;a title="Sterling NoSql OODB" href="http://sterling.codeplex.com/" target="_blank"&gt;Sterling&lt;/a&gt;. I was looking for an easy way to persist objects. NHibernate is nice, but compared to object-oriented databases, it’s a lot of work (database schema’s, mapping files, etc.). RavenDB introducted me to the NoSql alternatives, but has a high licensing fee and is a little to heavy for my needs. Karvonite was actually what I was looking for, but &lt;strong&gt;Sterling&lt;/strong&gt; will be more actively under development and supported. There’s little news on the Karvonite site.&lt;/p&gt;  &lt;p&gt;So, I’m developing a &lt;strong&gt;WPF desktop application&lt;/strong&gt;, and want to work with Sterling. This is possible since 1.4 beta (although I had to sign the assemblies myself for now).&lt;/p&gt;  &lt;p&gt;First, I will add my references to Wintellect.Sterling.Server and Wintellect.Sterling.Server.FileSystem. Next, I create my &lt;strong&gt;DatabaseInstance&lt;/strong&gt;:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SterlingDatabaseInstance : BaseDatabaseInstance&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; List&amp;lt;ITableDefinition&amp;gt; RegisterTables()&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;ITableDefinition&amp;gt;&lt;br /&gt;                       {&lt;br /&gt;                           CreateTableDefinition&amp;lt;Patient, Guid&amp;gt;(x =&amp;gt; x.Id),&lt;br /&gt;                           CreateTableDefinition&amp;lt;JournalEntry, Guid&amp;gt;(x =&amp;gt; x.Id).WithIndex&amp;lt;JournalEntry, DateTime, Guid&amp;gt;(JournalEntryEntryDateIndex, x =&amp;gt; x.EntryDate)&lt;br /&gt;                       };&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;SterlingDatabaseInstance&amp;quot;&lt;/span&gt;; }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Next, we need the &lt;strong&gt;Sterling engine&lt;/strong&gt;. As per the &lt;a title="The Sterling Engine" href="http://www.sterlingdatabase.com/sterling-user-guide/3-the-sterling-engine" target="_blank"&gt;documentation&lt;/a&gt;, &lt;em&gt;“The Sterling engine should always be activated at the beginning of the application, and disposed of at the end. It should live as long as the application does.”&lt;/em&gt; I will do this in my App.xaml.cs. I could choose to instantiate a new SterlingEngine the first time a repository is used. But I would need to dispose it when my application shuts down, so I need code in App.xaml.cs anyway.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;As I will be needing the database in my repositories, I’m making a DatabaseService class:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DatabaseService&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; SterlingEngine _engine;&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ISterlingDatabaseInstance _databaseInstance;&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Start()&lt;br /&gt;        {&lt;br /&gt;            _engine = &lt;span class="kwrd"&gt;new&lt;/span&gt; SterlingEngine();&lt;br /&gt;            _engine.Activate();&lt;br /&gt;            var folder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + &lt;span class="str"&gt;&amp;quot;MyApp/&amp;quot;&lt;/span&gt;;&lt;br /&gt;            var driver = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileSystemDriver(folder);&lt;br /&gt;            _databaseInstance = _engine.SterlingDatabase.RegisterDatabase&amp;lt;SterlingDatabaseInstance&amp;gt;(driver);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ISterlingDatabaseInstance Current&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _databaseInstance; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Stop()&lt;br /&gt;        {&lt;br /&gt;            _engine.Dispose();&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;Now, in my App.xaml.cs, on starting my application, I just call DatabaseService.Start(). And on exiting the application, I call DatabaseService.Stop().&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Then, finally, I can implement my repository. Because I’m using a BaseRepository&amp;lt;T&amp;gt;, where T is any aggregate root, this was fairly simple:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BaseRepository&amp;lt;T&amp;gt; : IBaseRepository&amp;lt;T&amp;gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; T : BaseEntity, &lt;span class="kwrd"&gt;new&lt;/span&gt;()&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; IList&amp;lt;T&amp;gt; GetAll()&lt;br /&gt;        {&lt;br /&gt;            var query = (from key &lt;span class="kwrd"&gt;in&lt;/span&gt; DatabaseService.Current.Query&amp;lt;T, &lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;() select key.LazyValue.Value).ToList();&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; query;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Save(T aggregate)&lt;br /&gt;        {&lt;br /&gt;            DatabaseService.Current.Save(aggregate);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Delete(T aggregate)&lt;br /&gt;        {&lt;br /&gt;            DatabaseService.Current.Delete(aggregate);&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;Notice the fact that T must have a parameterless constructor. The key variable will have a property Key, which is the primary key of your table, and a LazyValue, which is the actual object. This isn’t loaded until you call it, and the same goes for Indexes, which gives you a preformance advantage. But more on that later (maybe).&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-6836228352818462100?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/6836228352818462100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=6836228352818462100' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/6836228352818462100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/6836228352818462100'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2011/05/repository-with-sterling-for-desktop.html' title='A repository with Sterling for a desktop WPF application'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-1349592370441456586</id><published>2011-02-10T20:00:00.000+01:00</published><updated>2011-02-10T20:00:01.770+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Testing your code</title><content type='html'>&lt;p&gt;Thinking about it, the team I work in has quite a lot of ‘security checkpoints’ for our code. We try to put as many pieces of code under unit test. However, we are often hindered by an old framework that can be described as a sort of ‘&lt;a title="CSLA - Rockford Lhotka" href="http://www.lhotka.net/cslanet/"&gt;CSLA&lt;/a&gt; meets &lt;a title="Active Record - Martin Fowler" href="http://martinfowler.com/eaaCatalog/activeRecord.html"&gt;Active Record&lt;/a&gt;’. If &lt;strong&gt;unittests&lt;/strong&gt; are impossible, we will make &lt;strong&gt;fit-tests&lt;/strong&gt; (using &lt;a title="FitSharp" href="http://www.syterra.com/FitSharp.html"&gt;FitSharp&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;We develop using the &lt;a title="Scrum" href="http://en.wikipedia.org/wiki/Scrum_(development)"&gt;Scrum&lt;/a&gt; methodology, and, after you finished your task, you can stick the post-it in the ‘&lt;strong&gt;2nd opinion&lt;/strong&gt;’ column. This isn’t required, but if you’re not sure about something, you can have a teammember look at the code you’ve written.&lt;/p&gt;  &lt;p&gt;At the end of a story, there’s a paper hanging on our wall with a description of the story, the Definition of Done, and a list of &lt;strong&gt;acceptance requirements&lt;/strong&gt;. When the story is finished (no more tasks for the story), any developer can take this paper and &lt;strong&gt;test the entire story&lt;/strong&gt;. He/she checks all acceptance criteria, but also does some random testing, plays with the new features, acts as a normal user, tries some exceptional cases, etc.&lt;/p&gt;  &lt;p&gt;At the &lt;strong&gt;end of a sprint&lt;/strong&gt;, all stories are shown to the product owner and the entire team. Here again, the acceptance criteria are checked.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Before we do a release&lt;/strong&gt;, we deploy our application (a .NET web application) on a local server and all stories are tested again, plus some default test scenarios (critical functionalities that always have to work for our users). This manual testing is done by the product owner, as well as one or two developers.&lt;/p&gt;  &lt;p&gt;This is two weeks before the release into the production environment. One week before, we deploy to the &lt;strong&gt;beta&lt;/strong&gt; environment of our customers (those who have a beta environment). This way, they can explore the new functionalities and signal bugs.&lt;/p&gt;  &lt;p&gt;Finally, we release to the &lt;strong&gt;production&lt;/strong&gt; environment. If anywhere along the way a bug is found, it is fixed of course. So you’d think this is a fairly tight strategy, wouldn’t you? And yet, &lt;strong&gt;bugs still get through&lt;/strong&gt;. Granted, it’s been a while since we’ve had to deploy a critical bugfix to production. Also, usually we’ll catch the bug in our week of testing, but even then you would think it would’ve/should’ve been noticed earlier.&lt;/p&gt;  &lt;p&gt;This strategy seems a lot of work, but it has saved us a lot of time. In the past, we’ve had weeks in which we had to deploy up to 8 critical bugfixes, some of which were incomplete and had to be fixed in a next bugfix. This creates a reasonable amount of stress, looks unprofessional to users, and wastes your time as a developer. So catching and fixing the bugs beforehand with this extensive strategy actually saves us time and lets us concentrate on developing new, requested features.&lt;/p&gt;  &lt;p&gt;To quote the &lt;a title="Google Testing Blog" href="http://googletesting.blogspot.com/"&gt;Google Testing Blog&lt;/a&gt;: “if it ain’t broke, you’re not testing hard enough.”&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-1349592370441456586?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/1349592370441456586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=1349592370441456586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/1349592370441456586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/1349592370441456586'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2011/02/testing-your-code.html' title='Testing your code'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-8598729112056307327</id><published>2011-01-10T20:21:00.001+01:00</published><updated>2011-01-10T20:28:04.558+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='RavenDB'/><category scheme='http://www.blogger.com/atom/ns#' term='Karvonite'/><title type='text'>Karvonite as alternative to RavenDB in a desktop application</title><content type='html'>&lt;p&gt;Right now, I’m using &lt;strong&gt;RavenDB&lt;/strong&gt;, but it seems to be a little overkill. It’s a great piece of software, very powerful, but a little too powerful for what I need. It handles all sorts of fancy stuff like &lt;a title="RavenDB sharding" href="http://ravendb.net/documentation/docs-sharding"&gt;sharding&lt;/a&gt;, &lt;a title="RavenDB replication" href="http://ravendb.net/documentation/replication"&gt;replication&lt;/a&gt;, &lt;a title="RavenDB versioning" href="http://ravendb.net/bundles/versioning"&gt;versioning&lt;/a&gt;, etc. I have the impression it’s made for applications that have fairly hefty requirements, often client/server applications that need to scale up in time.&lt;/p&gt;  &lt;p&gt;Also, specifically for me, the &lt;a href="http://ravendb.net/licensing"&gt;licensing of RavenDB&lt;/a&gt; is too expensive. I don’t have a clear view of where my application is going. Will I be able to sell it to customers? Will I open source it? Will I build it to a certain point and then sell it?&lt;/p&gt;  &lt;p&gt;So, I started looking for an &lt;strong&gt;alternative to RavenDB&lt;/strong&gt;, keeping in mind that I’m developing a classic desktop application. I considered &lt;a title="MongoDB" href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt;, but it is also aimed at scalable applications with a server (I believe). I looked at &lt;a title="Sterling Isolated Storage Database" href="http://sterling.codeplex.com/"&gt;Sterling&lt;/a&gt;, which is aimed at Silverlight and Windows Phone. Someone &lt;a title="Sterling ported for desktop" href="http://sterling.codeplex.com/Thread/View.aspx?ThreadId=233719"&gt;ported it to the desktop&lt;/a&gt;, but I’d have to rebuild it with every update.&lt;/p&gt;  &lt;p&gt;But recently, I found &lt;strong&gt;&lt;a title="Karvonite" href="http://code.msdn.microsoft.com/karvonite"&gt;Karvonite&lt;/a&gt;&lt;/strong&gt;. It promises to give you persistence ignorance, and can serialize objects, even with circular and shared references. It also supports a changing domain model. It supports Windows, XNA (XBOX), and Windows Phone.&lt;/p&gt;  &lt;p&gt;Setting it up was fairly easy:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Reference Karvonite40.dll in the correct directory (based on your platform).&lt;/li&gt;    &lt;li&gt;Use the Persistence Model Editor to generate a Persistence Model.&lt;/li&gt;    &lt;li&gt;Add the generated kvtmodel file as Embedded Resource.&lt;/li&gt;    &lt;li&gt;I made an ObjectSpaceFactory to initialize the ObjectSpace if necessary, and return it (only open the ObjectSpace once).&lt;/li&gt;    &lt;li&gt;Wired it up to my BaseRepository&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Presto!&lt;/p&gt;  &lt;p&gt;I’m amazed I never heard of this, and hope it will continue to be under development. I’ll post more details when I learn more about it, but for now, initial tests work.&lt;/p&gt;  &lt;p&gt;Oh, recommended reading: the &lt;a title="Karvonite overview" href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=karvonite&amp;amp;DownloadId=14376"&gt;Karvonite overview&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/4093944831568090072-8598729112056307327?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/8598729112056307327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=8598729112056307327' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8598729112056307327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8598729112056307327'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2011/01/alternative-to-ravendb.html' title='Karvonite as alternative to RavenDB in a desktop application'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-5278458390301447675</id><published>2010-12-15T19:16:00.002+01:00</published><updated>2010-12-23T11:29:58.236+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><title type='text'>Technical language in user interfaces</title><content type='html'>&lt;p&gt;Too often do we developers think as technical users. Take the following example I recently bumped into. &lt;/p&gt;&lt;p&gt;Our application, an &lt;a title="Electronic Health Record" href="http://en.wikipedia.org/wiki/Electronic_health_record"&gt;electronic health record&lt;/a&gt; for hospitals, needed a feature to send simple requests. The user would select a patient, select the request (let’s say ‘Request for MRI scan’), and then fill in the details (what to scan, for example).&lt;/p&gt;&lt;p&gt;We would then simply send an email to the correct email address, and include a PDF in attachment. This PDF would contain the details of the request. We named the attachment… ‘attachment.pdf’. Hurrah! To make it complete, the body of the email contained no reference of the patient, so the receiver couldn’t know which patient it concerned, unless he/she opened the attachment.&lt;/p&gt;&lt;p&gt;So we set out to change name of the attachment (among other things like the body of course), and changed it to… ‘attachment_John Doe.pdf’. That’s better, but it shows we were thinking like technical people. At least we used ‘John Doe’ with a space, and not John_Doe. Because ever since Windows 95 (I think), the normal world has moved on and named there files something like ‘This is the request for John Doe(2).pdf’.&lt;/p&gt;&lt;p&gt;So we changed it to ‘Request for MRI scan – John Doe.pdf’. That’s more like it. Use your technical style in code, but &lt;strong&gt;use normal language in your UI&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/4093944831568090072-5278458390301447675?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/5278458390301447675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=5278458390301447675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5278458390301447675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5278458390301447675'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/12/technical-language-in-user-interfaces.html' title='Technical language in user interfaces'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-3859065347873551574</id><published>2010-11-20T10:12:00.001+01:00</published><updated>2010-11-20T16:03:40.859+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='RavenDB'/><title type='text'>Running RavenDb embedded</title><content type='html'>&lt;p&gt;I seem to have some trouble finding how to &lt;strong&gt;run RavenDb in embedded mode&lt;/strong&gt;. This isn’t the same as my post on &lt;a title="Running RavenDb embedded for .NET 3.5" href="http://petermorlion.blogspot.com/2010/06/running-ravendb-only-when-your.html"&gt;running RavenDb embedded for .NET 3.5&lt;/a&gt;. This time, I’ve already updated to .NET 4, so I should be able to use the RavenDb embedded assemblies. I’m using build 193 by the way.&lt;/p&gt;  &lt;p&gt;The documentation on RavenDb.net is a little out of date, but that’s normal, because RavenDb is still very actively under development. A downside of using a new technology.&lt;/p&gt;  &lt;p&gt;But here goes. Start by referencing Raven.Client.Embedded. Instead of using a DocumentStore, you should now use an &lt;strong&gt;EmbeddablDocumentStore&lt;/strong&gt; (in my version of RavenDb there’s still a typo, it should be Embeddable I believe):&lt;/p&gt;  &lt;pre class="brush: js"&gt;var store = new EmbeddablDocumentStore { DataDirectory = @&amp;quot;D:\path\to\documentstore&amp;quot; };&lt;br /&gt;store.Initialize();&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You will also need a reference to Raven.Client.Lightweight, Raven.Storage.Essent (to avoid the “Could not find transactional storage type: Raven.Storage.Esent.TransactionalStorage, Raven.Storage.Esent” exception at runtime) and System.ComponentModel.Composition. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Note: At one time I got the exception: “Could not open transactional storage: D:\RavenDbTest\Data”. This was because somewhere else in my code, I was initializing the store again, when it was already initialized.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-3859065347873551574?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/3859065347873551574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=3859065347873551574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/3859065347873551574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/3859065347873551574'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/11/running-ravendb-embedded.html' title='Running RavenDb embedded'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-5463046194069750224</id><published>2010-09-14T18:39:00.001+02:00</published><updated>2010-09-14T18:39:52.856+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>Multiline textbox (textarea) and maxLength</title><content type='html'>&lt;p&gt;In ASP.NET, you can create a &lt;strong&gt;textarea&lt;/strong&gt; by adding a &lt;strong&gt;multiline textbox&lt;/strong&gt; to your markup:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;asp:textbox id=&amp;quot;textboxDescription&amp;quot; runat=&amp;quot;server&amp;quot; textmode=&amp;quot;MultiLine&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Intuitively, we started adding the &lt;strong&gt;MaxLength&lt;/strong&gt; property to this, in order to let the content of the textarea match the length of our database column:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;asp:textbox id=&amp;quot;textboxDescription&amp;quot; runat=&amp;quot;server&amp;quot; textmode=&amp;quot;MultiLine&amp;quot; maxlength=&amp;quot;2000&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;If you’re reading this, you know that doesn’t work. We, however didn’t. This is easily fixed with some javascript. But if you have a large site with many of these mistakes, you’d want to do it in one go. Use a control adapter for this:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h1&gt;&lt;font size="2" face="Courier New"&gt;Public Class TextBoxAdapter      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; Inherits WebControlAdapter &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ' If you need to access the adapted control, the framework advises to expose      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ' a private method encapsulating the Adapter's Control property.      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ' We can cast it without doing any test, as by naming convention,      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ' this adapter shall only be used for adapting Textboxes (or derived types)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; Private ReadOnly Property TextBoxControl() As TextBox      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return DirectCast(MyBase.Control, TextBox)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; End Property&amp;#160; &lt;br /&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; Protected Overrides Sub RenderBeginTag(ByVal writer As System.Web.UI.HtmlTextWriter)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If TextBoxControl.TextMode = TextBoxMode.MultiLine AndAlso TextBoxControl.MaxLength &amp;gt; 0 Then      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.AddAttribute(&amp;quot;maxlength&amp;quot;, TextBoxControl.MaxLength.ToString)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If&amp;#160; &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MyBase.RenderBeginTag(writer)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; End Sub&amp;#160; &lt;br /&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RenderBeginTag(writer)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If TextBoxControl.TextMode = TextBoxMode.MultiLine Then      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HttpUtility.HtmlEncode(TextBoxControl.Text, writer)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MyBase.RenderContents(writer)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MyBase.RenderEndTag(writer)      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; End Sub &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font size="2" face="Courier New"&gt;End Class&lt;/font&gt;&lt;/h1&gt;  &lt;p&gt;Due to a &lt;a title="A bug in the WebControlAdapter" href="http://forums.asp.net/t/1198521.aspx" target="_blank"&gt;bug in the WebControlAdapter class&lt;/a&gt;, you have to override the Render method.&lt;/p&gt;  &lt;p&gt;Now, add an App_Browsers ASP.NET folder to your project, and add an Allbrowsers.browser file to the folder:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;browsers&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;browser refID=&amp;quot;Default&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;controlAdapters&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;adapter controlType=&amp;quot;System.Web.UI.WebControls.TextBox&amp;quot; adapterType=&amp;quot;Ihc.Cpd.Presentation.Globals.TextBoxAdapter&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/controlAdapters&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/browser&amp;gt;       &lt;br /&gt;&amp;lt;/browsers&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Finally, include some javascript to your project. We’ve put it in a seperate file, which is always loaded (this needs &lt;a title="jQuery" href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt;, and was based on other peoples code, but I’ve lost the links):&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;// ignore these keys      &lt;br /&gt;var ignore = [8, 9, 13, 33, 34, 35, 36, 37, 38, 39, 40, 46]; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;// use keypress instead of keydown as that's the only place keystrokes could be canceled in Opera      &lt;br /&gt;// handle textareas with maxlength attribute       &lt;br /&gt;$('textarea[maxlength]').live('keypress',       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; function(event) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // this is where the magic happens       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var self = $(this),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; maxlength = self.attr('maxlength'),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; code = $.data(this, 'keycode'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // check if maxlength has a value.      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // The value must be greater than 0       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (maxlength &amp;amp;&amp;amp; maxlength &amp;gt; 0) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // continue with this keystroke if maxlength       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // not reached or one of the ignored keys were pressed.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (self.val().length &amp;gt;= maxlength || $.inArray(code, ignore) !== -1) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; alert('Too long!');       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return false;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; })       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .live('keydown',       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; function(event) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // store keyCode from keydown event for later use       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $.data(this, 'keycode', event.keyCode || event.which);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; })       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .live('keyup',       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; function(event) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // cut long text if pasted in the textarea       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var self = $(this),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; maxlength = self.attr('maxlength'),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text = self.val();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (text.length &amp;gt; maxlength)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; alert('Too long!');       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; self.val(text.substr(0, maxlength));       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Now, what does that learn us? First, that we didn’t test this good enough. Second, a schemaless database like &lt;a title="RavenDb" href="http://ravendb.net/" target="_blank"&gt;RavenDb&lt;/a&gt; has the &lt;a href="http://petermorlion.blogspot.com/2010/05/data-storage-for-stand-alone-client.html" target="_blank"&gt;advantage&lt;/a&gt; over relational databases. That’s why I’m &lt;a title="Switching from NHibernate to RavenDb" href="http://petermorlion.blogspot.com/2010/06/switching-from-nhibernate-to-ravendb.html" target="_blank"&gt;switching from NHibernate to RavenDb&lt;/a&gt; for my own project.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-5463046194069750224?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/5463046194069750224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=5463046194069750224' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5463046194069750224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5463046194069750224'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/09/multiline-textbox-textarea-and.html' title='Multiline textbox (textarea) and maxLength'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-6298844891811760411</id><published>2010-09-14T18:33:00.001+02:00</published><updated>2010-09-14T18:34:05.963+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iTunes'/><title type='text'>iTunes 10 not playing mp3 files?</title><content type='html'>&lt;p&gt;I recently upgraded to &lt;strong&gt;iTunes 10&lt;/strong&gt; because I was dying to try Ping. Let me rephrase that, I upgraded to iTunes 10 because I hate it but have an iPod, and I do love the Store.&lt;/p&gt;  &lt;p&gt;Anyway after upgrading, I found that &lt;strong&gt;some mp3s couldn’t be played anymore&lt;/strong&gt;. Not in iTunes, nor on my iPod. Googling around only led me to &lt;a href="http://discussions.apple.com/thread.jspa?messageID=12259236" target="_blank"&gt;two&lt;/a&gt;&amp;#160;&lt;a href="http://discussions.apple.com/thread.jspa?messageID=12247447" target="_blank"&gt;discussions&lt;/a&gt; on the Apple forum. But it seems quite some other people are having this problem: the biggest part of your collection will play fine, but some files do absolutely nothing.&lt;/p&gt;  &lt;p&gt;So here is a way to fix it: download &lt;a title="MP3 Validator" href="http://www.gromkov.com/faq/repair/mp3_validator.html" target="_blank"&gt;mp3Validator&lt;/a&gt; and let is scan your broken files. In my case, it found several errors in the files, but it could fix them.&lt;/p&gt;  &lt;p&gt;After that, no need to reimport the files, iTunes 10 just played them nicely again.&lt;/p&gt;  &lt;p&gt;I can’t find any reaction from Apple, which seems logical, but I find it strange that I can’t find any of this in any reviews. Anyway, my guess is that the files were already mucked up (some of my files were ripped years ago), but something changed in iTunes causing it to not play these mp3 files anymore.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-6298844891811760411?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/6298844891811760411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=6298844891811760411' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/6298844891811760411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/6298844891811760411'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/09/itunes-10-not-playing-mp3-files.html' title='iTunes 10 not playing mp3 files?'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-8536922112732682684</id><published>2010-06-11T17:48:00.001+02:00</published><updated>2010-06-14T19:04:41.220+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RavenDB'/><title type='text'>Running RavenDb embedded for .NET 3.5</title><content type='html'>&lt;p&gt;The application I’m developing will be a stand-alone client application. Nothing fancy and business-critical, so RavenDb might be overkill, but I’m attracted to the ease of use. &lt;/p&gt;  &lt;p&gt;The application will be installed by non-technical users, so I’m not too fond of the idea of running RavenDb as a service. This will require the users to enter their Administrator password, which could frighten them. I could choose the embedded option, but as I don’t have &lt;strong&gt;Visual Studio 2010&lt;/strong&gt; yet, I can’t develop for &lt;strong&gt;.NET 4&lt;/strong&gt;. So I want to have a sort of &lt;strong&gt;embedded option&lt;/strong&gt; for &lt;strong&gt;RavenDb &lt;/strong&gt;using &lt;strong&gt;.NET 3.5&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;I want to run &lt;strong&gt;RavenDb in the background&lt;/strong&gt; while my application runs, and shut it down when the user exits the application. Luckily, you can start RavenDb.exe as a &lt;strong&gt;console application&lt;/strong&gt;. But then the user would see a console launching, which I don’t want either.&lt;/p&gt;  &lt;p&gt;So this is what I did.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;public static void StartRavenDb()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var ravenDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, &amp;quot;RavenDb/RavenDb.exe&amp;quot;);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProcessStartInfo startInfo = new ProcessStartInfo(ravenDbPath);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; startInfo.UseShellExecute = false;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; startInfo.CreateNoWindow = true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Process.Start(startInfo);       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="verd"&gt;This starts RavenDb, but &lt;strong&gt;avoids creating a console window&lt;/strong&gt;. When my application stops I can call:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;public static void StopRavenDb()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; System.Diagnostics.Process.GetProcessesByName(&amp;quot;RavenDb&amp;quot;)[0].Kill();       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This could be a problem if RavenDb is already running for another application. First, because you can only start one instance of RavenDb.exe, and then I could be killing the process used by another applicaiton. &lt;/p&gt;  &lt;p&gt;However, the possibility is very low, especially with my target users, but I will have to look into this. One other thing to check is whether this can do any harm, as the console application of RavenDb is meant for debugging purposes.&lt;/p&gt;  &lt;p&gt;UPDATE: I asked Ayende and he was kind enough to answer, saying this is &lt;a href="http://groups.google.com/group/ravendb/browse_thread/thread/4bf4f4a420bc4505" target="_blank"&gt;indeed a viable option&lt;/a&gt;, but I’d better stop the process gracefully instead of killing it.&lt;/p&gt;  &lt;p&gt;UPDATE 2: closing RavenDb is better than killing it, so I changed the StartRavenDb and StopRavenDb methods to:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;public static void StartRavenDb()     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var ravenDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, &amp;quot;RavenDb/RavenDb.exe&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProcessStartInfo startInfo = new ProcessStartInfo(ravenDbPath);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; startInfo.UseShellExecute = false;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; startInfo.CreateNoWindow = true;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; startInfo.RedirectStandardInput = true;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; _ravenDb = Process.Start(startInfo);      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;public static void StopRavenDb()     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var inputStream = _ravenDb.StandardInput;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; inputStream.Write(&amp;quot;\r\n&amp;quot;);      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Apparently, I have to put the result of Process.Start in a variable to keep a reference to it. Also, to avoid the ‘&lt;strong&gt;StandardIn has not been redirected&lt;/strong&gt;’ exception, I have to set the &lt;strong&gt;RedirectStandardInput&lt;/strong&gt; property to true.&lt;/p&gt;  &lt;p&gt;To stop RavenDb, I just send “\r\n” to the standard input of RavenDb. Thanks to Ayende for &lt;a title="Run RavenDb in background, not as service" href="http://groups.google.com/group/ravendb/browse_thread/thread/4bf4f4a420bc4505" target="_blank"&gt;pointing out the obvious&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/4093944831568090072-8536922112732682684?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/8536922112732682684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=8536922112732682684' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8536922112732682684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8536922112732682684'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/06/running-ravendb-only-when-your.html' title='Running RavenDb embedded for .NET 3.5'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-9110420412967878974</id><published>2010-06-02T18:59:00.002+02:00</published><updated>2010-06-08T13:47:41.310+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RavenDB'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>Switching from NHibernate to RavenDB</title><content type='html'>&lt;p&gt;In my previous post, I explained how I went about &lt;a title="Starting with RavenDB" href="http://petermorlion.blogspot.com/2010/05/starting-up-ravendb-with-net-35.html" target="_blank"&gt;starting with RavenDB&lt;/a&gt;. Now I want to continue my &lt;strong&gt;switch from NHibernate to RavenDB&lt;/strong&gt;. The GetAll method was fairly simple. I also have a GetOneById method in my BaseRepository, but, as I’m not using it right now, I decided to remove it (&lt;a title="You ain&amp;#39;t gonna need it" href="http://en.wikipedia.org/wiki/You_ain't_gonna_need_it" target="_blank"&gt;YAGNI&lt;/a&gt; you know).&lt;/p&gt;&lt;p&gt;Then, I changed the my BaseRepository to enforce the T to be a BaseEntity:&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;public class BaseRepository&amp;lt;T&amp;gt; : IBaseRepository&amp;lt;T&amp;gt; where T : BaseEntity&lt;/font&gt;&lt;/p&gt;&lt;p&gt;I thought this would be necessary to check the Id in my SaveOrUpdate method to see if it’s a new object, or one that has already been saved and has to be updated. I found that in Shiju Varghese’s &lt;a title="NoSQL with RavenDB and ASP.NET MVC-Part1" href="http://weblogs.asp.net/shijuvarghese/archive/2010/05/26/nosql-with-ravendb-and-asp-net-mvc-part-1.aspx" target="_blank"&gt;NoSQL with RavenDB and ASP.NET MVC-Part1&lt;/a&gt;. Yet it seems unnecessary. Maybe it’s because he’s working with a web project, but I can just call Store() and SaveChanges() and my object is either saved or updated.&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;public void SaveOrUpdate(T aggregate)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; using (var session = _store.OpenSession())       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.Store(aggregate);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.SaveChanges();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Keep in mind that the objects aren’t persisted until you call SaveChanges(). Also, only then are the Id’s generated for your objects (if it’s an insert). This method is also transactional.&lt;/p&gt;&lt;p&gt;It should be fairly clear by now. My Delete method:&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;public void Delete(T aggregate)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; using (var session = _store.OpenSession())      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.Delete(aggregate);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.SaveChanges();&lt;/font&gt;&lt;font face="Courier New"&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;p&gt;I also had a PersistAll method in my IBaseRepository, which I removed. Must have copied that from the interface at work :)&lt;/p&gt;&lt;p&gt;So that’s about it. My &lt;strong&gt;switch from NHibernate to RavenDB&lt;/strong&gt; was fairly easy thanks to the BaseRepository I’m using (and it’s a fairly simple application at the moment, I admit).&lt;/p&gt;&lt;p&gt;Next up, is seeing if I can run the RavenDB server when my application starts, and stopping it when it exits. Also, I did a LuceneQuery in the GetAll method (see &lt;a title="Starting up RavenDB with .NET 3.5" href="http://petermorlion.blogspot.com/2010/05/starting-up-ravendb-with-net-35.html" target="_blank"&gt;Starting up RavenDB with .NET 3.5&lt;/a&gt;), but I want to check out &lt;a title="Raven DB Documentation" href="http://ravendb.net/documentation" target="_blank"&gt;RavenDB’s indexes&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Now, compare this piece of code, with what you get when you use NHibernate. The BaseRepository for NHibernate might not differ that much, but you need the configuration, the mapping files, the database, … With RavenDB, I just need RavenDB and my BaseRepository. RavenDB takes care of the persistence for you, so you can concentrate on your application. That’s what I’m looking for in a persistence framework.&lt;/p&gt;&lt;p&gt;This is my BaseRepository now:&lt;/p&gt;&lt;p&gt;public class BaseRepository&amp;lt;T&amp;gt; : IBaseRepository&amp;lt;T&amp;gt; where T : BaseEntity   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private IDocumentStore _store; &lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; protected BaseRepository()   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _store = new DocumentStore { Url = @&amp;quot;&lt;a href="http://localhost:8080&amp;quot;"&gt;http://localhost:8080&amp;quot;&lt;/a&gt; };    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _store.Initialise();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public IList&amp;lt;T&amp;gt; GetAll()   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; using (var session = _store.OpenSession())    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return session.LuceneQuery&amp;lt;T&amp;gt;().ToList();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public void SaveOrUpdate(T aggregate)   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; using (var session = _store.OpenSession())    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.Store(aggregate);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.SaveChanges();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public void Delete(T aggregate)   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; using (var session = _store.OpenSession())    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.Delete(aggregate);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.SaveChanges();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;Yes, the url of the documentstore shouldn’t be hard-coded, but that’s on my todo-list.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-9110420412967878974?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/9110420412967878974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=9110420412967878974' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/9110420412967878974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/9110420412967878974'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/06/switching-from-nhibernate-to-ravendb.html' title='Switching from NHibernate to RavenDB'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-7718505325676165260</id><published>2010-05-27T21:27:00.003+02:00</published><updated>2010-06-08T13:48:06.923+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RavenDB'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>Starting up RavenDB with .NET 3.5</title><content type='html'>&lt;p&gt;The application I’m writing isn’t in a very far stadium yet, but I do have some implementation of repositories using &lt;strong&gt;NHibernate&lt;/strong&gt;. Now I want to switch to &lt;strong&gt;RavenDB&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;So I &lt;a title="RavenDB download" href="http://builds.hibernatingrhinos.com/builds/ravendb" target="_blank"&gt;downloaded RavenDB&lt;/a&gt; (the latest build at this time – build 81) and unzipped it. I wanted to follow the &lt;strong&gt;RavenDB&lt;/strong&gt; &lt;a title="RavenDB Hello World tutorial" href="http://ravendb.net/tutorials/hello-world" target="_blank"&gt;Hello World tutorial&lt;/a&gt;, but soon found out its built for .NET 4.&lt;/p&gt;&lt;p&gt;I don’t have .NET 4 or Visual Studio 2010 yet, but luckily there’s a client for .NET 3.5. I removed all NHibernate references and added one to Raven.Client-3.5.dll in m Dal project.&lt;/p&gt;&lt;p&gt;You’re sort of screwed if you only have Visual Studio 2008 and .NET 3.5 installed. I wanted to use it as an embedded client, but that’s .NET 4.0 only at the moment.&lt;/p&gt;&lt;p&gt;So I started up the server (check the &lt;a title="RavenDB Hello World" href="http://ravendb.net/tutorials/hello-world" target="_blank"&gt;RavenDB Hello World&lt;/a&gt; for more info) and surfed to http://localhost:8080 and all looks well.&lt;/p&gt;&lt;p&gt;On of the first things I did, was change the type of the Id properties of my domain objects from a Guid to a string (which was a good moment to introduce a BaseEntity of which other classes can derive). According to the &lt;a title="RavenDB Hello World" href="http://ravendb.net/tutorials/hello-world" target="_blank"&gt;RavenDB Hello World&lt;/a&gt;, this is configurable, but I can’t be bothered right now to find out.&lt;/p&gt;&lt;p&gt;I have a BaseRepository that implements the following interface:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: courier new"&gt;public interface IBaseRepository&amp;lt;T&amp;gt;      &lt;br /&gt;{&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; T GetOneById(Guid id);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; IList&amp;lt;T&amp;gt; GetAll();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SaveOrUpdate(T aggregate);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void Delete(T aggregate);       &lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Other repositories inherit from the BaseRepository, and, through their interface, only expose their relevant methods:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: courier new"&gt;public class PatientRepository : BaseRepository&amp;lt;Patient&amp;gt;, IPatientRepository      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public PatientRepository(string connectionStringName) : base(connectionStringName)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Let’s start with the &lt;span style="font-family: courier new"&gt;GetAll &lt;/span&gt;method. This is the NHibernate way:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: courier new"&gt;public IList&amp;lt;T&amp;gt; GetAll()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ICriteria criteria = Session.CreateCriteria(typeof (T));       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return criteria.List&amp;lt;T&amp;gt;();       &lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;In the constructor of my BaseRepository, I create an IDocumentStore (an expensive thing to do):&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: courier new"&gt;_store = new DocumentStore { Url = @&amp;quot;D:\data&amp;quot; };      &lt;br /&gt;_store.Initialise();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Then my method creates a session (a cheap thing to do):&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: courier new"&gt;public IList&amp;lt;T&amp;gt; GetAll()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; using (var session = _store.OpenSession())       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return session.LuceneQuery&amp;lt;T&amp;gt;().ToList();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;I put all my other methods in comment, and everything builds and the application works!&lt;/p&gt;&lt;p&gt;I am using the LuceneQuery because the normal Query() method needs an index, which I don’t have yet. I’m still researching how to do this in the best way.&lt;/p&gt;&lt;p&gt;There’s the DocumentStore.DatabaseCommands.PutIndex method (I found a good example on &lt;a href="http://codeofrob.com/archive/2010/05/09/ravendb-an-introduction.aspx" target="_blank"&gt;Rob Ashtons blog&lt;/a&gt;), but that would execute everytime my application runs. Or you can check out the &lt;a title="RavenDB documentation on indexes" href="http://ravendb.net/documentation/docs-http-indexes-querying" target="_blank"&gt;RavenDB documentation on indexes&lt;/a&gt;, but that seems overly complicated.&lt;/p&gt;&lt;p&gt;Next post should be something on switching from NHibernate to RavenDB, but now it’s time for my couch.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-7718505325676165260?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/7718505325676165260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=7718505325676165260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/7718505325676165260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/7718505325676165260'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/05/starting-up-ravendb-with-net-35.html' title='Starting up RavenDB with .NET 3.5'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-7797050276170498488</id><published>2010-05-20T19:42:00.001+02:00</published><updated>2010-05-20T19:43:06.931+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='RavenDB'/><title type='text'>Data storage for a stand-alone client application</title><content type='html'>&lt;p&gt;I’m developing a stand-alone &lt;strong&gt;client application&lt;/strong&gt; that will be able to store a fair amount of data. No client-server stuff, just plain old open-the-application-change-the-data-save-close. I need a good way to store the data and, traditionally, developers look at &lt;strong&gt;SQL&lt;/strong&gt; databases for data storage. But I’m thinking this will make it overly complex. A search for &lt;strong&gt;alternatives&lt;/strong&gt; starts.&lt;/p&gt;  &lt;p&gt;The application is for the administration of a speech therapist. It should have the patients, appointments, documents, etc. But also more complex business logic such as calculating payments for patients (which in Belgian social security can be complex), calculating how many more session (appointments) a patient can have (which can be, but isn’t always, legally regulated), etc. So just an Excel file or an Access database won’t do. And besides, I’m a &lt;strong&gt;.NET&lt;/strong&gt; developer.&lt;/p&gt;  &lt;p&gt;So you’d take a SQL database right? With the compact edition, no? And, being all up-to-date on our developing skills, use &lt;strong&gt;NHibernate&lt;/strong&gt;! Well, I’ve been reading the &lt;a title="That No SQL thing" href="http://ayende.com/Blog/archive/2010/03/27/that-no-sql-thing.aspx" target="_blank"&gt;No SQL posts by Ayende&lt;/a&gt; with much interest (and some other blogs too), and it hit me that the whole SQL and mapping files thing is quite complex.&lt;/p&gt;  &lt;p&gt;I know there a lot of info out there on how to use NHibernate, but I must say, it stays kind of hard to do it right. You always get into trouble using collections, you have to make compromises in your domain, there’s all sorts of best ways to manage your sessions, etc. Being a developer, and not a database specialist, I won’t to write code, instead of having to hassle with data storage details.&lt;/p&gt;  &lt;p&gt;Why not go old school, and save your objects to &lt;strong&gt;file&lt;/strong&gt; (binary or xml)? I could do that, but I don’t have any experience with doing this on a lot of objects, objects that hold other objects, I don’t know how this affects performance, …&lt;/p&gt;  &lt;p&gt;So I did start looking for object databases or document databases. &lt;a title="db4o object database" href="http://www.db4o.com/" target="_blank"&gt;db4o&lt;/a&gt; looked promising and I must look into it further. I first discarded it as an option due to licensing (I might go commercial with my application if all goes well). I checked other options like the most known ones: &lt;a title="MongoDB" href="http://www.mongodb.org/" target="_blank"&gt;MongoDB&lt;/a&gt;, &lt;a title="CouchDB" href="http://couchdb.apache.org/" target="_blank"&gt;CouchDB&lt;/a&gt;, but they seemed quite complex also, in part because they’re not targeting the .NET platform.&lt;/p&gt;  &lt;p&gt;So I ended up choosing &lt;a title="RavenDB" href="http://ravendb.net/" target="_blank"&gt;RavenDB&lt;/a&gt;, which has a paying license for commercial applications also, like db4o. But I haven’t gone into the details of the licensing yet, so I couldn’t tell you the difference. Maybe I didn’t give db4o a decent chance, but I’m going to try &lt;strong&gt;RavenDB&lt;/strong&gt; now anyway.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-7797050276170498488?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/7797050276170498488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=7797050276170498488' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/7797050276170498488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/7797050276170498488'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/05/data-storage-for-stand-alone-client.html' title='Data storage for a stand-alone client application'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-8023822165046268166</id><published>2010-04-16T09:18:00.007+02:00</published><updated>2010-04-20T18:49:36.998+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xsl'/><title type='text'>Pagenumbers like 'page 3 of 10' with XSL-FO</title><content type='html'>Using &lt;b&gt;xsl-fo&lt;/b&gt; to generate PDFs, and you want to display the &lt;b&gt;pagenumbers &lt;/b&gt;like 'page 3 of 10'? It isn't too hard. Just add this to the footer of your pages:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Page &amp;lt;fo:page-number&amp;gt; of &amp;lt;fo:page-number-citation id="last-page"&gt;&amp;lt;/fo:page-number-citation&amp;gt;&amp;lt;/fo:page-number&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then, make sure you have the following at the end of your document (so, on the last page):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&amp;lt;fo:block id="last-page"&amp;gt;&amp;lt;/fo:block&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-8023822165046268166?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/8023822165046268166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=8023822165046268166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8023822165046268166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8023822165046268166'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/04/pagenumbers-like-page-3-of-10-with-xsl.html' title='Pagenumbers like &apos;page 3 of 10&apos; with XSL-FO'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-144596198834823637</id><published>2010-03-25T18:49:00.018+01:00</published><updated>2010-05-21T13:35:50.460+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Git'/><title type='text'>Git, TortoiseGit and (Putty) SSH keys for Windows</title><content type='html'>&lt;div style="TEXT-ALIGN: left"&gt;Okay, I finally got Git to work. Here's the necessary steps, after having installed msysgit and TortoiseGit.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;First, create the local repository.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6ukF-ICZuI/AAAAAAAAAFU/2LJIe3p92q8/s1600/Git+Create+Repository.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 170px; DISPLAY: block; HEIGHT: 320px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452632196345128674" border="0" alt="" src="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6ukF-ICZuI/AAAAAAAAAFU/2LJIe3p92q8/s320/Git+Create+Repository.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You'll get a notification that an empty repository was created. You can now use the repository to track your changes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(0,0,238); -webkit-text-decorations-in-effect: underline" class="Apple-style-span"&gt;&lt;span style="COLOR: rgb(0,0,0)" class="Apple-style-span"&gt;&lt;a href="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6uk4dJ8d3I/AAAAAAAAAFk/OJQoHs6mlyE/s1600/Git+Commit+To+Master.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 151px; DISPLAY: block; HEIGHT: 320px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452633063668086642" border="0" alt="" src="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6uk4dJ8d3I/AAAAAAAAAFk/OJQoHs6mlyE/s320/Git+Commit+To+Master.png" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 234px; DISPLAY: block; HEIGHT: 320px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452632451415574498" border="0" alt="" src="http://1.bp.blogspot.com/_nJPIQzt8vNY/S6ukU0Vkh-I/AAAAAAAAAFc/mR2PMAAtDgk/s320/Git+First+Commit.PNG" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(0,0,238); -webkit-text-decorations-in-effect: underline" class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(0,0,238); -webkit-text-decorations-in-effect: underline" class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;But of course, you want to push this stuff to a server, as backup, because other people will collaborate on your project, etc. I'm using &lt;a href="http://www.unfuddle.com/"&gt;Unfuddle&lt;/a&gt; so I'll concentrate on that (check out &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; for info on &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Create a new Project in Unfuddle. Then, create a new repository and associate the repository to the project. Remember to choose Git as repository type.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_nJPIQzt8vNY/S6ums5QJbOI/AAAAAAAAAFs/7fFgMzpXdx0/s1600/Unfuddle+create+repository.PNG"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 213px; DISPLAY: block; HEIGHT: 188px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452635064075119842" border="0" alt="" src="http://2.bp.blogspot.com/_nJPIQzt8vNY/S6ums5QJbOI/AAAAAAAAAFs/7fFgMzpXdx0/s320/Unfuddle+create+repository.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;Now you need to generate a public SSH key to authenticate yourself. If you installed TortoiseGit, you should have Puttygen installed too. Open it and generate a private and a public key.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6unqLCpj4I/AAAAAAAAAF0/0AxUjU9J8uc/s1600/puttygen.PNG"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 308px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452636116822364034" border="0" alt="" src="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6unqLCpj4I/AAAAAAAAAF0/0AxUjU9J8uc/s320/puttygen.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;Save the public key and the private key with the same filename, the only difference is that the private key should have a .ppk file extension. Also, copy the public key in the top part of the Putty Key Generator.&lt;br /&gt;Now, in the Personal Settings of your Unfuddle account, create a new key and paste it accordingly.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_nJPIQzt8vNY/S6uoWY1L8mI/AAAAAAAAAF8/QFyZzjzvS40/s1600/Unfuddle+putty+key.PNG"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 124px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452636876438237794" border="0" alt="" src="http://2.bp.blogspot.com/_nJPIQzt8vNY/S6uoWY1L8mI/AAAAAAAAAF8/QFyZzjzvS40/s320/Unfuddle+putty+key.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;Now right-click on your local Git repository and choose 'Settings'. Go to the 'Remote' node and choose 'Add New'. Give it a name (TortoiseGit will suggest 'remote') and paste the URL you can find in Unfuddle. Point TortoiseGit to the correct (private) putty key.&lt;br /&gt;&lt;div style="TEXT-ALIGN: center"&gt;&lt;span class="Apple-style-span"  style="color:#0000ee;"&gt;&lt;u&gt;&lt;span style="COLOR: rgb(0,0,0); -webkit-text-decorations-in-effect: none" class="Apple-style-span"&gt;&lt;a href="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6xoACNwZzI/AAAAAAAAAGs/dEDDjjf_p8c/s1600/Unfuddle+URL.PNG"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 301px; DISPLAY: block; HEIGHT: 76px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452847598642685746" border="0" alt="" src="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6xoACNwZzI/AAAAAAAAAGs/dEDDjjf_p8c/s320/Unfuddle+URL.PNG" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#0000ee;"&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;&lt;a href="http://1.bp.blogspot.com/_nJPIQzt8vNY/S6upm-vUHZI/AAAAAAAAAGM/GI9pbCG0lxs/s1600/TortoiseGit+remote.PNG"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 161px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452638261003689362" border="0" alt="" src="http://1.bp.blogspot.com/_nJPIQzt8vNY/S6upm-vUHZI/AAAAAAAAAGM/GI9pbCG0lxs/s320/TortoiseGit+remote.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;Now you have one more thing to do. Start Pageant (C:\Program Files\TortoiseGit\bin\pageant.exe) if it hasn't already started, and add the private key you made a few steps earlier.&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_nJPIQzt8vNY/S6uqVAOIrQI/AAAAAAAAAGU/oJGVVzQZiYc/s1600/pageant.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 227px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452639051675380994" border="0" alt="" src="http://2.bp.blogspot.com/_nJPIQzt8vNY/S6uqVAOIrQI/AAAAAAAAAGU/oJGVVzQZiYc/s320/pageant.png" /&gt;&lt;/a&gt;&lt;br /&gt;That's it! You can now right-click on your local repository and choose to Push to push your changes to Unfuddle.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6urJBwRvII/AAAAAAAAAGc/fYMQyRvpYDM/s1600/Git+push+to+master.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 245px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452639945440214146" border="0" alt="" src="http://3.bp.blogspot.com/_nJPIQzt8vNY/S6urJBwRvII/AAAAAAAAAGc/fYMQyRvpYDM/s320/Git+push+to+master.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_nJPIQzt8vNY/S6urdhUgrZI/AAAAAAAAAGk/cIecOYsxqq4/s1600/Git+pushed.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 214px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5452640297511071122" border="0" alt="" src="http://4.bp.blogspot.com/_nJPIQzt8vNY/S6urdhUgrZI/AAAAAAAAAGk/cIecOYsxqq4/s320/Git+pushed.png" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-144596198834823637?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/144596198834823637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=144596198834823637' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/144596198834823637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/144596198834823637'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2010/03/okay-i-finally-got-git-to-work.html' title='Git, TortoiseGit and (Putty) SSH keys for Windows'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_nJPIQzt8vNY/S6ukF-ICZuI/AAAAAAAAAFU/2LJIe3p92q8/s72-c/Git+Create+Repository.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-331856632408394782</id><published>2009-10-09T22:11:00.002+02:00</published><updated>2009-10-09T22:23:23.553+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Git'/><title type='text'>Git and SSH keys</title><content type='html'>&lt;b&gt;Git&lt;/b&gt; can be quite confusing in the beginning, especially coming from a subversion background. But once you've got it running, you realize it's quite easy:&lt;div&gt;&lt;ul&gt;&lt;li&gt;install &lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt;&lt;/li&gt;&lt;li&gt;optionally install something like &lt;a href="http://code.google.com/p/tortoisegit/"&gt;TortoiseGit&lt;/a&gt;&lt;/li&gt;&lt;li&gt;now you need to create an SSH key, which is explained on the TortoiseGit site for Linux, but for Windows, it's a little harder:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;open command prompt and navigate to where msysgit is installed&lt;/li&gt;&lt;li&gt;enter the following command: ssh-keygen.exe -t rsa&lt;/li&gt;&lt;li&gt;(use /? to see more info)&lt;/li&gt;&lt;li&gt;enter your passphrase and the location to save the key file (passphrase = password)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;now you probably need to enter your public key somewhere (like in the personal settings part of &lt;a href="http://unfuddle.com"&gt;Unfuddle&lt;/a&gt;). Open your public keyfile (i.e. key.pub) in a text editor and copy-paste it.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-331856632408394782?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/331856632408394782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=331856632408394782' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/331856632408394782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/331856632408394782'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2009/10/git-and-ssh-keys.html' title='Git and SSH keys'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-2604759879800219721</id><published>2009-07-15T13:03:00.004+02:00</published><updated>2010-05-21T13:38:15.187+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><title type='text'>Tortoise SVN and Visual Studio</title><content type='html'>Using &lt;a href="http://tortoisesvn.tigris.org/"&gt;TortoiseSVN&lt;/a&gt; (or just looking for &lt;strong&gt;SVN integration with Visual Studio&lt;/strong&gt;)? Check out &lt;a href="http://garrys-brain.blogspot.com/2007/07/tortoisesvn-and-visual-studio.html"&gt;this site&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-2604759879800219721?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/2604759879800219721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=2604759879800219721' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/2604759879800219721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/2604759879800219721'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2009/07/tortoise-svn-and-visual-studio.html' title='Tortoise SVN and Visual Studio'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-4090153531106810974</id><published>2009-03-07T10:41:00.003+01:00</published><updated>2009-03-07T11:06:01.967+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='F#'/><title type='text'>Great F# tutorial</title><content type='html'>Looking for &lt;strong&gt;a good F# tutorial &lt;/strong&gt;to figure out what the hype is all about? Check out the &lt;a href="http://www.gotnet.biz/Blog/post/Kevin-Hazzards-Exploring-the-FSharp-Language-Series-Part1-What-is-FSharp.aspx"&gt;excellent F# series&lt;/a&gt; on Kevin Hazzard's blog. Maybe a little out-dated when you're using the September 2008 CTP of F# (there's no add-in anymore, and the command mentioned in part 2 has a different name - just search for 'send'), but finally a tutorial that explains it step by step.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-4090153531106810974?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/4090153531106810974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=4090153531106810974' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/4090153531106810974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/4090153531106810974'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2009/03/great-f-tutorial.html' title='Great F# tutorial'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-6737162679999368783</id><published>2009-02-23T20:51:00.003+01:00</published><updated>2009-02-23T20:58:59.852+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVVM'/><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>WPF, NHibernate and the Model-View-ViewModel design pattern (MVVM)</title><content type='html'>WPF creates a whole new range of possibilities, but you can often run into trouble when trying to combine it with NHibernate. NHibernate can't handle &lt;strong&gt;ObservableCollections*&lt;/strong&gt;, which is a quite handy feature of WPF. Furthermore, what to do with the good databinding capabilities of WPF?&lt;br /&gt;Shawn Duggan provides a nice solution using the &lt;strong&gt;Model-View-ViewModel &lt;/strong&gt;pattern &lt;a href="http://www.shawnduggan.com/?p=46=1"&gt;here&lt;/a&gt;. Check out this recent article by Josh Smith for &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;a good introduction of the MVVM design pattern&lt;/a&gt; (with an easy-to-follow example).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* it is possible to work with NHibernate and ObservableCollections without the MVVM pattern, by either creating your own NHibernate collection class, or by creating a wrapper around ObservableCollection. I find the solution presented by Shawn Duggan to be the most elegant, because it combines it with the MVVM pattern.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-6737162679999368783?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/6737162679999368783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=6737162679999368783' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/6737162679999368783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/6737162679999368783'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2009/02/wpf-nhibernate-and-model-view-viewmodel.html' title='WPF, NHibernate and the Model-View-ViewModel design pattern (MVVM)'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-2247974056604478217</id><published>2008-09-13T11:17:00.002+02:00</published><updated>2010-05-21T13:38:55.711+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><title type='text'>Creating applications with adsutil.vbs</title><content type='html'>&lt;p&gt;There's lots of information out there on &lt;a href="http://community.acresso.com/archive/index.php?t-128564.html" target="_blank"&gt;how to create a virtual directory in IIS with adsutil.vbs&lt;/a&gt;. But when you need an &lt;strong&gt;application&lt;/strong&gt;, like for an &lt;strong&gt;ASP.NET website&lt;/strong&gt;, you need one more step which I had some trouble finding.&lt;/p&gt;&lt;p&gt;Adsutil.vbs is a script to manage IIS from the commandline. If you're using IIS6 you can use other scripts like &lt;a href="http://technet.microsoft.com/en-us/library/cc736889.aspx" target="_blank"&gt;iisvdir.vbs&lt;/a&gt; and &lt;a href="http://technet.microsoft.com/en-us/library/cc739153.aspx" target="_blank"&gt;iisweb.vbs&lt;/a&gt;. But for &lt;strong&gt;IIS5&lt;/strong&gt;, these aren't available, so you have to &lt;strong&gt;use adsutil.vbs instead&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Here's the three commands necessary:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;cscript %SystemDrive%\Inetpub\AdminScripts\AdsUtil.vbs create w3svc/1/root/myApp "IisWebVirtualDir"&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;cscript %SystemDrive%\Inetpub\AdminScripts\AdsUtil.vbs appcreateinproc w3svc/1/root/myApp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;cscript %SystemDrive%\Inetpub\AdminScripts\AdsUtil.vbs set w3svc/1/root/myApp\path "D:\MyWebsite"&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The first step creates a virtual directory under IIS. The virtual directory is named 'myApp' in this case and is of the keytype 'IisWebVirtualDir' (I haven't found a resource on keytypes yet, so it's the only type I know).&lt;/p&gt;&lt;p&gt;The second step creates an (in process) application from that virtual directory.&lt;/p&gt;&lt;p&gt;The last step sets the path to content somewhere on the filesystem.&lt;/p&gt;&lt;p&gt;After that, the site is accessible through http://localhost/myApp.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-2247974056604478217?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/2247974056604478217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=2247974056604478217' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/2247974056604478217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/2247974056604478217'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/09/creating-applications-with-adsutilvbs.html' title='Creating applications with adsutil.vbs'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-8456211326271769529</id><published>2008-08-19T22:55:00.003+02:00</published><updated>2010-05-21T13:38:01.385+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Everyone does Agile Software Development</title><content type='html'>&lt;p&gt;Ok, not everyone does, but you have to admit it's a trend in the software development world and a good one for that. But if you're already developing in an agile manner or plan to, take 5 minutes to stop reading about scrum, TDD, XP and other Agile methods and check out the basics.&lt;/p&gt;&lt;p&gt;In other words, read the &lt;a href="http://www.agilemanifesto.org/" target="_blank"&gt;Agile Manifesto&lt;/a&gt;, and see &lt;strong&gt;why&lt;/strong&gt; we're doing &lt;strong&gt;agile software development&lt;/strong&gt;. Also, be sure to read the &lt;a href="http://www.agilemanifesto.org/principles.html" target="_blank"&gt;twelve principles behind the manifesto&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It's a short but interesting read which anyone who says he/she's doing Agile should read.&lt;/p&gt;&lt;p&gt;Edit: on a related note, &lt;a href="http://www.objectmentor.com/omTeam/martin_r.html" target="_blank"&gt;Robert Martin&lt;/a&gt; (AKA Uncle Bob) proposed a new value for the Agile Manifesto: &lt;a href="http://blog.objectmentor.com/articles/2008/08/14/quintessence-the-fifth-element-for-the-agile-manifesto" target="_blank"&gt;Craftsmanship over Execution&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/4093944831568090072-8456211326271769529?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/8456211326271769529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=8456211326271769529' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8456211326271769529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8456211326271769529'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/08/everyone-does-agile-software.html' title='Everyone does Agile Software Development'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-8808803150471544780</id><published>2008-06-01T12:18:00.003+02:00</published><updated>2010-09-14T18:43:30.794+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Icons for your applications</title><content type='html'>Looking for good &lt;span style="font-weight: bold;"&gt;icons&lt;/span&gt; for your applications, that &lt;span style="font-weight: bold;"&gt;blend in well&lt;/span&gt; with other typical Windows applications? If you have Visual Studio, then you already have &lt;span style="font-weight: bold;"&gt;1000+ icons&lt;/span&gt; without having to Google for 'free icons' and coming up with loads of unusable previews.&lt;br /&gt;Navigate to your Visual Studio install directory and in \Common7\VS2008ImageLibrary you'll find a zip file VS2008ImageLibrary.zip. Extract that and you've got a whole set of icons you can use in your application. In each folder there's a read-me with an overview of all the icons in that folder.&lt;br /&gt;This should satifsy most of your needs and it all has a consistent look.&lt;br /&gt;&lt;br /&gt;More info &lt;a href="http://msdn.microsoft.com/en-us/library/ms246582.aspx"&gt;here&lt;/a&gt; (VS2008) and &lt;a href="http://msdn.microsoft.com/en-us/library/ms247035%28VS.80%29.aspx"&gt;here&lt;/a&gt; (VS2005).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-8808803150471544780?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/8808803150471544780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=8808803150471544780' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8808803150471544780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8808803150471544780'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/06/icons-for-your-applications.html' title='Icons for your applications'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-6720816597748264045</id><published>2008-05-18T15:52:00.011+02:00</published><updated>2010-09-14T18:43:22.579+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>WPF Databinding to Controls with ValueConverter</title><content type='html'>I'm a fan of the MVP design pattern, so &lt;span style="font-weight: bold;"&gt;databinding &lt;/span&gt;isn't something I would use very often, but I have found a use for it in &lt;span style="font-weight: bold;"&gt;WPF&lt;/span&gt;. It is very easy to &lt;span style="font-weight: bold;"&gt;databind one Control to the other&lt;/span&gt;. This gives us some interesting possibilities.&lt;br /&gt;For a standard example, check out &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=276212"&gt;this screencast&lt;/a&gt;. What I want to show here is how you can extend this with &lt;span style="font-weight: bold;"&gt;ValueConverters&lt;/span&gt;.&lt;br /&gt;In a project of mine, I needed to show a control depending on the checked status of a RadioButton. More specifically, I needed to databind the Visibility of a Grid to the Checked property of a RadioButton. The problem is Visibility is an enumeration (Hidden, Visible, or Collapsed) and Checked is a Boolean, so this &lt;span style="font-weight: bold;"&gt;doesn't databind just like that&lt;/span&gt;.&lt;br /&gt;Luckily, there are ValueConverters: these just convert one value to another. There are a number of built-in ValueConverters, but you can also build your own. This is quite easy, but more on that later.&lt;br /&gt;&lt;br /&gt;Focussing on my example with visibility, to &lt;span style="font-weight: bold;"&gt;databind with a ValueConverter &lt;/span&gt;in Blend, select the control you want to make (in)visible and click on the Advanced Property Options next to the Visibility Property:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nJPIQzt8vNY/SDBZnmPePlI/AAAAAAAAABc/NHiLgcQ20Sk/s1600-h/wpf-databinding-valueconverter.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_nJPIQzt8vNY/SDBZnmPePlI/AAAAAAAAABc/NHiLgcQ20Sk/s320/wpf-databinding-valueconverter.jpg" alt="" id="BLOGGER_PHOTO_ID_5201756106428137042" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Choose 'Data Binding...'&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nJPIQzt8vNY/SDBZ62PePmI/AAAAAAAAABk/Ktijwa9DHL0/s1600-h/databinding-expression-blend.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_nJPIQzt8vNY/SDBZ62PePmI/AAAAAAAAABk/Ktijwa9DHL0/s320/databinding-expression-blend.jpg" alt="" id="BLOGGER_PHOTO_ID_5201756437140618850" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Select the 'Element Property' tab at the top of the new window. You will see your controls in a treeview to the left. Select the control you want to databind to (in our example: a RadioButton). In the right part of the window, you'll see the properties you can choose from. To get the IsChecked property, select 'All Properties' in the 'Show' listbox (bottom right). Select the IsChecked property:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nJPIQzt8vNY/SDBaE2PePnI/AAAAAAAAABs/8pxthZOleoM/s1600-h/DataBinding-Element-Property.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_nJPIQzt8vNY/SDBaE2PePnI/AAAAAAAAABs/8pxthZOleoM/s320/DataBinding-Element-Property.jpg" alt="" id="BLOGGER_PHOTO_ID_5201756608939310706" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Now all we need is a &lt;span style="font-weight: bold;"&gt;ValueConverter&lt;/span&gt;. Slide out the bottom part of this windows by clicking on the arrow. In het bottom left, you'll see a ListBox for ValueConverter. If the BooleanToVisibilityConverter isn't in the list yet, click on the '...' button, and select it:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nJPIQzt8vNY/SDBaMmPePoI/AAAAAAAAAB0/1h_fxDYo74s/s1600-h/BooleanToVisibilityConverter.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_nJPIQzt8vNY/SDBaMmPePoI/AAAAAAAAAB0/1h_fxDYo74s/s320/BooleanToVisibilityConverter.jpg" alt="" id="BLOGGER_PHOTO_ID_5201756742083296898" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;That's all there's to it. Repeat for other Controls and RadioButtons, and your GUI will change according to the selected RadioButtons.&lt;br /&gt;&lt;br /&gt;Don't use this for too many controls though, as they are still loaded, they're just not visible. But it does show how WPF Controls can be databound to others.&lt;img src="file:///C:/DOCUME%7E1/PETERM%7E1/LOCALS%7E1/Temp/moz-screenshot-3.jpg" alt="" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-6720816597748264045?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/6720816597748264045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=6720816597748264045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/6720816597748264045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/6720816597748264045'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/05/wpf-databinding-to-controls-with.html' title='WPF Databinding to Controls with ValueConverter'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_nJPIQzt8vNY/SDBZnmPePlI/AAAAAAAAABc/NHiLgcQ20Sk/s72-c/wpf-databinding-valueconverter.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-3974847769073106753</id><published>2008-04-30T18:19:00.003+02:00</published><updated>2010-09-14T18:43:14.912+02:00</updated><title type='text'>Turnover in the IT world</title><content type='html'>I haven't had a lot of time recently, so just a link to an interesting article about &lt;a href="http://thedailywtf.com/Articles/Up-or-Out-Solving-the-IT-Turnover-Crisis.aspx"&gt;turnover in the IT business&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-3974847769073106753?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/3974847769073106753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=3974847769073106753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/3974847769073106753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/3974847769073106753'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/04/turnover-in-it-world.html' title='Turnover in the IT world'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-942754718628964159</id><published>2008-04-09T12:11:00.003+02:00</published><updated>2010-06-08T13:48:46.840+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>NHibernate Intellisense for Visual Studio 2008</title><content type='html'>Want &lt;span style="font-weight: bold;"&gt;intellisense for NHibernate&lt;/span&gt; in Visual Studio 2008? It's easy, just download the NHibernate source &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=73818&amp;amp;package_id=73969"&gt;here&lt;/a&gt;, and extract it somewhere. Go to the src/NHibernate folder and copy the following files:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;nhibernate-configuration.xsd&lt;/li&gt;&lt;li&gt;nhibernate-mapping.xsd&lt;/li&gt;&lt;li&gt;nhibernate-generic.xsd&lt;/li&gt;&lt;/ul&gt;Paste these files in the Xml/Schemas folder of your &lt;span style="font-weight: bold;"&gt;VS2008 &lt;/span&gt;installation folder. Usually this will be C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-942754718628964159?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/942754718628964159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=942754718628964159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/942754718628964159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/942754718628964159'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/04/nhibernate-intellisense-for-visual.html' title='NHibernate Intellisense for Visual Studio 2008'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-1847858098950698358</id><published>2008-02-21T18:54:00.002+01:00</published><updated>2008-02-21T19:17:07.655+01:00</updated><title type='text'>Microsoft opening up?</title><content type='html'>Microsoft has a history and/or image of being a competition-crushing behemoth, with a not-so-open attitude. And I mean open in a general way: they're not into open source or open standards, giving away stuff for free, contributing to the community, etc.&lt;br /&gt;Yet one might think they're &lt;span style="font-weight: bold;"&gt;opening up&lt;/span&gt; lately. The deal with Novell was controversial to say the least, but it showed they've at least started noticing Linux. The Express Editions of their development tools were an attempt to bind more students to their technologies, but now they're &lt;a href="https://downloads.channel8.msdn.com/"&gt;starting to give the full (professional) editions away for free&lt;/a&gt;! Apart from that, there's also the &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/03/releasing-the-source-code-for-the-net-framework-libraries.aspx"&gt;releasing of the .NET source code&lt;/a&gt;, and the whole &lt;a href="http://www.codeplex.com"&gt;Codeplex community&lt;/a&gt;, which shows Microsoft is starting to see the value of a community.&lt;br /&gt;Of course, all this could be (and probably is) part of a bigger campaign &lt;span style="font-weight: bold;"&gt;to stay ahead of competition &lt;/span&gt;and to get people to use and like their products. But in the grand picture, I believe Microsoft is losing some of it's big mean corporate doings. Although it would be naive to think they will open up fully. Maybe in a few years from now, the pendulum will swing the other way, who knows. And let's not forget the whole &lt;a href="http://www.theregister.co.uk/2008/02/08/ooxml_eu_probe_iso/"&gt;OOXML - ODF debacle&lt;/a&gt;.&lt;br /&gt;Anyway, latest news is that Microsoft is &lt;a href="http://www.theregister.co.uk/2008/02/21/microsoft_goes_open/"&gt;opening their protocols and APIs&lt;/a&gt;, which is definitely a step we wouldn't have expected even a year ago. It remains to be seen, of course, whether or not there's a catch somewhere, but it's a good step for many developers, I believe.&lt;br /&gt;&lt;a href="http://www.theregister.co.uk/2008/02/21/microsoft_goes_api_mad/"&gt;The Register sums it&lt;/a&gt; up fairly well: "All in all, it's funny to see how slowly a company like Microsoft moves. It was engaging in public debates about the evils of the GPL and funding SCO a few years ago. Now Microsoft has awoken to the notion that it can ride the free publicity happiness train just by seeming less rigid."&lt;br /&gt;&lt;br /&gt;But anyway, if we can get free stuff out of it, we will! So, if you're a student somewhere, go check out the &lt;a href="https://downloads.channel8.msdn.com/"&gt;DreamSpark site&lt;/a&gt;, for &lt;span style="font-weight: bold;"&gt;free MS development tools&lt;/span&gt;. Yes, you have to be a student, they're not going to play Santa Claus now, will they.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-1847858098950698358?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/1847858098950698358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=1847858098950698358' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/1847858098950698358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/1847858098950698358'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/02/microsoft-opening-up.html' title='Microsoft opening up?'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-8745322133964840966</id><published>2008-02-19T18:09:00.004+01:00</published><updated>2010-09-14T18:43:08.893+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>Exporting a asp.net gridview to Excel</title><content type='html'>I was looking for a way to &lt;span style="font-weight: bold;"&gt;export a gridview of an asp.net site to an Excel-file&lt;/span&gt; (.xls). Most methods I found involved overriding a Page-method and/or disabling validation of the controls. The &lt;a href="http://mattberseth.com/blog/2007/04/export_gridview_to_excel_1.html"&gt;solution provided by Matt Berseth&lt;/a&gt; is safer and more elegant in that it uses &lt;span style="font-weight: bold;"&gt;a seperate class with a shared method&lt;/span&gt; (static for C# people). This way, you can access it from multiple pages without having to rewrite the code multiple times.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-8745322133964840966?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/8745322133964840966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=8745322133964840966' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8745322133964840966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/8745322133964840966'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/02/exporting-aspnet-gridview-to-excel.html' title='Exporting a asp.net gridview to Excel'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-5554686672744290740</id><published>2008-01-31T18:50:00.001+01:00</published><updated>2010-09-14T18:42:41.258+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Contact management class library</title><content type='html'>Is there a &lt;span style="font-weight: bold;"&gt;good and complete class library for contact management &lt;/span&gt;around? I've looked around on the internet but can't seem to find one. One of the first 'real' programs I had to write during my education was a .NET application to manage contacts, an addressbook. Add, edit and remove people, with addresses, phone numbers, etc. These people could belong to a company which also had an address, and so on. It was fairly simple.&lt;br /&gt;I'm on to a bigger project now, and need more than people and companies. I'll need all sorts of organisations, different types of people, etc. What strikes me as odd is that I couldn't find a class library that allready had these features, and focused solely on this scope: contact management and contact management alone.&lt;br /&gt;I can imagine hoards of developers and student-programmers build a few &lt;span style="font-weight: bold;"&gt;administrative applications&lt;/span&gt; in their lives, so why is there no reusable class library to manage this? It's practically always the same: person has address, company has people, company has address, address has a street, number, country, etc. It shouldn't even be a very big class library.&lt;br /&gt;So I plan to &lt;span style="font-weight: bold;"&gt;release my class library &lt;/span&gt;out into the wild when it's finished. So that not only I, but also others can &lt;span style="font-weight: bold;"&gt;skip the part of developing the zillionth contact management library &lt;/span&gt;and focus on the specific work of the job.&lt;br /&gt;The library will probably not fit everyone's need but inheritance and open source should be able to solve that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-5554686672744290740?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/5554686672744290740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=5554686672744290740' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5554686672744290740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/5554686672744290740'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/01/contact-management-class-library.html' title='Contact management class library'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-970191507519789994</id><published>2008-01-18T17:36:00.001+01:00</published><updated>2010-09-14T18:42:28.413+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><title type='text'>Easy, light-weight ISO burning tool</title><content type='html'>Just found an excellent tool to burn ISOs. It's free, it's light-weight, and it works from the context menu: &lt;a href="http://isorecorder.alexfeinman.com/isorecorder.htm"&gt;ISORecorder&lt;/a&gt;. It fits my needs perfectly. I don't need a big suite with all kind of options I won't be using (cf. Nero).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-970191507519789994?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/970191507519789994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=970191507519789994' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/970191507519789994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/970191507519789994'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/01/easy-light-weight-iso-burning-tool.html' title='Easy, light-weight ISO burning tool'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-2118014861707589949</id><published>2008-01-18T17:06:00.000+01:00</published><updated>2008-01-18T17:14:36.902+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>.NET source code available</title><content type='html'>Well, not all of it, but Microsoft has made it possible to enter the .NET Framework code when debugging. Although &lt;a href="http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx"&gt;configuring Visual Studio to do this&lt;/a&gt; is a little more work than what you need to do with, say, Java and Eclipse (which is: none), I believe it is still quite a useful feature. It allows developers to &lt;span style="font-weight: bold;"&gt;go into the code of the .NET Framework &lt;/span&gt;and see what's happening with the objects that are passed on.&lt;br /&gt;I have yet to test it, since I have Visual Studio 2005 and it's only available for VS2008, but I hope to get 2008 somewhere in the future.&lt;br /&gt;Anyway, it's a little buzz on blogs here and there. Be sure to check out &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/16/net-framework-library-source-code-now-available.aspx"&gt;Scott Guthrie's post on it&lt;/a&gt;, where he mentions which namespaces are available for now, and which are planned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-2118014861707589949?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/2118014861707589949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=2118014861707589949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/2118014861707589949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/2118014861707589949'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/01/net-source-code-available.html' title='.NET source code available'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-4699047088239632861</id><published>2008-01-09T22:15:00.003+01:00</published><updated>2010-09-14T18:42:07.973+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='UML'/><title type='text'>Quick and easy UML sequence diagrams</title><content type='html'>Following my previous post on &lt;span style="font-weight: bold;"&gt;UML&lt;/span&gt;, I'd like to point out a tool I like very much. It's only for &lt;span style="font-weight: bold;"&gt;sequence diagrams&lt;/span&gt; but I find it does the job very good, and real quick too. Also, it's far less of a pain than Microsoft Visio when changes have to be made.&lt;br /&gt;&lt;br /&gt;The name is Tracemodeler and can be found on &lt;a href="http://www.tracemodeler.com"&gt;tracemodeler.com&lt;/a&gt;. The advantages are plenty. For the record, I did not code this tool, so I'm not trying to sell my own&lt;br /&gt;First, you don't have to drag and drop elements, connecting stuff. Just right-click on the diagram, choose the correct element and it appears on the screen, where you clicked. If you clicked between messages or any other elements, those are nicely rearranged so your original flow stays unmessed with.&lt;br /&gt;Clicked on the wrong spot, and the message or object or whatever is in the wrong place? No problem, you can just left-click on it, and &lt;span style="font-weight: bold;"&gt;drag-and-drop&lt;/span&gt; it at the correct position. It even shows you where it will be dropped (see the red line), and everything stays connected.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_nJPIQzt8vNY/R4ec2OwI3DI/AAAAAAAAAAM/63AlFCem4QI/s1600-h/easy-uml-sequence-diagram.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_nJPIQzt8vNY/R4ec2OwI3DI/AAAAAAAAAAM/63AlFCem4QI/s320/easy-uml-sequence-diagram.JPG" alt="" id="BLOGGER_PHOTO_ID_5154260754035694642" border="0" /&gt;&lt;/a&gt;All this, without you having to rearrange all the other elements because they got in each others way (as in Visio). This way, you can focus on your &lt;span style="font-weight: bold;"&gt;sequence diagram&lt;/span&gt; and build them &lt;span style="font-weight: bold;"&gt;quick and easy&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Apart from that &lt;a href="http://www.tracemodeler.com"&gt;Tracemodeler&lt;/a&gt; comes with a simple but &lt;span style="font-weight: bold;"&gt;slick UI&lt;/span&gt;. Nice colors and style, but no overload. Although I might say, not all icons fit perfectly with what they do. The dialog for the export settings is reached through clicking on a camera. One could expect this would take a screenshot. The 'optimize target order' option (handy!) has a magic stick as icon, which reminds me of wizards.&lt;br /&gt;&lt;br /&gt;But that's details. The fact is, this is a &lt;span style="font-weight: bold;"&gt;simple and easy tool with no bloat&lt;/span&gt;. I'd recommend you download it and give it a try.&lt;br /&gt;&lt;br /&gt;That's enough on UML I recon. I don't plan to make this a UML blog. Anyone know good tools to make &lt;a href="http://www.smartdraw.com/tutorials/software/uml/tutorial_01.htm"&gt;UML diagrams&lt;/a&gt; though, be sure to let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-4699047088239632861?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/4699047088239632861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=4699047088239632861' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/4699047088239632861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/4699047088239632861'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/01/quick-and-easy-uml-sequence-diagrams_09.html' title='Quick and easy UML sequence diagrams'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_nJPIQzt8vNY/R4ec2OwI3DI/AAAAAAAAAAM/63AlFCem4QI/s72-c/easy-uml-sequence-diagram.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-7730349986695237751</id><published>2008-01-08T19:22:00.000+01:00</published><updated>2008-01-09T22:16:13.484+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UML'/><title type='text'>Thoughts on UML</title><content type='html'>Okay, here goes my first real post.&lt;br /&gt;&lt;br /&gt;Every developer must have at least a basic understanding of &lt;span style="font-weight: bold;"&gt;UML&lt;/span&gt;. In my opinion, it can be a very powerful tool for explaining the architecture of applications (even to yourself after not having worked in the code for a while). It's much more easy to follow a neat diagram, than to have to dig through the code and go from method to method, switching between classes and trying to remember where in the whole application(flow) you are.&lt;br /&gt;&lt;br /&gt;A &lt;span style="font-weight: bold;"&gt;downside of UML&lt;/span&gt; is the fact that we as developers like to work more in code than we like making diagrams, charts, documents with long boring texts,... Code is much more fun! To make matters worse, whenever you change parts of the code, the documentation has to be updated too. Especially when big changes have been made, or the updating of the documentation has been postponed for too long, this makes a fun job indeed.&lt;br /&gt;&lt;br /&gt;Alongside this, discussions or considerations can arise over futile details which will have no influence on the ultimate &lt;span style="font-weight: bold;"&gt;goal of UML&lt;/span&gt;: clarifying the workings of the application, explaining the architecture in a simplified way. Not all details should go in your diagrams, because they won't help at guiding a newcomer (or yourself) through the project. &lt;span style="font-weight: bold;"&gt;Typically, class diagrams&lt;/span&gt; are stuffed full of methods, properties, members, associations, ... which sort of clouds the overall image. Read the interesting article on &lt;a href="http://www.regdeveloper.co.uk/2007/12/18/analysis_paralysis_part_one/"&gt;analysis paralysis&lt;/a&gt; (don't forget &lt;a href="http://www.regdeveloper.co.uk/2008/01/03/analysis_paralysis_part_two/"&gt;part 2&lt;/a&gt;).&lt;br /&gt;Put this all together and people start thinking UML will hold them back more than it can help them. And it can and should helpt! Just put enough time into it, without putting too much time into it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-7730349986695237751?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/7730349986695237751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=7730349986695237751' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/7730349986695237751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/7730349986695237751'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/01/quick-and-easy-uml-sequence-diagrams.html' title='Thoughts on UML'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4093944831568090072.post-1050895981053629707</id><published>2008-01-07T18:14:00.000+01:00</published><updated>2008-01-07T18:15:12.607+01:00</updated><title type='text'>First post</title><content type='html'>Hello world!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4093944831568090072-1050895981053629707?l=petermorlion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petermorlion.blogspot.com/feeds/1050895981053629707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4093944831568090072&amp;postID=1050895981053629707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/1050895981053629707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4093944831568090072/posts/default/1050895981053629707'/><link rel='alternate' type='text/html' href='http://petermorlion.blogspot.com/2008/01/first-post.html' title='First post'/><author><name>Peter</name><uri>http://www.blogger.com/profile/07764563431818681764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
