<?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-7873754566403770354</id><updated>2012-01-28T13:11:52.876+01:00</updated><category term='Coding'/><category term='Blend'/><category term='Visual Studio'/><category term='Performance'/><category term='CSS'/><category term='Installer'/><category term='Subversion'/><category term='Javascript'/><category term='Version Control'/><category term='UI'/><category term='Thoughts'/><category term='Build'/><category term='Tips'/><category term='Windows7'/><category term='IIS'/><category term='SvnQuery'/><category term='Unit Tests'/><category term='DI'/><category term='ReSharper'/><category term='Expression Web'/><category term='Feature Toggles'/><category term='WiX'/><category term='IE8'/><category term='Quotation'/><category term='Frequent Errors'/><category term='Debugging'/><category term='TortoiseSVN'/><category term='WPF'/><category term='Silverlight'/><category term='Continous Deployment'/><category term='.NET'/><category term='Books'/><title type='text'>Atombrenner</title><subtitle type='html'>Christian Rodemeyer's Blog</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-7444135563417831619</id><published>2012-01-19T21:10:00.001+01:00</published><updated>2012-01-19T21:10:59.645+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Thoughts'/><title type='text'>The best fellow employee ...</title><content type='html'>&lt;p&gt;... is someone that you can criticize without pissing him off. The same should be true the other way round. I'm glad that I'm working for an exceptional company where nearly everyone has this attitude.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-7444135563417831619?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/7444135563417831619/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2012/01/best-fellow-employee.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/7444135563417831619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/7444135563417831619'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2012/01/best-fellow-employee.html' title='The best fellow employee ...'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-8206167204228776664</id><published>2011-11-27T12:35:00.001+01:00</published><updated>2011-11-27T12:35:57.601+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Build'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>Speed up your build with UseHardlinksIfPossible</title><content type='html'>&lt;p&gt;MsBuild 4.0 added the new attribute &amp;quot;UseHardlinksIfPossible&amp;quot; to the &lt;a href="http://msdn.microsoft.com/en-us/library/3e54c37h(v=VS.100).aspx"&gt;Copy task&lt;/a&gt;. Using &lt;a href="http://en.wikipedia.org/wiki/Hard_link"&gt;Hardlinks&lt;/a&gt; makes your build faster because less IO operations and disk space is needed (= better usage of file system cache). What's best is that this new option is already be used by the standard .net build system! But Microsoft decided to turn them off by default. &lt;/p&gt;  &lt;p&gt;After searching a little bit in the c# target files I found out how to turn this feature globally on and my build was 20% faster than before. And if you have big builds with more than a hundred projects this counts!&lt;/p&gt;  &lt;p&gt;So here comes the way to turn on hard linking in your build. First, this works only with NTFS. Second you have to explicitly set the ToolsVersion to 4.0. You can do this with a command line argument (&lt;font face="Consolas"&gt;msbuild /tv:4.0&lt;/font&gt;) or inside the project file &lt;font face="Consolas"&gt;&lt;font face="Verdana"&gt;(&lt;/font&gt;&amp;lt;Project DefaultTargets=&amp;quot;Build&amp;quot; ToolsVersion=&amp;quot;4.0&amp;quot; ...&lt;/font&gt;&lt;font face="Verdana"&gt;).&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Then you have to override the following properties with a value of &amp;quot;True&amp;quot;:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;CreateHardLinksForCopyFilesToOutputDirectoryIfPossible &lt;/li&gt;    &lt;li&gt;CreateHardLinksForCopyAdditionalFilesIfPossible &lt;/li&gt;    &lt;li&gt;CreateHardLinksForCopyLocalIfPossible &lt;/li&gt;    &lt;li&gt;CreateHardLinksForPublishFilesIfPossible &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Use command line properties (&lt;font face="Consolas"&gt;msbuild /p:CreateHardLinksForCopyLocalIfPossible=true) &lt;/font&gt;&lt;font face="Verdana"&gt;to override them for all projects in one build. Or you can create a little startup build file that collects all projects and set the properties in one place. Here is mine: &lt;/font&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a07ae26c-c066-4a21-9539-853e1c7307c0" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515"&gt;xml&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;version&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;encoding&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;?&amp;gt;&lt;/span&gt;&lt;br&gt; &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;Project&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;DefaultTargets&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;Build&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;ToolsVersion&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;4.0&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &amp;gt;&lt;/span&gt;&lt;br&gt; &lt;br&gt;   &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;    &lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;Include&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;**&amp;#92;*.csproj&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;Include&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;Exclude&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;_build&amp;#92;**&amp;#92;*.csproj&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;Exclude&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;CreateHardLinksIfPossible&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;true&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;CreateHardLinksIfPossible&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt; &lt;br&gt;   &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;ItemGroup&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;ProjectFiles&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;Include&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;$(Include)&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;Exclude&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;$(Exclude)&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;ItemGroup&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt; &lt;br&gt;   &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;Target&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;Name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;Build&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;MSBuild&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;Projects&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;@(ProjectFiles)&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;Targets&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;Build&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;BuildInParallel&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;True&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;ToolsVersion&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;4.0&lt;/span&gt;&amp;quot;&lt;br&gt;              &lt;span style="color:#0000ff"&gt;&lt;/span&gt;&lt;span style="color:#ff0000"&gt;Properties&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;Configuration=$(Configuration);&lt;/span&gt;&lt;br&gt;                          &lt;span style="color:#0000ff"&gt;BuildInParallel=True;&lt;/span&gt;&lt;br&gt;                          &lt;span style="color:#0000ff"&gt;CreateHardLinksForCopyFilesToOutputDirectoryIfPossible=$(CreateHardLinksIfPossible);&lt;/span&gt;&lt;br&gt;                          &lt;span style="color:#0000ff"&gt;CreateHardLinksForCopyAdditionalFilesIfPossible=$(CreateHardLinksIfPossible);&lt;/span&gt;&lt;br&gt;                          &lt;span style="color:#0000ff"&gt;CreateHardLinksForCopyLocalIfPossible=$(CreateHardLinksIfPossible);&lt;/span&gt;&lt;br&gt;                          &lt;span style="color:#0000ff"&gt;CreateHardLinksForPublishFilesIfPossible=$(CreateHardLinksIfPossible);&lt;/span&gt;&lt;br&gt;                          &lt;span style="color:#0000ff"&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; /&amp;gt;    &lt;/span&gt;&lt;br&gt;   &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;Target&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color:#0000ff"&gt;&lt;/span&gt;&lt;br&gt; &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;Project&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-8206167204228776664?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/8206167204228776664/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/11/speed-up-your-build-with.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8206167204228776664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8206167204228776664'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/11/speed-up-your-build-with.html' title='Speed up your build with UseHardlinksIfPossible'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-9221470726388354529</id><published>2011-08-06T22:42:00.001+02:00</published><updated>2011-08-06T22:42:57.288+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Feature Toggles'/><title type='text'>Feature Toggle Status Page</title><content type='html'>&lt;p&gt;If a website uses Feature Toggles it should have some diagnostic page that displays the the current configuration and state of all toggles. On our Feature Toggle status page it is even possible to explicitly switch a toggle ON or OFF with one click. Another feature that I like is, that you can quickly see toggles that are still in use but nowhere configured. This is an indication that it was forgotten to remove some code.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-_qvn0fyzCgo/Tj2nSsmCKsI/AAAAAAAAAGw/q04xFPg-XIM/s1600-h/image%25255B30%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-qVyW6kkhJQc/Tj2nT4XC-fI/AAAAAAAAAG0/zYdzuB2vxs8/image_thumb%25255B24%25255D.png?imgmax=800" width="644" height="217" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-9221470726388354529?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/9221470726388354529/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/08/feature-toggle-status-page.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/9221470726388354529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/9221470726388354529'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/08/feature-toggle-status-page.html' title='Feature Toggle Status Page'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-qVyW6kkhJQc/Tj2nT4XC-fI/AAAAAAAAAG0/zYdzuB2vxs8/s72-c/image_thumb%25255B24%25255D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-5265352956835894270</id><published>2011-08-06T22:09:00.001+02:00</published><updated>2011-08-06T22:09:54.523+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Continous Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Feature Toggles'/><title type='text'>More cool Feature Toggle Features</title><content type='html'>&lt;p&gt;We have extended our Feature Toggle implementation with two more features:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;an activation interval that determines in advance when a toggle is on or off &lt;/li&gt;    &lt;li&gt;a toggle that is only enabled for a certain rate of visitors &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We release new versions every two weeks and sometimes the activation of a feature is coupled to a fixed date by marketing or legal reasons. You could argue that the feature itself should implement the date checking but it was attractive to use the existing Feature Toggle infrastructure. Our existing implementation could be easily extended to support this, but I admit that it added complexity and that the implementation is now a little bit impure in the sense that it is now no longer exclusively used as a development tool. &lt;/p&gt;  &lt;p&gt;The Feature Toggle configuration is still simple and readable. Everything except the name attribute is optional so you have to specify only the borders you need:&lt;/p&gt;  &lt;pre&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#d19049"&gt;toggle&lt;/font&gt; &lt;font color="#ff0000"&gt;name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;myFeature&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;enabled&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/font&gt; &lt;font color="#0000ff"&gt;/&amp;gt; &lt;/font&gt;
&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#d19049"&gt;toggle&lt;/font&gt; &lt;font color="#ff0000"&gt;name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;myFeature&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;enabled&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;from&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;2012-01-01&amp;quot;&lt;/font&gt; &lt;font color="#0000ff"&gt;/&amp;gt; &lt;/font&gt;
&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#d19049"&gt;toggle&lt;/font&gt; &lt;font color="#ff0000"&gt;name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;myFeature&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;enabled&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;to&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;2012-06-01&amp;quot;&lt;/font&gt; &lt;font color="#0000ff"&gt;/&amp;gt; &lt;/font&gt;
&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#d19049"&gt;toggle&lt;/font&gt; &lt;font color="#ff0000"&gt;name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;myFeature&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;enabled&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;from&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;2012-01-01&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;to&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;2012-06-01&amp;quot;&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The second feature was inspired by the &lt;a href="http://atombrenner.blogspot.com/2011/06/cool-toggle-feature.html"&gt;allowHttpOverride&lt;/a&gt; property original developed for testing purposes. If a user visits our page the toggle decides randomly with the given rate if the toggle is on or off. The result is stored inside a browser cookie and never changed. So it works for features that span several pages or workflows. The rate feature is extremely useful if you plan to do canary releases for only a few percent of your users. If everything works fine you can slowly increase the rate until it reaches 100%.&lt;/p&gt;





&lt;p&gt;Every toggle attribute can be combined with every other attribute, e.g. a toggle that is on only for a specific interval with a specific rate and overriding it per cookie or query parameter is not allowed:&lt;/p&gt;

&lt;pre&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#f79646"&gt;toggle&lt;/font&gt; &lt;font color="#ff0000"&gt;name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;myFeature&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;enabled&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/font&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;from&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;2012-01-01&amp;quot;&lt;/font&gt; &lt;font color="#ff0000"&gt;to&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;2012-06-01&amp;quot;&lt;/font&gt;
        &lt;font color="#ff0000"&gt;rate&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;42&amp;quot;&lt;/font&gt;
        &lt;font color="#ff0000"&gt;allowHttpOverride&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/font&gt; &lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;
 &lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-5265352956835894270?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/5265352956835894270/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/08/more-cool-feature-toggle-features.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/5265352956835894270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/5265352956835894270'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/08/more-cool-feature-toggle-features.html' title='More cool Feature Toggle Features'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-1096650454165736649</id><published>2011-06-26T19:11:00.001+02:00</published><updated>2011-06-26T19:11:47.509+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Continous Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Feature Toggles'/><title type='text'>A Cool 'Feature Toggle' Feature</title><content type='html'>&lt;p&gt;Recently we gave our &lt;a href="http://atombrenner.blogspot.com/2011/02/feature-toggles-links.html"&gt;Feature Toggles&lt;/a&gt; the possibility to be overridden at runtime. For a web application I found this extension quite useful and its implementation was easy and straightforward. This is the configuration for toggles that are always on or off:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7a55fd2c-fc9e-40fa-83dc-f07a6feb16cd" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #fffff2; max-height: 400px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;featureToggles&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;toggle&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;aFeature&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;enabled&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; /&amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;toggle&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;anotherFeature&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;enabled&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; /&amp;gt;&lt;/span&gt;&lt;br&gt; &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;featureToggles&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;If I want that the toggle can be overridden at runtime I just add one additional attribute:&lt;/p&gt;    &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1fb0db92-6f00-4665-8ce7-e02757480a71" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #fffff2; max-height: 400px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;featureToggles&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;toggle&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;aFeature&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;enabled&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;allowHttpOverride&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;toggle&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;anotherFeature&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;enabled&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;allowHttpOverride&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt; &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;featureToggles&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;Now if a visit a page, say &lt;em&gt;www.atombrenner.de/test&lt;/em&gt;,&amp;#160; I can modify the url to be &lt;em&gt;www.atombrenner.de/test?aFeature=off&lt;/em&gt; and now for the complete request the toggle is off. For workflows that cover more than one page request we use cookies. Just create a new cookie with your favorite cookie manager (I like the &lt;a href="https://chrome.google.com/webstore/detail/fngmhnnpilhplaeedifhccceomclgfbg"&gt;'Edit this cookie'&lt;/a&gt; plugin for Google Chrome very much).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-n9cRJRzuPPE/TgdoUBu-9_I/AAAAAAAAAFA/bcdY90yF_YM/s1600-h/image%25255B2%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-cOcqgjus4gA/TgdoUrWP6fI/AAAAAAAAAFE/QOjDTWWBiaI/image_thumb.png?imgmax=800" width="387" height="292" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The name of the cookie must be the name of the toggle you want to override. Allowed values are: 0, 1, off, on, false, true. If both a query string value and a cookie value is given, the query string parameter wins.&lt;/p&gt;  &lt;p&gt;If find this feature extremely useful because it allows you to toggle very quickly the feature on or off, without the need for recompiling or reconfiguring. This enables you &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;to always test that your app is still stable when the new feature is turned off&lt;/li&gt;    &lt;li&gt;to give testers or managers a quick preview of the feature during development&lt;/li&gt;    &lt;li&gt;to provide external partners a preview of the feature in the live environment, so they can test and accept features before it goes public.&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/7873754566403770354-1096650454165736649?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/1096650454165736649/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/06/cool-toggle-feature.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/1096650454165736649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/1096650454165736649'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/06/cool-toggle-feature.html' title='A Cool &amp;#39;Feature Toggle&amp;#39; Feature'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/-cOcqgjus4gA/TgdoUrWP6fI/AAAAAAAAAFE/QOjDTWWBiaI/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-4079013907867967784</id><published>2011-06-26T13:19:00.001+02:00</published><updated>2011-06-26T13:19:08.204+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Frequent Errors'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><title type='text'>Exception Logging Antipatterns</title><content type='html'>&lt;p&gt;Here are some logging antipatterns I have seen again and again in real life production code. If your application has one global exception handler, catching and logging should be done only in this central place. If you want to provide additional information throw a new exception and attach the original exception. I assume that the logging framework is capable of dumping an exception recursively, that means with all inner exceptions and their stacktraces. &lt;/p&gt;  &lt;h5&gt;&lt;b&gt;Catch Log Throw&lt;/b&gt;&lt;/h5&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:87c53f46-335c-4ab1-a709-133c5fbfec27" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #fffff2; max-height: 400px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;Exception&lt;/span&gt; ex)&lt;br&gt; {&lt;br&gt;     _logger.WriteError(ex);&lt;br&gt;     &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt;;&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;No additionally info is added. The global exception handler will log this error anyway, therefore the logging is redundant and blows up your log. The correct solution is to not catch the exception at all.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Catch Log Throw Other&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:63f146bf-cc2b-4650-a5ea-affd4e1411c2" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #fffff2; max-height: 400px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;Exception&lt;/span&gt; ex)&lt;br&gt; {&lt;br&gt;     _logger.WriteError(ex, &lt;span style="color:#ff00ff"&gt;&amp;quot;information&amp;quot;&lt;/span&gt;);&lt;br&gt;     &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color:#ff00ff"&gt;&amp;quot;information&amp;quot;&lt;/span&gt;); &lt;span style="color:#008000"&gt;// same information&lt;/span&gt;&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; Same as Catch Log Throw, but now you have two totally unrelated log entries. Solution: use the InnerException mechanism to create a new exception and don't log the old one:   &lt;br /&gt;&lt;font color="#000000"&gt;&lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: magenta"&gt;&amp;quot;information&amp;quot;&lt;/span&gt;, ex);&lt;/font&gt;   &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h5&gt;&lt;strong&gt;Log Un-thrown Exceptions&lt;/strong&gt;&lt;/h5&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" &gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #fffff2; max-height: 500px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;Exception&lt;/span&gt; ex)&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; myException = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;MyException&lt;/span&gt;(&lt;span style="color:#ff00ff"&gt;&amp;quot;information&amp;quot;&lt;/span&gt;); &lt;br&gt;     _logger.WriteError(myException); &lt;br&gt;     &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; myException;&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;In this case an un-thrown exception is logged. This could cause problems, because the exception is not fully initialized until it was thrown. For example the Stacktrace property would be null. Solution: don't log, just attach the original exception ex to MyException:    &lt;br /&gt;&lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MyException&lt;/span&gt;(&lt;span style="color: magenta"&gt;&amp;quot;information&amp;quot;&lt;/span&gt;, ex); &lt;/p&gt;  &lt;h5&gt;&lt;strong&gt;Non Atomic Logging &lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h5&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2c7c7a65-bb78-45a0-84d9-8a60e9ace948" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #fffff2; max-height: 400px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;Exception&lt;/span&gt; ex)&lt;br&gt; {&lt;br&gt;     _logger.WriteError(ex.Message);&lt;br&gt;     _logger.WriteError(&lt;span style="color:#ff00ff"&gt;&amp;quot;Some information&amp;quot;&lt;/span&gt;);&lt;br&gt;     _logger.WriteError(ex);&lt;br&gt;     _logger.WriteError(&lt;span style="color:#ff00ff"&gt;&amp;quot;More information&amp;quot;&lt;/span&gt;);&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Several log messages are created for one cause. In the log they appear unrelated and can be mixed with other log message. Solution: Combine the information into one atomic write to the logging system: _logger.WriteError(ex, &lt;span style="color: magenta"&gt;&amp;quot;Some information and more information&amp;quot;&lt;/span&gt;);&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h5&gt;   &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;   &lt;strong&gt;Expensive Log Messages&lt;/strong&gt;&lt;/h5&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px"&gt;   &lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;     &lt;div style="padding-bottom: 2px; background-color: #fffff2; padding-left: 5px; padding-right: 5px; white-space: nowrap; max-height: 400px; overflow: auto; padding-top: 2px"&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [...] // some code         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; _logger.WriteInformation(&lt;span style="color: #2b91af"&gt;Helper&lt;/span&gt;.ReflectAllProperties(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;));         &lt;br /&gt;}&lt;/div&gt;   &lt;/div&gt; &lt;/div&gt; This one is really dangerous for your performance. An expensive log message is generated all the time even if the logging system is configured to ignore it. If you have expensive message, put the generation into an if block side by side with the logging statement:   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(_logger.ShouldWrite(&lt;font color="#2b91af"&gt;LogLevel&lt;/font&gt;.Information))
{
    &lt;font color="#008040"&gt;// do expensive logging here&lt;br /&gt;&lt;pre class="code"&gt;&lt;font color="#000000"&gt;    _logger.WriteInformation&lt;/font&gt;(&lt;span style="color: #2b91af"&gt;Helper&lt;/span&gt;.&lt;font color="#000000"&gt;ReflectAllProperties&lt;/font&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;));
&lt;/pre&gt;&lt;/font&gt;&lt;br /&gt;}&lt;/pre&gt;

&lt;pre class="code"&gt;&amp;#160;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-4079013907867967784?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/4079013907867967784/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/06/exception-logging-antipatterns.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/4079013907867967784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/4079013907867967784'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/06/exception-logging-antipatterns.html' title='Exception Logging Antipatterns'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-6989663552685434341</id><published>2011-06-13T11:19:00.002+02:00</published><updated>2011-06-15T20:24:56.669+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Disable ASP.NET Development Server</title><content type='html'>I always forget how to stop the ASP.NET Development server from starting when I attach to the IIS for debugging, so here is the way to do it:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Select the web or WCF project. Press F4 to show the property window. If only an empty window appears, repeat the process. &lt;/li&gt;
&lt;li&gt;Set the first property to "False". &lt;/li&gt;
&lt;/ol&gt;
&lt;a href="http://lh4.ggpht.com/-FrUoZyghCWY/TfXWLiaIJYI/AAAAAAAAAE4/Gt1esk4FZh8/s1600-h/Always_start_when_debugging%25255B4%25255D.png"&gt;&lt;img alt="Always_start_when_debugging" border="0" height="307" src="http://lh4.ggpht.com/-KhK8bX4LcbE/TfXWMBfiB5I/AAAAAAAAAE8/zLGPFuKwaWY/Always_start_when_debugging_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Always_start_when_debugging" width="451" /&gt;&lt;/a&gt;&lt;br /&gt;
If your solution contain projects that start the ASP.NET Development Server you will enjoy my macro that sets this property solution wide:&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:07c23fd0-1234-4afb-aba2-753bc26688ab" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;
&lt;div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;"&gt;
&lt;div style="background-color: #fcf8e9; max-height: 500px; overflow: auto; padding: 2px 5px; white-space: nowrap;"&gt;
&lt;span style="color: blue;"&gt;Sub&lt;/span&gt; TurnOffAspNetDebugging()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;REM The dynamic property CSharpProjects returns all projects &lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;REM recursively. "Solution.Projects" would return only the top &lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;REM level projects. Use VBProjects if you are using VB :-).&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;Dim&lt;/span&gt; projects = &lt;span style="color: blue;"&gt;CType&lt;/span&gt;(DTE.GetObject(&lt;span style="color: #a31515;"&gt;"CSharpProjects"&lt;/span&gt;), Projects)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;For&lt;/span&gt; &lt;span style="color: blue;"&gt;Each&lt;/span&gt; p &lt;span style="color: blue;"&gt;As&lt;/span&gt; Project &lt;span style="color: blue;"&gt;In&lt;/span&gt; projects&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;For&lt;/span&gt; &lt;span style="color: blue;"&gt;Each&lt;/span&gt; prop &lt;span style="color: blue;"&gt;In&lt;/span&gt; p.Properties&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;If&lt;/span&gt; prop.Name = &lt;span style="color: #a31515;"&gt;"WebApplication.StartWebServerOnDebug"&lt;/span&gt; &lt;span style="color: blue;"&gt;Then&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prop.Value = &lt;span style="color: blue;"&gt;False&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;If&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;Next&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;Next&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Sub&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-6989663552685434341?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/6989663552685434341/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/06/disable-aspnet-development-server.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6989663552685434341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6989663552685434341'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/06/disable-aspnet-development-server.html' title='Disable ASP.NET Development Server'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-KhK8bX4LcbE/TfXWMBfiB5I/AAAAAAAAAE8/zLGPFuKwaWY/s72-c/Always_start_when_debugging_thumb%25255B1%25255D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-7737005399423947348</id><published>2011-06-12T22:37:00.001+02:00</published><updated>2011-06-12T23:17:27.269+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Continous Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><category scheme='http://www.blogger.com/atom/ns#' term='Feature Toggles'/><title type='text'>Feature Toggle or Feature Branch</title><content type='html'>&lt;p&gt;I'm working in company that releases every two weeks with the goal to do weekly releases and eventually daily releases. We introduced &lt;a href="http://atombrenner.blogspot.com/2011/02/feature-toggles-links.html"&gt;Feature Toggles&lt;/a&gt; for the development of features that overlap a release without destroying Continuous Integration. &lt;/p&gt;  &lt;p&gt;Recently I noticed that people start using Feature Toggles for features that take only a few hours to implement. In this case the effort to setup, configure and test the Feature Toggle is easily more than 50 percent of implementation effort. It would be much more efficient to create a branch and merge it one or two days later back to the trunk. The cost for having no continuous integration is less than the cost for using a toggle in this case. &lt;/p&gt;  &lt;p&gt;Why are people doing this? One answer could be that they are entrapped by the possibility to dynamically turn features on or off. Another is process thinking: because there was a process that enforced feature branches for feature development it is believed that you now &lt;strong&gt;must&lt;/strong&gt; use Feature Toggles. Another company specific reason is that we had feature branches coupled with a heavyweight process (including the setup of a complete cloned environment with automatic builds, databases, dozens of service, ...) that was so painful that everybody shivers when hearing the word Feature Branch.&lt;/p&gt;  &lt;p&gt;Make sure that you are using feature toggles and feature branches for the right things. A lightweight feature branch needs much less brainpower than implementing of a toggle for the modification of an legacy feature. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-7737005399423947348?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/7737005399423947348/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/06/feature-toggle-or-feature-branch.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/7737005399423947348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/7737005399423947348'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/06/feature-toggle-or-feature-branch.html' title='Feature Toggle or Feature Branch'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-2896378752763536295</id><published>2011-03-30T07:50:00.001+02:00</published><updated>2011-03-30T07:50:32.386+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Feature Toggles'/><title type='text'>Why a Feature Toggle should be ‘OFF’ if it is undefined</title><content type='html'>&lt;p&gt;When I first implemented some infrastructure supporting &lt;a href="http://martinfowler.com/bliki/FeatureToggle.html"&gt;Feature Toggles&lt;/a&gt; I thought it was a good idea to have three states: on, off and undefined. If some code access a feature that is not defined it should throw an exception. The reason for this was that I used a fairly dynamic approach where a feature was identified by its name. This allows simple adding and removing of feature toggles without the static typing overhead. The drawback is that typing errors cannot be found by the compiler or interpreter, e.g. the feature is defined as “Toggle” but you write “togle”. In this case I thought it would be good to throw an exception. &lt;/p&gt;  &lt;p&gt;But if you are developing a component that is is used in several applications than you have to define the feature in every applications configuration. Even if the feature should be disabled everywhere except in your test application. And if the feature is finished you have to remove the feature from all application configuration again. Error prone and time consuming. &lt;/p&gt;  &lt;p&gt;Therefore an undefined feature toggle should always be treated as ‘OFF’.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-2896378752763536295?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/2896378752763536295/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/03/why-feature-toggle-should-be-off-if-it.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/2896378752763536295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/2896378752763536295'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/03/why-feature-toggle-should-be-off-if-it.html' title='Why a Feature Toggle should be ‘OFF’ if it is undefined'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-8835080087373751352</id><published>2011-02-24T15:55:00.002+01:00</published><updated>2011-09-29T21:47:28.441+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Continous Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Feature Toggles'/><title type='text'>Feature Toggles Links</title><content type='html'>At work we want to use Feature Toggles (Branching in code) to avoid “Feature Branch Hell”. Here is a list of links with experiences and definition from others with thanks to Pete and Natalya.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://martinfowler.com/bliki/FeatureToggle.html"&gt;Feature Toggles (Martin Fowler)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://martinfowler.com/bliki/FeatureBranch.html"&gt;Feature Branch (Martin Fowler)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://sarahtaraporewalla.com/design/experience-report-feature-toggling/"&gt;Feature Toggle Experience report&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pauljulius.com/blog/2009/09/03/feature-branches-are-poor-mans-modular-architecture/"&gt;Feature Branches are poor mans modular architecture&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.infoq.com/presentations/Feature-Bits"&gt;Feature Bits by Erik Sowa and Rob Loh (Presentation, 56 min)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.infoq.com/interviews/jez-humble-martin-fowler-cd"&gt;Interview with Jez Humble and Martin Fowler (38 min)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.flickr.com/blog/2009/12/02/flipping-out/"&gt;Feature Flags by Flickr (Blog)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.google.com/present/view?id=dg63dpc6_4d7vkk6ch&amp;amp;pli=1"&gt;Chrome Release Process (Slideshow)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://assets.en.oreilly.com/1/event/29/10+%20Deploys%20Per%20Day_%20Dev%20and%20Ops%20Cooperation%20at%20Flickr%20Presentation.pdf"&gt;10 Deploys per Day at Flickr&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://nosql.mypopescu.com/post/407159447/cassandra-twitter-an-interview-with-ryan-king"&gt;Switching incrementally to Cassandra at Twitter&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.startuplessonslearned.com/search/label/continuous%20deployment"&gt;Continous Deployment&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://prettyprint.me/2011/01/24/continuous-deployment-at-outbrain/"&gt;Continuous deployment at outbrain&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.stevemoyer.net/2011/03/feature-toggles-for-net-ntoggle.html"&gt;nToggle implementation&lt;/a&gt; &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/7873754566403770354-8835080087373751352?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/8835080087373751352/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/02/feature-toggles-links.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8835080087373751352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8835080087373751352'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/02/feature-toggles-links.html' title='Feature Toggles Links'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-4330299934961227963</id><published>2011-02-16T20:56:00.001+01:00</published><updated>2011-02-16T20:56:45.603+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Visual Studio 2010 Javascript Snippets for Jasmine</title><content type='html'>&lt;p&gt;Because Resharper 5 does not support live templates for Javascript I’m forced to use the built in VS2010 snippets. The default Javascripts snippets are located here:&lt;/p&gt;  &lt;p&gt;%ProgramFiles%\Microsoft Visual Studio 10.0\Web\Snippets\JScript\1033\JScript&lt;/p&gt;  &lt;p&gt;The ‘1033’ locale ID may be different for your country. I’m using the following snippets for creating &lt;a href="https://github.com/pivotal/jasmine/wiki"&gt;Jasmine&lt;/a&gt; specs:&lt;/p&gt;  &lt;h5&gt;describe&lt;/h5&gt;  &lt;p&gt;&lt;font size="1" face="Courier New"&gt;&amp;lt;CodeSnippet Format=&amp;quot;1.1.0&amp;quot; xmlns=&amp;quot;&lt;/font&gt;&lt;font size="1" face="Courier New"&gt;http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet&amp;quot;&lt;/font&gt;&lt;font size="1" face="Courier New"&gt;&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;Header&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Title&amp;gt;describe&amp;lt;/Title&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Author&amp;gt;Christian Rodemeyer&amp;lt;/Author&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Shortcut&amp;gt;describe&amp;lt;/Shortcut&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;Code snippet for a jasmine 'describe' function&amp;lt;/Description&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SnippetTypes&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SnippetType&amp;gt;Expansion&amp;lt;/SnippetType&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/SnippetTypes&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/Header&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;Snippet&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Declarations&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Literal&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ID&amp;gt;suite&amp;lt;/ID&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ToolTip&amp;gt;suite description&amp;lt;/ToolTip&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Default&amp;gt;some suite&amp;lt;/Default&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Literal&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Declarations&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Code Language=&amp;quot;jscript&amp;quot;&amp;gt;&amp;lt;![CDATA[describe(&amp;quot;$suite$&amp;quot;, function () {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $end$&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;gt;&amp;lt;/Code&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/Snippet&amp;gt;      &lt;br /&gt;&amp;lt;/CodeSnippet&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;h5&gt;it&lt;/h5&gt;  &lt;p&gt;&lt;font size="1" face="Courier New"&gt;&amp;lt;CodeSnippet Format=&amp;quot;1.1.0&amp;quot; xmlns=&amp;quot;&lt;/font&gt;&lt;font size="1" face="Courier New"&gt;http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet&amp;quot;&lt;/font&gt;&lt;font size="1" face="Courier New"&gt;&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;Header&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Title&amp;gt;it&amp;lt;/Title&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Author&amp;gt;Christian Rodemeyer&amp;lt;/Author&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Shortcut&amp;gt;it&amp;lt;/Shortcut&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;Code snippet for a jasmine 'it' function&amp;lt;/Description&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SnippetTypes&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SnippetType&amp;gt;Expansion&amp;lt;/SnippetType&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/SnippetTypes&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/Header&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;Snippet&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Declarations&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Literal&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ID&amp;gt;spec&amp;lt;/ID&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ToolTip&amp;gt;spec description&amp;lt;/ToolTip&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Default&amp;gt;expected result&amp;lt;/Default&amp;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;lt;/Literal&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Declarations&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Code Language=&amp;quot;jscript&amp;quot;&amp;gt;&amp;lt;![CDATA[it(&amp;quot;should be $spec$&amp;quot;, function () {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var result = $end$&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; });]]&amp;gt;&amp;lt;/Code&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/Snippet&amp;gt;      &lt;br /&gt;&amp;lt;/CodeSnippet&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;h5&gt;func &lt;/h5&gt;  &lt;p&gt;&lt;font size="1" face="Courier New"&gt;&amp;lt;CodeSnippet Format=&amp;quot;1.1.0&amp;quot; xmlns=&amp;quot;&lt;/font&gt;&lt;font size="1" face="Courier New"&gt;http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet&amp;quot;&lt;/font&gt;&lt;font size="1" face="Courier New"&gt;&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;Header&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Title&amp;gt;function&amp;lt;/Title&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Author&amp;gt;Christian Rodemeyer&amp;lt;/Author&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Shortcut&amp;gt;func&amp;lt;/Shortcut&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;Code snippet for an anonymous function&amp;lt;/Description&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SnippetTypes&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SnippetType&amp;gt;Expansion&amp;lt;/SnippetType&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SnippetType&amp;gt;SurroundsWith&amp;lt;/SnippetType&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/SnippetTypes&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;/Header&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;Snippet&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Code Language=&amp;quot;jscript&amp;quot;&amp;gt;&amp;lt;![CDATA[function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $selected$$end$       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }]]&amp;gt;&amp;lt;/Code&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;/Snippet&amp;gt;       &lt;br /&gt;&amp;lt;/CodeSnippet&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-4330299934961227963?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/4330299934961227963/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/02/visual-studio-2010-javascript-snippets.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/4330299934961227963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/4330299934961227963'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/02/visual-studio-2010-javascript-snippets.html' title='Visual Studio 2010 Javascript Snippets for Jasmine'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-6648985088938071852</id><published>2011-02-10T21:12:00.001+01:00</published><updated>2011-02-10T21:29:50.400+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Frequent Errors'/><category scheme='http://www.blogger.com/atom/ns#' term='SvnQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Subversion'/><title type='text'>Removing the mime-type of files in Subversion with SvnQuery</title><content type='html'>&lt;p&gt;If you add files to subversion they are associated with a mimetype. &lt;a href="http://svnquery.tigris.org"&gt;SvnQuery&lt;/a&gt; will only index text files, that means files without an svn:mime-type property or where the property is set to something like “text/*”. At work I wondered why I couldn’t find some words that I know must exist. It turned out that subversion marks files stored as UTF-8 files with BOM as binary, using svn:mime-type application/octet-stream. This forces the indexer to ignore the content of the file. &lt;/p&gt;  &lt;p&gt;I used SvnQuery to find all files that are marked as binary, e.g. &lt;strong&gt;t:app* .js&lt;/strong&gt; finds all javascript files and &lt;strong&gt;t:app* .cs &lt;/strong&gt;finds all C# files. With the download button at the bottom of the results page I downloaded a text files with the results. Because &lt;strong&gt;&lt;font face="Courier New"&gt;svn propdel svn:mime-type [PATH]&lt;/font&gt; &lt;/strong&gt;can work only on one file (it has no --targets option) I had to modify the text file to create a small batch script like this:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;svn propdel svn:mime-type c:\workspaces\javascript\file1.js     &lt;br /&gt;svn propdel svn:mime-type c:\workspaces\javascript\file1.js      &lt;br /&gt;svn propdel svn:mime-type c:\workspaces\javascript\file1.js      &lt;br /&gt;…&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;After this change indexing worked again. I now run a daily query that ensures that no sources files are marked as binary.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-6648985088938071852?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/6648985088938071852/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/02/removing-mime-type-of-files-in.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6648985088938071852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6648985088938071852'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/02/removing-mime-type-of-files-in.html' title='Removing the mime-type of files in Subversion with SvnQuery'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-5110707020694268338</id><published>2011-01-23T17:24:00.001+01:00</published><updated>2011-01-23T17:24:07.747+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Frequent Errors'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Subversion'/><title type='text'>What means “Skipped” in the subversion merge log?</title><content type='html'>&lt;p&gt;I have seen many people who tend to ignore the “Skipped” messages that are sometimes displayed when you do a merge with subversion:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_sIFn2ZjjKAY/TTxWGVy9AUI/AAAAAAAAAEU/7yG_srJoRr4/s1600-h/skipped_merge_tortoise%5B5%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="skipped_merge_tortoise" border="0" alt="skipped_merge_tortoise" src="http://lh3.ggpht.com/_sIFn2ZjjKAY/TTxWG5RLRjI/AAAAAAAAAEY/CFhM3BWo-hw/skipped_merge_tortoise_thumb%5B3%5D.png?imgmax=800" width="504" height="240" /&gt;&lt;/a&gt;&amp;#160;&lt;a href="http://lh6.ggpht.com/_sIFn2ZjjKAY/TTxWHdWMfNI/AAAAAAAAAEc/KLUQFSnDcj0/s1600-h/skipped_merge_cmd%5B11%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="skipped_merge_cmd" border="0" alt="skipped_merge_cmd" src="http://lh5.ggpht.com/_sIFn2ZjjKAY/TTxWH6QxndI/AAAAAAAAAEg/0mpIV-FNuVg/skipped_merge_cmd_thumb%5B7%5D.png?imgmax=800" width="444" height="172" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The “Skipped” message means that the merge operations wants to create or modify a file but that file already exists in your working copy and is not under version control (added to the repository:&lt;a href="http://lh3.ggpht.com/_sIFn2ZjjKAY/TTxWIU55H3I/AAAAAAAAAEk/767fdIzIF4k/s1600-h/unversioned_file%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="unversioned_file" border="0" alt="unversioned_file" src="http://lh6.ggpht.com/_sIFn2ZjjKAY/TTxWIgIjkgI/AAAAAAAAAEo/0fpk0zrYctU/unversioned_file_thumb.png?imgmax=800" width="162" height="141" /&gt;&lt;/a&gt;This can easily happen if you do a forward merge from trunk to a brunch and revert your local changes to the working copy (maybe because some manual merges went wrong). The revert command will leave new files as orphaned files in the working copy.&lt;/p&gt;  &lt;p&gt;Don’t ignore those warnings! If you commit a working copy with “Skipped” warnings and do a backward (reintegrate) merge from branch to trunk, subversion will &lt;strong&gt;delete&lt;/strong&gt; the formerly skipped files from the trunk! &lt;strong&gt;As a rule, you should never ignore “Skipped” warnings and if they occur fix the root problem then repeat the merge on a clean working copy.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_sIFn2ZjjKAY/TTxWJE0JTxI/AAAAAAAAAEs/FxvOFLURTc0/s1600-h/merge_deletes%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="merge_deletes" border="0" alt="merge_deletes" src="http://lh5.ggpht.com/_sIFn2ZjjKAY/TTxWJlC2xRI/AAAAAAAAAEw/aUUzqFR6WBw/merge_deletes_thumb%5B1%5D.png?imgmax=800" width="545" height="284" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-5110707020694268338?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/5110707020694268338/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2011/01/what-means-skipped-in-subversion-merge.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/5110707020694268338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/5110707020694268338'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2011/01/what-means-skipped-in-subversion-merge.html' title='What means “Skipped” in the subversion merge log?'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_sIFn2ZjjKAY/TTxWG5RLRjI/AAAAAAAAAEY/CFhM3BWo-hw/s72-c/skipped_merge_tortoise_thumb%5B3%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-522692922646593198</id><published>2010-11-21T20:04:00.001+01:00</published><updated>2010-11-21T20:05:10.145+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><title type='text'>C# Object Initialization Wonders</title><content type='html'>&lt;p&gt;Since I am coding a lot in JavaScript recently I tend to use &lt;a href="http://msdn.microsoft.com/en-us/library/bb384062.aspx"&gt;C# Object Initialization&lt;/a&gt; more often than before. Last evening I had an astonishing experience …&lt;/p&gt;  &lt;p&gt;I had a class Foo&lt;/p&gt;  &lt;div style="padding-bottom: 2px; background-color: #fff7d5; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Foo&lt;/span&gt;     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; Data { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;and wrote this object initializer:&lt;/p&gt;  &lt;div style="padding-bottom: 2px; background-color: #fff7d5; padding-left: 5px; padding-right: 5px; white-space: nowrap; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; bar = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Foo&lt;/span&gt; {Data = {&lt;span style="color: #ff00ff"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;, &lt;span style="color: #ff00ff"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;}};&lt;/div&gt;  &lt;p&gt;The first wonder was that this code actually compiles. Fine, nearly as compact as JavaScript. But at runtime I had a mysterious error. When I finally inspected the Data property with &lt;span style="padding-bottom: 2px; background-color: #fef9d3; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #2b91af"&gt;Debug&lt;/span&gt;.WriteLine(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Join(&lt;span style="color: #ff00ff"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;, bar.Data));&lt;/span&gt; it contains &lt;strong&gt;1, 2, a, b&lt;/strong&gt; and not the expected &lt;strong&gt;a, b&lt;/strong&gt;. So the former assignment to Data was not setting the property but somehow adding to the existing content. Looking into the Foo constructor proved this.&lt;/p&gt;  &lt;div style="padding-bottom: 2px; background-color: #fef9d3; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Foo()     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Data = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;{&lt;span style="color: #ff00ff"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;, &lt;span style="color: #ff00ff"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;};     &lt;br /&gt;}&lt;/div&gt;  &lt;p&gt;The compiler interpreted the assignment to the Data property as a collection initializer and was just calling Add() for “a” and “b” on the existing collection. To overwrite the existing collection I had to specify a new type:&lt;/p&gt;  &lt;div style="padding-bottom: 2px; background-color: #fef9d3; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; bar = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Foo&lt;/span&gt; {Data = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;{&lt;span style="color: #ff00ff"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;, &lt;span style="color: #ff00ff"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;}};&lt;/div&gt;  &lt;p&gt;I’m not really sure if this is a bug or a feature …&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-522692922646593198?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/522692922646593198/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/11/c-object-initialization-wonders.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/522692922646593198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/522692922646593198'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/11/c-object-initialization-wonders.html' title='C# Object Initialization Wonders'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-9144924125957909886</id><published>2010-10-14T17:15:00.001+02:00</published><updated>2010-10-14T17:15:46.435+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TortoiseSVN'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Subversion'/><title type='text'>Always “Compare whitespaces” when merging</title><content type='html'>&lt;p&gt;I am working in an environment where we develop features in branches, using Subversion and TortoiseSVN. Every day we do a forward merge from the trunk to branch. When the feature is complete the branch is merged back to the trunk and the branch gets deleted.&amp;#160; Recently I noticed a lot of whitespace issues, like wrong indentations. It turned out that the reason for this is one commonly misunderstood option in the merge dialog of TortoiseSVN: &lt;strong&gt;“Compare whitespaces”&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_sIFn2ZjjKAY/TLcen9I1NaI/AAAAAAAAAEA/5gZ1WwX6_8U/s1600-h/CompareWhitespace14.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Compare Whitespace" border="0" alt="Compare Whitespace" src="http://lh4.ggpht.com/_sIFn2ZjjKAY/TLceoXvL_vI/AAAAAAAAAEE/lIwPi_NCDz0/CompareWhitespace_thumb8.png?imgmax=800" width="524" height="480" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The default settings of this dialog are the correct ones but many developers automatically click on one of the &amp;quot;Ignore whitespace&amp;quot; options. Why? Because they are using this option in their diff tools all the time. But what is good when comparing is actually a very bad thing when merging. Imagine that someone surrounds some existing code with an “if” or “try-catch” block. That would indent the existing code which is just a whitespace change. The new indentation will not be merged to the branch if you choose one of the ignore options! The same is true if you changed tabs to spaces or inserted some empty lines. And now comes the worst problem: You chose to ignore whitespaces on forward branches. But you didn't ignore them when merging back to the trunk. Now you actually have erased all whitespace changes from the trunk between the time you created the branch and the time you merged it back!&lt;/p&gt;  &lt;p&gt;&amp;lt;Insert picture here&amp;gt;&lt;/p&gt;  &lt;p&gt;So remember one thing: &lt;strong&gt;Always choose &amp;quot;Compare whitespaces&amp;quot; in the merge options!&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/7873754566403770354-9144924125957909886?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/9144924125957909886/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/10/always-compare-whitespaces-when-merging.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/9144924125957909886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/9144924125957909886'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/10/always-compare-whitespaces-when-merging.html' title='Always “Compare whitespaces” when merging'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_sIFn2ZjjKAY/TLceoXvL_vI/AAAAAAAAAEE/lIwPi_NCDz0/s72-c/CompareWhitespace_thumb8.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-1608012770965282172</id><published>2010-08-21T10:11:00.001+02:00</published><updated>2010-11-21T19:00:36.897+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Subversion'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>Speed up your Subversion repository</title><content type='html'>&lt;p&gt;Normally, I am satisfied with the performance of Subversion. I used to work on a 20GB repository with ca 20000 revisions, 20 developers in a not so fast local network. Daily business operations like update, commit were done in a few seconds. &lt;/p&gt;  &lt;p&gt;Now I work with 30 developers on 4GB repository with ca 18000 revision in a super fast network. And the performance sucks, compared to my former experiences. A checkout of a 120MB working copy takes more than 10 minutes. Updating (without any changes) takes at least 40 seconds. &lt;/p&gt;  &lt;p&gt;So what’s the problem here? I have some guesses but are not yet sure about the real reasons. But here are my suggestions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Use the FSFS mode&lt;/strong&gt; (I hope nobody is using Berkeley DB anymore?)       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Use &lt;/strong&gt;&lt;a href="http://subversion.apache.org/docs/release-notes/1.5.html#fsfs-sharding"&gt;&lt;strong&gt;Sharding&lt;/strong&gt;&lt;/a&gt;. This affects the way how the repository is stored on the server. At most 1000 files are put in one directory then another directory will be created. This helps a lot if the underlying file system performance worse with an increasing number of files per directory.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://subversion.apache.org/docs/release-notes/1.6.html#filesystem-improvements"&gt;&lt;strong&gt;Pack&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; your repository regularly&lt;/strong&gt;. Normally, each revision is stored as a single file. If you have a sharded repository then &lt;font face="Courier New"&gt;&lt;em&gt;svnadmin pack&lt;/em&gt; &lt;/font&gt;will convert all full shards into one big files. This saves space and helps the OS to reduce I/O and improve caching.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Use the svn:// protocol&lt;/strong&gt;. The http and https protocols are just a tunnel for &lt;a href="http://www.webdav.org/deltav/"&gt;WebDAV delta-v&lt;/a&gt; which is a quite chatty protocol. For each file you need a full roundtrip from the client. On high latency networks this could be a real bottleneck. The svn protocol is much faster and consumes less cpu cycles. On my test machine a complete checkout of 120MB working copy took on average 5min 20s over https:// and only 4min over svn://.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Check your commit hooks&lt;/strong&gt;. Perhaps you have installed some expensive commit hooks. On Windows, try using &lt;a href="http://svnquery.tigris.org/servlets/ProjectProcess?pageID=o0dpdE"&gt;RunDetached&lt;/a&gt; to prevent subversion from waiting for the hook to finish. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Beware of Polling Build Agents&lt;/strong&gt;. If you are Continuous Integration there will be some kind of mechanism in place to detect changes in the repositories. The most efficient one is a post commit hook, but for example &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl.NET&lt;/a&gt; and &lt;a href="http://www.jetbrains.com/teamcity/"&gt;TeamCity&lt;/a&gt; use an inefficient polling approach that is basically doing an “svn log” and parsing the output. Doing this over https every second from forty build agents can easily bring up the load on the repository server to 100%. A more efficient polling mechanism would be to store the latest revision and query only the newest revision of the repository. This is only implemented by some custom plugins.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Monitor I/O load&lt;/strong&gt;. Still, when people think of performance they think of CPU performance. But for the subversion repository I/O is the limiting resource. An update or checkout operation will do many small reads on different areas of the repository. Therefore the average access time is the most important factor. If your repository is running on a virtual machine make sure that the repository is located on a physical drive that is &lt;strong&gt;exclusively &lt;/strong&gt;reserved for this purpose. Use a SSD or at least a 10,000 RPM drive.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Store your repository on a&amp;#160; Intel Solid State Disk. &lt;/strong&gt;The disk should be exclusively reserved for use by the repository. No other application should touch it. This is the simplest and most effective way to improve performance.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Optimize your working copy&lt;/strong&gt;. Change the layout so you can do partial updates. Try to use &lt;a href="http://subversion.apache.org/docs/release-notes/1.6.html#sparse-directory-exclusion"&gt;&lt;em&gt;&lt;font face="Courier New"&gt;svn update –-svn-depth -exclude&lt;/font&gt;&lt;/em&gt;&lt;/a&gt; to exclude parts you don’t need in your day-to-day work. Remove files you don’t need.&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Note: All tips are written at the time of Subversion 1.6 and increase the server performance. Subversion 1.7 will improve the local working copy which theoretically should also increase the client performance. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-1608012770965282172?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/1608012770965282172/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/08/speed-up-your-subversion-repository.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/1608012770965282172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/1608012770965282172'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/08/speed-up-your-subversion-repository.html' title='Speed up your Subversion repository'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-5525329490447739798</id><published>2010-08-08T23:41:00.001+02:00</published><updated>2010-08-08T23:41:12.274+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='DI'/><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><title type='text'>Requirements for a Dependency Injection Container</title><content type='html'>&lt;p&gt;Recently I was asked by a coworker about my requirements for a DI Container as part of a poll to all developers. My first reaction was to answer with the famous Ford quote “&lt;em&gt;If I’d asked people what they wanted, they would have said faster horses.&lt;/em&gt;” This was because I personally realized the benefits of using a DI container only after working with one in a real project. Before this experience I wasn’t really able to give reasons why I should use one at all. Sure, I wanted one to try out, because I had the feeling it could be useful, but giving requirements was out of scope. &lt;/p&gt;  &lt;p&gt;Today I have worked with &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt; and much more with &lt;a href="http://unity.codeplex.com/"&gt;Unity&lt;/a&gt;. I know &lt;a href="http://structuremap.github.com/structuremap/index.html"&gt;StructureMap&lt;/a&gt; and &lt;a href="http://code.google.com/p/autofac/"&gt;Autofac&lt;/a&gt; (but &lt;a href="http://www.castleproject.org/container/index.html"&gt;Castle Windsor&lt;/a&gt; is still on my list :-). I believe that DI containers should be provided by the .NET framework (and sooner or later will be) just like the collection classes. No big up front requirements analysis should be done because a DI container is no longer rocket science. Just start using one that is accepted by the community. If you haven’t used one you wouldn’t know what a DI can do for you. If you have used only one you would repeat features as requirements. If you know more than one you would list the features you love most. &lt;/p&gt;  &lt;p&gt;This is my list of important and useful features:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Container setup should be possible in code with a readable and fluent API. Use explicit xml configuration only as a last resort (too much bad experiences with Spring.NET xml configuration). Setup with code allows intellisense and checking at compile time. Most setups will be done in test code, not in production code!&lt;/li&gt;    &lt;li&gt;Wiring dependencies should be possible by conventions or attribute based. Use explicit wiring only as a last resort (bad maintainability).&lt;/li&gt;    &lt;li&gt;Understandable error message and diagnostic help if something went wrong when constructing/resolving a type.&lt;/li&gt;    &lt;li&gt;Constructor and property must be possible, event and method injections would be nice to have.&lt;/li&gt;    &lt;li&gt;Nested Container. That means you can create a container that inherits from an existing one and add or overwrite some mappings or strategies. Useful for test code.&lt;/li&gt;    &lt;li&gt;Extensibility: it should be possible to implement autofaking or automocking strategies (described &lt;a href="http://weblogs.asp.net/rosherove/archive/2008/04/14/creating-a-automockingcontainer-with-microsoft-unity-pretty-darn-simple.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://elegantcode.com/2010/01/03/unitymoq-automocker-or-automockingcontainer/"&gt;here&lt;/a&gt;) which are extremely useful for unit testing.&lt;/li&gt;    &lt;li&gt;Lifetime of objects should be configurable in different ways (free, singleton, container bound, thread bound, …).&lt;/li&gt;    &lt;li&gt;If object lifetime can be bound to the container lifetime the disposal of the container should also dispose all contained objects.&lt;/li&gt;    &lt;li&gt;Automatic factories. The possibility to not inject a single object but a generic factory, say Func&amp;lt;T&amp;gt;(), without explicit configuration.&lt;/li&gt;    &lt;li&gt;The container should have at least two distinct interfaces, one for configuring the container and one for resolving/constructing types. &lt;/li&gt;    &lt;li&gt;Static Service Locator Facade (with override possibility) for working with legacy code.&lt;/li&gt;    &lt;li&gt;Partial construction if you have no control over object creation (for frameworks like WPF or ASP.NET) but still want to use you container to inject some dependencies.&lt;/li&gt;    &lt;li&gt;Should have no or very tedious interface to specify constructor parameters at resolve time. Reason: if you do so you don’t use your DI container as intended.&lt;/li&gt;    &lt;li&gt;… (to be continued) …&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/7873754566403770354-5525329490447739798?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/5525329490447739798/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/08/requirements-for-dependency-injection.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/5525329490447739798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/5525329490447739798'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/08/requirements-for-dependency-injection.html' title='Requirements for a Dependency Injection Container'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-6642270543066073508</id><published>2010-07-25T12:52:00.001+02:00</published><updated>2010-07-25T12:54:01.381+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ReSharper'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>How to change the ReSharper naming style for test methods</title><content type='html'>&lt;p&gt;For normal methods I use the Pascal casing convention (or UperCamelCase as it is called by ReSharper). But in unit tests readability rules and therefore I use very long names like:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8de41a0a-cf18-4479-bfd2-8b351031bbec" class="wlWriterEditableSmartContent"&gt; &lt;div class="code-container"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; MethodUnderTest_Scenario_ExpectedResult()&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;ReSharper marks them as violating the naming style, which is quite annoying because this distracts from real problems. Luckily there is a way to tell ReSharper to use a different naming convention for test methods. It is a little bit hidden in the ReSharper options, but here is the way to go:&lt;/p&gt;  &lt;p&gt;ReSharper Options –&amp;gt; Naming Style –&amp;gt; Advanced settings&lt;a href="http://lh4.ggpht.com/_sIFn2ZjjKAY/TEwXanBVVBI/AAAAAAAAADg/C3mPTtlP1Qc/s1600-h/image%5B17%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_sIFn2ZjjKAY/TEwXcT54p3I/AAAAAAAAADk/19WKt_ILCrc/image_thumb%5B7%5D.png?imgmax=800" width="630" height="524" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_sIFn2ZjjKAY/TEwXc0-V_OI/AAAAAAAAADo/1ymVVIVfkbs/s1600-h/image%5B18%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_sIFn2ZjjKAY/TEwXdpxnF4I/AAAAAAAAADs/rLgi71eHzx8/image_thumb%5B8%5D.png?imgmax=800" width="498" height="506" /&gt;&lt;/a&gt;     &lt;br /&gt;In “Affected entities” mark “Test method (property)” and disable inspections.&lt;a href="http://lh4.ggpht.com/_sIFn2ZjjKAY/TEwXewGkckI/AAAAAAAAADw/kaF2GEEPYgQ/s1600-h/image%5B19%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_sIFn2ZjjKAY/TEwXgH1ZGvI/AAAAAAAAAD0/dsS-a3G-RKE/image_thumb%5B9%5D.png?imgmax=800" width="630" height="442" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now you have no warnings in your tests anymore that complain of inconsistent naming styles. Naming styles for non test classes and methods are still working as before. This was tested with ReSharper 5.1.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-6642270543066073508?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/6642270543066073508/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/07/how-to-change-resharper-naming-style.html#comment-form' title='7 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6642270543066073508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6642270543066073508'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/07/how-to-change-resharper-naming-style.html' title='How to change the ReSharper naming style for test methods'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_sIFn2ZjjKAY/TEwXcT54p3I/AAAAAAAAADk/19WKt_ILCrc/s72-c/image_thumb%5B7%5D.png?imgmax=800' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-7505512166143835241</id><published>2010-07-05T14:03:00.001+02:00</published><updated>2010-07-05T14:03:25.123+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><title type='text'>Don’t use keyword substitution if you use branches</title><content type='html'>&lt;p&gt;Many version control systems use some kind of keyword substitution, e.g. in Subversion the keyword &lt;font face="Courier New"&gt;$Author:$&lt;/font&gt; gets replaced on every commit through the committing author, say &lt;font face="Courier New"&gt;$Author: crodemeyer$.&lt;/font&gt; Now imagine that you have several branches of your trunk and that each branch is modified in parallel. When the time comes to merge back the changes to the trunk you will get many conflicts. They cannot be resolved automatically because in every branch the same line of code has been changed. Indeed you have entirely broken&amp;#160; automatic reintegration of branches if you use keyword replacement.&lt;/p&gt;  &lt;p&gt;Fortunately Subversion has the possibility to control keyword substitution with the &lt;em&gt;svn:keywords&lt;/em&gt; property. Be a hero and use “&lt;font face="Courier New"&gt;svn pd svn:keywords –R”&lt;/font&gt; to disable keyword substitution completely.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-7505512166143835241?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/7505512166143835241/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/07/dont-use-keyword-substitution-if-you.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/7505512166143835241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/7505512166143835241'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/07/dont-use-keyword-substitution-if-you.html' title='Don’t use keyword substitution if you use branches'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-6847584393712563070</id><published>2010-05-02T16:20:00.001+02:00</published><updated>2010-05-02T16:20:13.933+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Frequent Errors'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><title type='text'>Always databind SelectedItem before ItemsSource</title><content type='html'>&lt;p&gt;The order in which bindings are defined in Xaml are relevant. Look at this Example: I have a ComboBox and a ViewModel. The ItemsSource of the ComboBox is bound to the Repositories property and SelectedItem is bound to SelectedRepository.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d2b5e8b4-27c3-4431-b0fc-bb94892ccb1e" class="wlWriterEditableSmartContent"&gt; &lt;div class="code-container"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;ComboBox&lt;/span&gt;&lt;span style="color:#ff0000"&gt; ItemsSource&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515"&gt;Binding&lt;/span&gt;&lt;span style="color:#ff0000"&gt; Repositories}&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#ff0000"&gt; SelectedItem&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515"&gt;Binding&lt;/span&gt;&lt;span style="color:#ff0000"&gt; SelectedRepository}&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;quot; /&amp;gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;The constructor of the ViewModel initializes the Repositories with a non empty collection and sets the SelectedRepository to the first element. &lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6669313c-7763-460b-874c-e834c1158a3e" class="wlWriterEditableSmartContent"&gt; &lt;div class="code-container"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; ViewModel()&lt;br&gt; {&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;Repositories = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;&amp;gt; {&lt;span style="color:#ff00ff"&gt;&amp;quot;First&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff00ff"&gt;&amp;quot;Second&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff00ff"&gt;&amp;quot;Third&amp;quot;}&lt;/span&gt;;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;SelectedRepository = Repositories[0];&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/p&gt;  &lt;p&gt;Yet, immediately after starting, I got null reference exceptions from other databound properties that are referencing the SelectedRepository property! After a little debugging I found out that when assigning the ViewModel to the DataContext of the view, the Binding Engine assigns null to the SelectedRepository! If you change the declaration of Databinding everything works as expected:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:840367e0-afa4-47f3-82b9-a7bedb79556f" class="wlWriterEditableSmartContent"&gt; &lt;div class="code-container"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#ff00ff"&gt;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;ComboBox&lt;/span&gt;&lt;span style="color:#ff0000"&gt; SelectedItem&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515"&gt;SelectedRepository}&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#ff0000"&gt; ItemsSource&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&amp;quot;Repositories&amp;quot; /&amp;gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; Conclusion: the order of databinding declaration matters!  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-6847584393712563070?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/6847584393712563070/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/05/always-databind-selecteditem-before.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6847584393712563070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6847584393712563070'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/05/always-databind-selecteditem-before.html' title='Always databind SelectedItem before ItemsSource'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-6115842990958109284</id><published>2010-04-30T14:15:00.003+02:00</published><updated>2011-08-23T22:20:41.883+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Unit Tests'/><title type='text'>Using Assembly.CodeBase to get the location if shadow copied</title><content type='html'>A long time I had problems with &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt; tests that needed to access files living relative to the tested dll. NUnit (and &lt;a href="http://www.jetbrains.com/resharper/"&gt;Resharper&lt;/a&gt;) are shadow copying a dll before running the test, so the &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.assembly.location.aspx"&gt;Location&lt;/a&gt; property of an assembly returns the path to the shadow folder and not the original location where the expected file lives. My solution was to disable shadow copying in NUnit and Resharper. But every now and then I forgot to disable it in new projects. The result was spending time with debugging until I remembered to disable shadow copying. &lt;br /&gt;
But now I have found by chance a much better solution, which is more robust and also useful for other shadow copying scenarios like hosting WCF services in IIS. You can use the assemblies &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.assembly.codebase(v=VS.100).aspx"&gt;CodeBase&lt;/a&gt; property to get the original location. The only drawback is that the codebase is formatted as a Uri. It normally includes a file protocol “file:///”&amp;nbsp; and uses slashes ‘/’ instead of backslashes ‘\’, so you need to modify the returned string a bit:&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8b12f3c0-cdfe-411c-ab70-38dd92d11585" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;
&lt;div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;"&gt;
&lt;div style="background-color: white; max-height: 300px; overflow-x: auto; overflow-y: auto; padding-bottom: 2px; padding-left: 5px; padding-right: 5px; padding-top: 2px;"&gt;
&lt;span class="Apple-style-span" style="color: #2b91af;"&gt;var&lt;/span&gt; assembly = Assembly.GetExecutingAssembly();&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: blue;"&gt;var&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; path = assembly.CodeBase.Replace(&lt;span style="color: #a31515;"&gt;"file:///"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;).Replace(&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;"/"&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;, &lt;/span&gt;&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;"\\"&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
I believe that in certain scenarios you may see other protocols (perhaps http://) but for unit testing scenarios that relieves from the pain of remembering to disable shadow copying.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-6115842990958109284?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/6115842990958109284/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/04/using-assemblycodebase-to-get-location.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6115842990958109284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6115842990958109284'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/04/using-assemblycodebase-to-get-location.html' title='Using Assembly.CodeBase to get the location if shadow copied'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-4229190229694301071</id><published>2010-02-25T17:21:00.001+01:00</published><updated>2010-02-25T17:21:03.894+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><title type='text'>Mercurial tutorial by Joel Spolsky</title><content type='html'>&lt;p&gt;A really good mercurial tutorial (especially for those who are damaged by subversion) by Joel Spolsky:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a title="http://hginit.com/index.html" href="http://hginit.com/index.html"&gt;http://hginit.com/index.html&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/7873754566403770354-4229190229694301071?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/4229190229694301071/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/02/mercurial-tutorial-by-joel-spolsky.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/4229190229694301071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/4229190229694301071'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/02/mercurial-tutorial-by-joel-spolsky.html' title='Mercurial tutorial by Joel Spolsky'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-5498339666719097779</id><published>2010-02-23T13:51:00.001+01:00</published><updated>2010-02-23T13:52:53.130+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Quotation'/><title type='text'>Wissensvermittlung und ein Konfuzius Zitat</title><content type='html'>&lt;p&gt;Ich habe gerade ein sehr passendes Zitat von Konfuzius gelesen (Papier, OBJEKTspektrum 03/2009) indem ich mich selbst wiedererkenne, wenn es um Wissensvermittlung geht:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;“Erkläre es mir und ich werde es vergessen. Zeige es mir und ich werde mich erinnern. Lass es mich selber machen und ich werde es verstehen.”&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-5498339666719097779?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/5498339666719097779/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/02/wissensvermittlung-und-ein-konfuzius.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/5498339666719097779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/5498339666719097779'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/02/wissensvermittlung-und-ein-konfuzius.html' title='Wissensvermittlung und ein Konfuzius Zitat'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-9198591133335827614</id><published>2010-02-23T12:43:00.001+01:00</published><updated>2010-02-23T12:46:14.275+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Blend'/><title type='text'>Expression Blend 3 Design Time Attributes</title><content type='html'>&lt;p&gt;Only a few people (including me until a few weeks ago) know that Expression Blend supports so called “Design Time Attributes”. These properties are very valuable to get “Design Time Data” into Blend. Without those example data designing DataTemplates is cumbersome and no fun. Those Design Time Attributes are not documented at all and I found out about them only by chance, reading some blogs. It seems that they are officially introduced with VS 2010 and documented &lt;a href="http://msdn.microsoft.com/en-us/library/ee839627(VS.100).aspx"&gt;there&lt;/a&gt;. Nevertheless they are fully functional with VS 2008 because they are &lt;strong&gt;ignored&lt;/strong&gt; by the compiler and only used by design tools like blend.&lt;/p&gt;  &lt;p&gt;All Design Time Attributes live in the d: namespace:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;d:DesignHeight&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="450"&gt;In Blend, there is a special handle you can use to modify the d:DesignHeight and d:DesignWidth attributes without modifying the real Height attribute. This is handy if you just want to test some resizing logic.&lt;a href="http://lh5.ggpht.com/_sIFn2ZjjKAY/S4O_WVGgh0I/AAAAAAAAADQ/FszPhMwc8Gk/s1600-h/DesignTimeHeight%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="DesignTimeHeight" border="0" alt="DesignTimeHeight" src="http://lh6.ggpht.com/_sIFn2ZjjKAY/S4O_WwC_bPI/AAAAAAAAADU/TE6rH6kjfdY/DesignTimeHeight_thumb%5B2%5D.png?imgmax=800" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;d:DesignWidth&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="450"&gt;&lt;a href="http://lh3.ggpht.com/_sIFn2ZjjKAY/S4O_XPTDfzI/AAAAAAAAADY/rUQyP7R_nvQ/s1600-h/DesignTimeWidth%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="DesignTimeWidth" border="0" alt="DesignTimeWidth" src="http://lh6.ggpht.com/_sIFn2ZjjKAY/S4O_XR4hD4I/AAAAAAAAADc/PDM2j2fEv0I/DesignTimeWidth_thumb%5B2%5D.png?imgmax=800" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;d:DataContext&lt;/td&gt;        &lt;td valign="top" width="450"&gt;Lets you specify the DataContext used at design time. Example: d:DataContext={StaticResource MyDataContextObject}, or even better&amp;#160;&amp;#160;&amp;#160; use d:DesignInstance&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;d:DesignInstance&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="450"&gt;d:DataContext=&amp;quot;{d:DesignInstance Type=local:MyDataContext, IsDesignTimeCreatable=True}&amp;quot;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;d:DesignData&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="450"&gt;needs VS2010, links to a sample data object defined in a xaml file&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;d:DesignSource&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="450"&gt;sets the Source property of a CollectionViewSource at design time&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-9198591133335827614?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/9198591133335827614/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/02/expression-blend-3-design-time.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/9198591133335827614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/9198591133335827614'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/02/expression-blend-3-design-time.html' title='Expression Blend 3 Design Time Attributes'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_sIFn2ZjjKAY/S4O_WwC_bPI/AAAAAAAAADU/TE6rH6kjfdY/s72-c/DesignTimeHeight_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-7628959586223601248</id><published>2010-02-15T21:51:00.001+01:00</published><updated>2010-02-15T21:51:13.567+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><title type='text'>You are not thy user</title><content type='html'>&lt;p&gt;I have just finished reading Dave S. Platt’s book “&lt;a href="http://www.whysoftwaresucks.com/"&gt;Why Software SUCKS&lt;/a&gt;”, and it was a lot of fun. I like his polemic and exaggerated way to make his point. And I strongly believe that at its heart he is absolutely right in his findings.&lt;/p&gt;  &lt;p&gt;The believe of programmers, that the user of a program is like him, causes much if not all of the trouble with the usability of programs nowadays. “You are not your user” says Platt. And if a programmer thinks “If I design a user interface that I like, the users will love it.” Dave says “&lt;em&gt;Wrong!&lt;/em&gt;”. This is not new knowledge, in Germany we know it as “&lt;a href="http://www.jochenduckeck.de/Hinnerk/SoftErg/Paper/Gesamt.html"&gt;Der Trugschluß der egozentrischen Intuition&lt;/a&gt;”, but no one before described it in such a catchy way.&lt;/p&gt;  &lt;p&gt;But I don’t like the oversimplification that always the programmer is the bad guy. In my experience the same amount of damage to usability is done by every person in the development chain, that means QA people, project managers, sales people, directors and the people responsible for buying.&lt;/p&gt;  &lt;p&gt;Think of Joe Programmer, who actually knows something about user interface design and has studied it for several years. He has seen the actual users in person and at work and knows the problem thy want to solve. He has designed a beautiful user interface and now his boss comes in, demanding a short review. “I don’t like that. My favorite GeekyApp does it like this, I like it and therefore it must be liked by the customer. Please change your software so that it does work like my beloved GeekyApp.” Ouch. Next comes the QA guy: “I need to test the performance of your app and I don’t like to manually create 1000th entries of test data, could you please add some batch generator to your UI, it would help me doing my job faster!” Argh, no user will ever do what you poor QA guy have to do. Now the sales people cry: “I need more colors and more animations. Otherwise I can’t sell it!” Sigh. Then the project manager declares: “I need a quick way to discover what is going on in the customers installation, please give me more analysis features.” Last but not least, even the people who are responsible for buying the software force him to cripple the user experience because the prefer to buy what they like and not what their users like. Poor users, no wonder why so many software sucks.&lt;/p&gt;  &lt;p&gt;My tip for Joe Programmer: Not only the final user has needs, everyone in the chain has his own needs. You cannot ignore them but must find a way to satisfy them adequately. You can give QA an automation api without compromising the user interface. You can build a system diagnosis view, that the normal user never will see. You can argue with sales and your boss (point them to Platt’s book). Offer some “baffle” mode for presentations and to convince the buying agent. This is a lot of work but by reading “Why Software SUCKS” you have a chance to convince the other people that they are also not like your users. At least it helps to detect the trap before falling into it.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-7628959586223601248?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/7628959586223601248/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/02/you-are-not-thy-user.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/7628959586223601248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/7628959586223601248'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/02/you-are-not-thy-user.html' title='You are not thy user'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-408656228733105171</id><published>2010-01-23T18:17:00.001+01:00</published><updated>2010-01-23T18:17:10.982+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Unit Tests'/><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><title type='text'>New NUnit syntax of how to expect exceptions</title><content type='html'>&lt;p&gt;I have just stumbled upon a new beautiful syntax of how you can write a unit tests that expects that a method throws a certain exeception or an exception derived from it. First your test fixture needs to inherit from AssertionHelper which gives you the static Expect method. Then you can implement a test like this:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a9dbc84f-5b0b-4a4a-a070-1c182ae3148d" class="wlWriterEditableSmartContent"&gt; &lt;div class="code-container"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;[&lt;span style="color:#2b91af"&gt;Test&lt;/span&gt;]&lt;br&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; GetExternals_InvalidWorkingCopy_ThrowsSvnException()&lt;br&gt; {&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008000"&gt;// Arange&lt;/span&gt;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; ep = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkingCopyCache&lt;/span&gt;();&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008000"&gt;// Act &amp;amp; Assert&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;Expect(() =&amp;gt; ep.Get(&lt;span style="color:#a31515"&gt;@&amp;quot;X:&amp;#92;Dummy&amp;quot;&lt;/span&gt;), &lt;span style="color:#2b91af"&gt;Throws&lt;/span&gt;.InstanceOf&amp;lt;&lt;span style="color:#2b91af"&gt;SvnException&lt;/span&gt;&amp;gt;());&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;To be honest this constraint based syntax exists for quite a while now, but I just didn’t know before. IMHO it is very powerful and readable, compared to other solutions. For more details about how NUnit evolved to finally arrived at this syntax see this blog &lt;a title="http://nunit.com/blogs/?p=63" href="http://nunit.com/blogs/?p=63"&gt;http://nunit.com/blogs/?p=63&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/7873754566403770354-408656228733105171?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/408656228733105171/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2010/01/new-nunit-syntax-of-how-to-expect.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/408656228733105171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/408656228733105171'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2010/01/new-nunit-syntax-of-how-to-expect.html' title='New NUnit syntax of how to expect exceptions'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-2286059703362310571</id><published>2009-12-19T10:54:00.002+01:00</published><updated>2009-12-19T12:02:15.625+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>AssemblyAttributes</title><content type='html'>This is a cute little helper class that is useful for almost every .NET or Silverlight application that displays some information about itself (think “About Box”). It retrieves the values of the following assembly attributes in an easy and consistent manner:   &lt;br /&gt;  &lt;ul&gt;   &lt;li&gt;Title &lt;/li&gt;    &lt;li&gt;Product &lt;/li&gt;    &lt;li&gt;Copyright &lt;/li&gt;    &lt;li&gt;Company &lt;/li&gt;    &lt;li&gt;Description &lt;/li&gt;    &lt;li&gt;Trademark &lt;/li&gt;    &lt;li&gt;Configuration &lt;/li&gt;    &lt;li&gt;Version &lt;/li&gt;    &lt;li&gt;FileVersion &lt;/li&gt;    &lt;li&gt;InformationalVersion &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Doing so is a piece of cake for every experienced developer but getting these information for the 100th time manually through reflection is quite cumbersome. And junior developers sometimes don’t know where to start and get lost in learning about reflection and attributes.    &lt;br /&gt;With the help of generics and lambdas you can code an elegant class that solves this problem one and for all. Usage is like this: &lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:78de5737-a555-447e-8cab-884587aa7985" class="wlWriterEditableSmartContent"&gt; &lt;div class="code-container"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#2b91af"&gt;AssemblyAttributes&lt;/span&gt; assembly = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AssemblyAttributes&lt;/span&gt;();&lt;br&gt; &lt;br&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; title = assembly.Title;&lt;br&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; version = assembly.Version;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;br /&gt;And this is the full source:   &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1d3a0d17-dd65-4ee2-acfc-333f3d8823c4" class="wlWriterEditableSmartContent"&gt; &lt;div class="code-container"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt; &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Easy access to common Assembly attributes.&lt;/span&gt;&lt;br&gt; &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AssemblyAttributes&lt;/span&gt;&lt;br&gt; {&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Assembly&lt;/span&gt; _assembly;&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; AssemblyAttributes() : &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Assembly&lt;/span&gt;.GetCallingAssembly())&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;{}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; AssemblyAttributes(&lt;span style="color:#2b91af"&gt;Assembly&lt;/span&gt; assembly)&lt;br&gt; &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;_assembly = assembly;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Title&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyTitleAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Title); }&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Product&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyProductAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Product); }&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Copyright&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyCopyrightAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Copyright); }&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Company&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyCompanyAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Company); }&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Description&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyDescriptionAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Description); }&lt;br&gt; &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;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Trademark&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyTrademarkAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Trademark); }&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;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Configuration&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyConfigurationAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Configuration); }&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Version&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;{&lt;br&gt; &lt;span style="color:#0000ff"&gt;#if&lt;/span&gt; !SILVERLIGHT&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;&lt;span style="color:#0000ff"&gt;return&lt;/span&gt; _assembly.GetName().Version.ToString(); &lt;br&gt; &lt;span style="color:#0000ff"&gt;#else&lt;/span&gt;&lt;br&gt; &lt;span style="color:#808080"&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;return _assembly.FullName.Split(&amp;#39;,&amp;#39;)[1].Split(&amp;#39;=&amp;#39;)[1]; // workaround for silverlight&lt;/span&gt;&lt;br&gt; &lt;span style="color:#0000ff"&gt;#endif&lt;/span&gt;&lt;br&gt; &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;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; FileVersion&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyFileVersionAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Version); }&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; InformationalVersion&lt;br&gt; &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;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetValue&amp;lt;&lt;span style="color:#2b91af"&gt;AssemblyInformationalVersionAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.InformationalVersion); }&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Returns the value of attribute T or String.Empty if no value is available.&lt;/span&gt;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; GetValue&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;&amp;gt; getValue) &lt;span style="color:#0000ff"&gt;where&lt;/span&gt; T : &lt;span style="color:#2b91af"&gt;Attribute&lt;/span&gt;&lt;br&gt; &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;T a = (T)&lt;span style="color:#2b91af"&gt;Attribute&lt;/span&gt;.GetCustomAttribute(_assembly, &lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(T));&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;return&lt;/span&gt; a == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; ? &lt;span style="color:#ff00ff"&gt;&amp;quot;&amp;quot;&lt;/span&gt; : getValue(a);&lt;br&gt; &amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br&gt; &lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The real workhorse of this class is the &lt;code&gt;GetValue&amp;lt;T&amp;gt;&lt;/code&gt; method. It gets an arbitrary custom attribute from an assembly. If it exists, it returns the result of applying the &lt;code&gt;getValue&lt;/code&gt; delegate on it. If the attributes does not exist, it returns the empty string.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;The &lt;a href="http://www.codeproject.com/KB/DLL/AssemblyAttributes.aspx"&gt;full article&lt;/a&gt; with downloads is posted at &lt;a href="http://www.codeproject.com/"&gt;CodeProject&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/7873754566403770354-2286059703362310571?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/2286059703362310571/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/12/assemblyattributes.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/2286059703362310571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/2286059703362310571'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/12/assemblyattributes.html' title='AssemblyAttributes'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-1485293560693133640</id><published>2009-12-14T16:36:00.001+01:00</published><updated>2009-12-14T16:42:30.058+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><title type='text'>Improve performance through using FileAccess.Write</title><content type='html'>&lt;p&gt;At work I’m implementing a little app that copies video files from cameras to network folders. The size of a video file is usually several hundred megabytes. The target file is written with the standard &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.filestream.aspx"&gt;.NET FileStream class&lt;/a&gt;. The strange thing I noticed was that calling &lt;font face="Consolas"&gt;Close&lt;/font&gt; on the stream took between 15 and 20 seconds. Even if I flushed the stream Close call took ages. I created the stream like this &lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt; output = &lt;font color="#0000ff"&gt;new&lt;/font&gt; FileStream(path, &lt;font color="#008080"&gt;FileMode.Create&lt;/font&gt;);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;After playing with the available constructor overloads I found a better solution:&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt; output = &lt;font color="#0000ff"&gt;new&lt;/font&gt; FileStream(path, &lt;font color="#008080"&gt;FileMode.Create&lt;/font&gt;, &lt;font color="#008080"&gt;FileAccess.Write&lt;/font&gt;,&lt;font color="#008080"&gt; FileShare.Read&lt;/font&gt;);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Using this overload, the Close call took only 1 millisecond! That means a performance boost of factor 20000 just by using the right FileAccess Options.&lt;/p&gt;  &lt;p&gt;Tip: Always use the “Read” or “Write” if you don’t need “ReadWrite”. This will give you a performance boost on network files.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-1485293560693133640?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/1485293560693133640/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/12/improve-performance-through-using.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/1485293560693133640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/1485293560693133640'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/12/improve-performance-through-using.html' title='Improve performance through using FileAccess.Write'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-8522560428409405008</id><published>2009-12-12T16:29:00.002+01:00</published><updated>2010-02-23T12:47:16.452+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Open Xaml file in Xml view without loading the Designer</title><content type='html'>I use Expression Blend almost always as a design tool for my WPF projects. If I want to do quick modifications inside the xaml code from Visual Studio, I find the designer loading time quite annoying. But VS offers you the possibility to open xaml files in the xml/xaml view by default. Just open Tools –&amp;gt; Options –&amp;gt; Text Editor –&amp;gt; XAML –&amp;gt; Miscellaneous and tick “Always open documents in full XAML view” check.&amp;#160; &lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_sIFn2ZjjKAY/SyO4UaK9TEI/AAAAAAAAAC8/jrmoyVqpzyc/s1600-h/full_xaml_view_vs2008%5B7%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="full_xaml_view_vs2008" border="0" alt="full_xaml_view_vs2008" src="http://lh6.ggpht.com/_sIFn2ZjjKAY/SyO4VaNtVZI/AAAAAAAAADA/7vhfQDEO2rI/full_xaml_view_vs2008_thumb%5B4%5D.png?imgmax=800" width="558" height="344" /&gt;&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-8522560428409405008?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/8522560428409405008/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/12/open-xaml-file-in-xml-view-without.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8522560428409405008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8522560428409405008'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/12/open-xaml-file-in-xml-view-without.html' title='Open Xaml file in Xml view without loading the Designer'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_sIFn2ZjjKAY/SyO4VaNtVZI/AAAAAAAAADA/7vhfQDEO2rI/s72-c/full_xaml_view_vs2008_thumb%5B4%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-6999555041625934842</id><published>2009-12-08T22:34:00.001+01:00</published><updated>2009-12-08T22:34:29.487+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WiX'/><category scheme='http://www.blogger.com/atom/ns#' term='Installer'/><title type='text'>WiX Lessons Part 2</title><content type='html'>&lt;p&gt;Today I did some localization of my WiX based installer and learned, that Windows Installer must have a very old code base. While localization with WiX is really easy it inherits some limitations that you don’t expect nowadays. First you cannot use UTF8 or Unicode to define your string tables. No, you need to specify windows codepages that should be used for a concrete language. Unicode is not supported. So you have to dig in old documentation for appropriate codepages (Luckily I can use Windows-1252 for West European Languages). Second you cannot simply build one msi for all languages. You must build a msi package for every language. Then you can either use a bootstrapper to decide which msi to start, or you can use some black magic on the command line which uses transformations at runtime to morph one msi into the appropriate language. Multi Language packages are not built into Windows Installer.&lt;/p&gt;  &lt;p&gt;I had another strange behavior today regarding the usage of WiX library. I made a simple library with some very minimalistic installer gui which needs three images. &lt;a href="http://lh4.ggpht.com/_sIFn2ZjjKAY/Sx7GYtpPGAI/AAAAAAAAACc/PS4Um2bmx38/s1600-h/project%5B5%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="project" border="0" alt="project" align="right" src="http://lh6.ggpht.com/_sIFn2ZjjKAY/Sx7GZK1bJ4I/AAAAAAAAACo/0WxUeZfKtX8/project_thumb%5B3%5D.png?imgmax=800" width="164" height="257" /&gt;&lt;/a&gt;The three images are located inside an Images folder. See attached picture for the project structure. The files are referenced like this: &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;&lt;font color="#800000"&gt;Binary&lt;/font&gt; &lt;font color="#ff0000"&gt;Id&lt;/font&gt;=&amp;quot;&lt;font color="#0000ff"&gt;Banner&lt;/font&gt;&amp;quot; &lt;font color="#ff0000"&gt;SourceFile&lt;/font&gt;=&amp;quot;&lt;font color="#0000ff"&gt;Images\banner.bmp&lt;/font&gt;&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;First build succeeded than it always failed, saying that it could not find “Images\banner.bmp”. It seems some tool in the chain needs an absolute path because I fixed the build by adding the &lt;font face="Courier New"&gt;$(sys.CURRENTDIR)&lt;/font&gt; preprocessor directives:&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;SourceFile&lt;/font&gt;=&amp;quot;&lt;font color="#0000ff" face="Courier New"&gt;$(sys.CURRENTDIR)Images\banner.bmp&lt;/font&gt;&amp;quot;&lt;/p&gt;  &lt;p&gt;And you need to check “Bind files into the library file” on the Build page of the project properties. Else the library contains only the filenames and every project using the library must have access to the absolute path of the images. By default this is unchecked which imho corrupts the meaning of a redistributable library. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-6999555041625934842?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/6999555041625934842/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/12/wix-lessons-part-2.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6999555041625934842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6999555041625934842'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/12/wix-lessons-part-2.html' title='WiX Lessons Part 2'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_sIFn2ZjjKAY/Sx7GZK1bJ4I/AAAAAAAAACo/0WxUeZfKtX8/s72-c/project_thumb%5B3%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-1940300099776912433</id><published>2009-11-23T17:17:00.001+01:00</published><updated>2009-11-23T17:17:32.410+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows7'/><title type='text'>Windows 7 Upgrade</title><content type='html'>&lt;p&gt;Last week I have upgraded my business notebook from Vista to Windows 7. I have lots of stuff installed on this machine and I wanted to save time reinstalling every little tool I need. And it worked!&lt;/p&gt;  &lt;p&gt;I started the setup in the afternoon and when it said “This can take several hours” decided to go home early this day. In the next morning it prompted for the serial key and wow Windows 7 was ready! In only needed to adjust the desktop resolution and was able to continue working without interruption. Every shortcut, every app was just working. This was the fastest and most impressive OS update I have experienced in the last twenty years. &lt;/p&gt;  &lt;p&gt;And working with Windows 7 is really more effective! All those subtle changes that you begin using without noticing. Working feels much fluffier now and I instantly became&amp;#160; addictive. Must upgrade all other PC’s now …&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-1940300099776912433?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/1940300099776912433/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/11/windows-7-upgrade.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/1940300099776912433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/1940300099776912433'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/11/windows-7-upgrade.html' title='Windows 7 Upgrade'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-8352066277327908069</id><published>2009-10-29T09:41:00.002+01:00</published><updated>2009-10-29T09:46:03.905+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WiX'/><category scheme='http://www.blogger.com/atom/ns#' term='Installer'/><title type='text'>WiX Lessons Learned</title><content type='html'>The last week I was playing around with the &lt;a href="http://wix.sourceforge.net/"&gt;Windows Installer XML&lt;/a&gt; to create a simple setup for a very simple product implemented with .NET. All I needed to do was to copy some files, install a service under a custom account, let the user enter the address of some web services. &lt;br /&gt;
These features are hot: &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;open source &lt;/li&gt;
&lt;li&gt;frontend for the built-in windows installer &lt;/li&gt;
&lt;li&gt;done by people who know windows installer inside out &lt;/li&gt;
&lt;li&gt;simple declaration of files and actions in xml &lt;/li&gt;
&lt;li&gt;simple install/deinstall of services with properties like windows account or description &lt;/li&gt;
&lt;li&gt;custom actions can done with .net very easily, they have read/write access to properties via a session object (see &lt;a href="http://www.tramontana.co.hu/wix/lesson3.php#3.5"&gt;tutorial&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;you can use managed custom actions for easy validation of custom dialogs &lt;/li&gt;
&lt;li&gt;can easily integrated into automatic msbuild builds &lt;/li&gt;
&lt;li&gt;very good logging capabilities which helps you on debugging &lt;/li&gt;
&lt;li&gt;property based, declarative style &lt;/li&gt;
&lt;li&gt;property values can be changed by administrators to support customized automatic install on clients &lt;/li&gt;
&lt;li&gt;support for commit/rollback and repair/maintenance mode &lt;/li&gt;
&lt;/ul&gt;
But this is what bites me:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Bringing new Custom Dialogs (e.g. query user/password) into the dialog chain is really a pain in the ass. The chaining is done through adding event-actions to the next/back buttons which open new dialogs. Adding some conditional logic if a dialog should be shown or not has to be done by attaching conditions on the adding of event actions of the Next button of the &lt;strong&gt;previous&lt;/strong&gt; dialog and the Back button of the &lt;strong&gt;following&lt;/strong&gt; dialog. An you have to deal with this because on Repair/Maintenance Mode your need probably another dialog sequence. &lt;/li&gt;
&lt;li&gt;Managed Custom Actions don’t seem to work in elevated mode. The bad thing is, that the installation succeeds without an error, and the custom action is ignored (that is unless you look into the log file). &lt;/li&gt;
&lt;li&gt;There is no easy way to manipulate files, say app.config on the fly during installation. There is an XmlConfig extension you can use, but using it is rather crude, if you know how to do it in managed code. &lt;/li&gt;
&lt;li&gt;The GUI support is very limited, you can have edit, password, combobox, listbox, check and radio controls, but layouting is done by entering x and y coordinates by hand. Browsing for a file is impossible, you can browse only for directories. &lt;/li&gt;
&lt;/ul&gt;
Other things:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;You need &lt;a href="http://www.tramontana.co.hu/wix/"&gt;the WiX tutorial&lt;/a&gt; or you are lost &lt;/li&gt;
&lt;li&gt;You need &lt;a href="http://robmensching.com/blog/posts/2008/5/16/Deployment-Tools-Foundation-joins-the-WiX-toolset"&gt;DTF (Deployment Tools Foundation)&lt;/a&gt; for managed custom actions &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;it is included in the WiX package &lt;/li&gt;
&lt;li&gt;the documentation is hidden in the doc folder of you installation … it is neither linked from the WiX documentation nor to be easily found on the internet &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;If you are a mortal .NET developer you have to do bend your mind to understand it, the windows installer technology sometimes feels like C64 basic with line numbers. Don’t be afraid, after one or two frustrating days you will get it. &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/7873754566403770354-8352066277327908069?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/8352066277327908069/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/10/wix-lessons-learned.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8352066277327908069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8352066277327908069'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/10/wix-lessons-learned.html' title='WiX Lessons Learned'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-8675944564988905263</id><published>2009-10-20T22:41:00.008+02:00</published><updated>2009-10-20T22:57:42.381+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IE8'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>IE8 Kompatibilitätsansicht für Intranetsites</title><content type='html'>Nachdem ich nun dem Table Layout abgeschworen habe und ins CSS Lager gewechselt bin, habe ich am Wochenende auch mein Hobbyprojekt &lt;a href="http://svnquery.tigris.org/"&gt;SvnQuery&lt;/a&gt; auf CSS&amp;nbsp;umgestellt. Das hat zwar etwas Mühe gekostet,&amp;nbsp;aber dafür habe ich wieder etwas gelernt, das html hat eine klare Struktur und nebenbei wurden noch einige andere html Fehler beseitigt.&lt;br /&gt;
&lt;br /&gt;
Zurück in der Arbeit aktualisierte ich auch die Suche der Firmenrepositories. Doch gleich bei der ersten Suche der Schock: Fette Scrollbalken schon auf der Startseite, offensichtlich wurde das Layout 200% breit statt wie gewünscht 100%. Und das auf dem &lt;a href="http://de.wikipedia.org/wiki/Internet_Explorer#Version_8"&gt;IE8&lt;/a&gt; gegen den ich hauptsächlich getestet hatte.&amp;nbsp;Hatte ich schlecht getestet? Warum war mir das daheim nicht aufgefallen?&lt;br /&gt;
&lt;br /&gt;
Also schnell das Projekt heruntergeladen, lokal installiert und ausprobiert. Und siehe da, das Layout war wie erwartet. Aber was war das Problem? Irgendwo musste es einen Unterschied geben. Entwickelt hatte ich gegen den ASP.NET Development Server, in der Firma läuft ein &lt;a href="http://de.wikipedia.org/wiki/Microsoft_Internet_Information_Services"&gt;IIS6&lt;/a&gt;. Also schnell die Seite auf dem lokalen IIS gehostet.&amp;nbsp;Doch auch hier wurde die Seite einwandfrei dargestellt. Jetzt wurde es mysteriös. Der einzige Unterschied, der noch blieb, war, dass auf meinem Enwicklungsrechner ein deutsches Vista mit &lt;a href="http://de.wikipedia.org/wiki/Microsoft_Internet_Information_Services_7"&gt;IIS7&lt;/a&gt; lief, und der Produktivserver mit einem englischen Windows Server 2003 und IIS6 arbeitete. Vielleicht ein Lokalisierungsproblem im IIS oder IE8? Ein Vergleich der Quelltexte von beiden Quellen zeigte zumindestens, dass der ASP.NET DataPager ein paar Texte lokalisierte (First ~ Erste, Next ~ Nächste, ...). Nachdem dies gefixt war, gab es aber auch hier keine Unterschiede mehr ... bis auf die Adressen der verlinkten CSS Stylesheets und Javscripts. Nun lernte ich, dass ASP.NET Scripts an dynamischen Adressen zum Nachladen generiert :&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;script src="/search/WebResource.axd?d=UV3-E5OwNGFcSb3I84w2&amp;amp;t=6391349351841...&lt;/span&gt;&lt;br /&gt;
Diese Scripte sind immerhin ca 20k groß und ihre Adresse ändert sich bei jedem Aufruf der Webseite. Vielleicht lag hier das Problem. Also speicherte ich die funktionierende Seite in ein lokales html file und bog händisch&amp;nbsp;Schritt für&amp;nbsp;Schritt die Links von der funktionierenden Quelle auf die nicht funktionierende um, in der Hoffnung irgendwann eine Seite mit dem zerstörten Layout zu erreichen. &lt;br /&gt;
Am Ende hatte ich jedoch eine lokale Seite mit Scripten und Stylesheets vom nicht funktionierenden Server, die immer noch das korrekte Layout anzeigte. Jetzt war ich völlig perplex!&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_sIFn2ZjjKAY/St4cMEnb2wI/AAAAAAAAABQ/TfS-nXDgKKY/s1600-h/komp_icon.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_sIFn2ZjjKAY/St4cMEnb2wI/AAAAAAAAABQ/TfS-nXDgKKY/s200/komp_icon.png" vr="true" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
Ich lud nun die beiden Seiten, funktionierend und defekt, in zwei Tabs des IE8. Während ich versuchte, mir eine neue Hypothese für dieses seltsame Verhalten auszudenken, schaltete ich immer zwischen beiden Tabs hin und her ... bis mir etwas auffiel. Es gab&amp;nbsp;Unterschiede, aber außerhalb des eigentlichen Darstellungsbereiches. Das Symbol für die Kompatibilitätsansicht im IE8 war im defekten Layout nicht sichtbar! Warum nicht? Der andere Unterschied war in der Statusleiste zu sehen, die funktionierende Seite kam von "Computer" die andere von "Lokales Intranet". Hatte es etwas mit dem berüchtigten Zonenmodell zu tun? Ich konnte im Menüpunkt&amp;nbsp;"Internetoptionen" nichts finden. Aber im Menü "Seite" gibt es den Punkt "'Einstellungen der Kompatibilitätsansicht" und dort gibt es die Option "Intranetsites in Kompatibilitätsansicht darstellen".&lt;br /&gt;
D.h. alle Seiten aus dem Intranet (wo sich auch das Firmenrepository befindet) werden in der Kompatibilitätsansicht dargestellt, und in der Kompatibilitätsansicht geht das Layout kaputt! Seiten vom lokalen Computer (localhost, Dateisystem) und aus dem Internet werden im neuen, standardkonformen Modus angezeigt! Offensichtlich ist dies die Standard Einstellung des IE8, wobei mir der Sinn dieser Option wirklich schleierhaft ist. Noch merkwürdiger,&amp;nbsp;dass sie &amp;nbsp;standardmäßig&amp;nbsp;aktiviert ist.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator"&gt;
&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_sIFn2ZjjKAY/St4kON8Q3fI/AAAAAAAAABg/vmCM8QMz2Rs/s1600-h/IE8_Komp_klein.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_sIFn2ZjjKAY/St4kON8Q3fI/AAAAAAAAABg/vmCM8QMz2Rs/s640/IE8_Komp_klein.png" vr="true" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
PS: Der Grund für das defekte Layout in der Kompatibilitätsansicht war übrigens ein absolut positioniertes Element, dessen Style die folgenden Attribute fehlten:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;right: 1px;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;top: 1px;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;width: auto;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;overflow: hidden;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-8675944564988905263?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/8675944564988905263/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/10/ie8-kompatibilitatsansicht-fur.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8675944564988905263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/8675944564988905263'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/10/ie8-kompatibilitatsansicht-fur.html' title='IE8 Kompatibilitätsansicht für Intranetsites'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_sIFn2ZjjKAY/St4cMEnb2wI/AAAAAAAAABQ/TfS-nXDgKKY/s72-c/komp_icon.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-3247457750178881586</id><published>2009-10-11T23:02:00.001+02:00</published><updated>2009-10-11T23:09:59.553+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Expression Web'/><title type='text'>Homepage Redesign mit Expression Web und Subversion</title><content type='html'>Gestern und heute habe ich mit einem Design für meine &lt;a href="http://www.atombrenner.de/"&gt;Homepage&lt;/a&gt; begonnen. Diese hatte ich mal vor Urzeiten (ca 2003) nach einem Provider Wechsel neu angelegt aber dann wegen Hochzeit, Kindern etc. nie wieder angefasst. Um den Lachanfällen von Frau, Kollegen und Nachbarn ein Ende zu setzen musste etwas passieren. Und eine gute Gelegenheit mal wieder meine Html Kenntnisse aufzupolieren. Und am besten gleich mal&amp;nbsp;&lt;a href="http://www.microsoft.com/expression/"&gt;Expression Web 3&lt;/a&gt; ausprobieren. Gesagt getan, rein ins Vergnügen.&lt;br /&gt;
&lt;br /&gt;
Erste Erkenntnis, Table Layout ist out, CSS funktioniert tatsächlich,&amp;nbsp;und nach einer halben Stunde Template Erforschung hatte ich dann a) ein funktionierendes neues Layout mit Navigation und b) endlich verstanden was das Cascading bedeutet. Und das man das Separation of Concerns Prinzip auch auf Stylesheets anwenden kann. Im Vergleich zu Frontpage oder gar dem Html Editor vom Visual Studio ist Expression Web um Lichtjahre besser. Kaum wartet man&amp;nbsp;ein paar Jahre, schon geht alles viel leichter :-)&lt;br /&gt;
&lt;br /&gt;
Doch dann bekam ich Probleme als ich versuchte mein Homepage Projekt unter Versionskontrolle zu stellen, konkret mit Subversion. Expression Web hat ja erstaunlicherweise keine eingebaute Unterstützung für Versionskontrolle außer für &lt;a href="http://en.wikipedia.org/wiki/Team_Foundation_Server"&gt;Microsofts TFS&lt;/a&gt;, welches außerhalb von großen Unternehmen kaum verbreitet sein dürfte. Mit Subversion bekommt man die größten Probleme, wenn Dateien oder gar Verzeichnisse umbenannt oder verschoben werden. Dies muss man unbedingt mit einem Subversion Client machen. Nun sind&amp;nbsp;jedoch genau diese Operationen beim Aufbau einer neuen Struktur nicht gerade selten. Mit Expression Web läßt sich das alles sehr einfach und bequem erledigen, alle Hyperlinks werden automatisch angepasst, etc. Doch danach ist die Subversion Working Copy erst einmal Schrott. OK, dann verschiebe und benamse ich mittels TortoiseSVN. Hat man dabei jedoch Expression Web offen, hatte ich öfters das Problem, das plötzlich Dateien mit altem Inhalt überschrieben wurden, Links kaputt waren und am Ende das Programm behauptete meine Homepage wäre kein gültiges WebSite Projekt mehr. &lt;br /&gt;
&lt;br /&gt;
Grund waren geheime (versteckte) _vti_* Verzeichnisse, deren Inhalt von TortoiseSvn logischerweise nicht upgedatet werden konnte. Letztendlich habe ich meine&amp;nbsp;Homepage wieder aus der Versionskontrolle entfernt und mache jetzt wieder händische Backups des kompletten Verzeichnisses.&lt;br /&gt;
&lt;br /&gt;
Ich frage mich nun, ob überhaupt jemand dieses Programm zu professionellen Web Design hernehmen kann, bzw. wo es Microsoft positioniert? Ohne funktionierende Versionskontrolle kann man doch nicht guten Gewissens arbeiten? Oder arbeiten Web Site Entwickler etwa noch ohne Versionskontrolle? Ich meine ein Versionkontroll Plugin Konzept wäre im Vergleich zu&amp;nbsp;den vielen tollen anderen Features wirklich trivial gewesen. Es muss doch nur eine Benachrichtung übers Anlegen, Ändern, Löschen, Umbenennen, und Verschieben gesendet werden.&lt;br /&gt;
&lt;br /&gt;
Wirklich schade, ohne dieses "fehlende Feature" ist Expression Web 3 wirklich ein tolles Produkt.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-3247457750178881586?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/3247457750178881586/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/10/gestern-und-heute-habe-ich-mit-einem.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/3247457750178881586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/3247457750178881586'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/10/gestern-und-heute-habe-ich-mit-einem.html' title='Homepage Redesign mit Expression Web und Subversion'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-6285866211473242508</id><published>2009-10-06T16:13:00.004+02:00</published><updated>2009-12-12T16:32:02.636+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Frequent Errors'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><title type='text'>Don't forget to run aspnet_regiis and ServiceModelReg</title><content type='html'>Every few month I run into weird installation problems on IIS so that ASP.NET applications (including .svc WCF services and Silverlight applications) don't run with misleading error messages. Today I was running into this problem again. Seems that&amp;nbsp;I hadn't the correct permissions to download&amp;nbsp;a .xap file from the ClientBin silverlight folder. After fiddling around for half an hour or so I eventually remembered to run&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/k6h9cz8h.aspx"&gt;aspnet_regiis.exe&lt;/a&gt;&amp;nbsp;-i&lt;/span&gt; to reregister the current .net framework. This solved the problem immediately. &lt;br /&gt;
Even if this tool is located in "%windir%\Microsoft.NET\Framework\v2.0.50727" it seems to reregister the newest installed framework (in my case .NET 3.5 and Silverlight).&lt;br /&gt;
&lt;br /&gt;
A similar problem can occur for WCF services with the .svc extension. In this case you need to run &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms732012.aspx"&gt;ServiceModelReg.exe&lt;/a&gt; -i&lt;/span&gt; again. This tool is located in "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation"&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-6285866211473242508?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/6285866211473242508/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/10/register-dont-fo.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6285866211473242508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/6285866211473242508'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/10/register-dont-fo.html' title='Don&apos;t forget to run aspnet_regiis and ServiceModelReg'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-3041963862408658354</id><published>2009-09-30T18:52:00.002+02:00</published><updated>2009-09-30T19:14:29.847+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><title type='text'>My recent transformation from hating code generators to loving them</title><content type='html'>For a long time now I believed that code generators were evil. When I discussed this topic I mainly gave these reasons:
&lt;ul&gt;&lt;li&gt;a strong believe that you could pack every code into a class and just use it from there   &lt;/li&gt;&lt;li&gt;a chapter from &lt;a href="http://www.pragprog.com/the-pragmatic-programmer"&gt;The Pragmatic Programmer&lt;/a&gt; I wrongly remembered as "Beware of evil code wizards"&lt;/li&gt;&lt;li&gt;bad experience with MFC Wizards(VS 4.2) for database based data entry / viewing dialogs&lt;/li&gt;&lt;/ul&gt;It didn't came to my mind until now that I was already using code generators everyday:
&lt;ul&gt;&lt;li&gt;Automatically add using references when typing still unreferenced types &lt;/li&gt;&lt;li&gt;Using &lt;a href="http://www.jetbrains.com/resharper/index.html"&gt;Resharper's &lt;/a&gt;Complete Code to insert delegates or create method stubs &lt;/li&gt;&lt;li&gt;using &lt;a href="http://www.jetbrains.com/resharper/index.html"&gt;Resharper's &lt;/a&gt;Live Templates to insert unit testing stubs &lt;/li&gt;&lt;/ul&gt;Perhaps they were so small and convenient that I didn't recognize them as code generators. Lateley I had to do a lot of &lt;a href="http://msdn.microsoft.com/en-us/library/ms731082.aspx"&gt;WCF &lt;/a&gt; programming. First I totally rejected the recommended way of using Web References because they generated tons of code I didn't understand. I wanted to do it like &lt;a href="http://www.amazon.com/Programming-WCF-Services-Juval-Lowy/dp/0596526997"&gt;Juval Löwy&lt;/a&gt;, that means
&lt;ul&gt;&lt;li&gt;refactor all contracts into a ServiceContract dll &lt;/li&gt;&lt;li&gt;reference this dll from the server and the client &lt;/li&gt;&lt;li&gt;let the client use a ChannelFactory to create a proxy on the fly from the service interface &lt;/li&gt;&lt;/ul&gt;This was an elegant and easy to understand solution. Additionaly I would got compiler errors if I changed an interface and forgot to change the client. This is absolutely necessary if you use Continous Integration.
Then I needed to think more and more about cross cutting concerns with WCF proxies like
&lt;ul&gt;&lt;li&gt;retrying failed service calls &lt;/li&gt;&lt;li&gt;authentication &lt;/li&gt;&lt;li&gt;central exception handling&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Some of these things cannot be simply refactored into another class and just used. Basically, often you need to wrap every method into a try-catch block or do some common initialization. You have to do the same thing over and over again, and if every member in your team has to do it also it becomes a nightmare to ensure that everyone is doing it in the same way. In parallel I  needed to do some &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt; clients for the same WCF services. This should be easy, but with Silverlight you can't reference the ServiceContract dll generated by normal .net (because it uses a different runtime version) and even worse you need to  use the asnychronous communication modell, which means you need another interface with other methods. Combined with the additional needed cross cutting concerns and soon you have a very unmaintainable code base.&lt;/p&gt;&lt;p&gt;In this situation I started to think of a code generator that could generate proxies for silverlight and .net with allthe special cross cutting stuff from one single source. I started to develop it, and a day later I had a protypegenerating working proxies. I spent another day with integrating it into Visual Studio and the automatic build and then it was obvious to me that this was the right solution to my problems. Integrating cross cutting concerns is really simple, all the special knowledge is encapsulated inseid the proxy generator, proxies get regenerated on every automatic build with the newest proxy generator, team members just add a custom service generation step and start using the proxies. No more code reviews and no more search and replace through the whole code base if a cross cutting concern changes.&lt;/p&gt;&lt;p&gt;After this experience I have now reread &lt;a href="http://www.pragprog.com/the-pragmatic-programmer/extracts/wizards"&gt;the chapter about evil wizards&lt;/a&gt; and learned that my understanding mutated over the years. Actually the pragamatic programmer encourages you to build code generators to automate repetive tasks. The evil is not the code generation itself. The evil is, that you get code that you don't understandand that you must modify it, because it is like a framework. After a modification you cannot regenerateit without loosing your modifications.
&lt;/p&gt;&lt;p&gt;Having this remembered and extended my understanding I can now happily say that generating code from file A to file B in a repeatable way is always safe. Its just like a compiler for a DSL stored in file A. Just don't modify B. Creating method stubs or unit test hull is also safe, even if you need to modify them, because they are small and understandable. But keep aware of run-once-wizards which generate complex application frameworks that you don't understand.
 &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-3041963862408658354?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/3041963862408658354/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/09/my-recent-transformation-from-hating.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/3041963862408658354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/3041963862408658354'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/09/my-recent-transformation-from-hating.html' title='My recent transformation from hating code generators to loving them'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7873754566403770354.post-3683278284372116920</id><published>2009-09-18T15:10:00.004+02:00</published><updated>2009-09-18T15:20:18.304+02:00</updated><title type='text'>Eintrag Eins</title><content type='html'>So, nun versuche ich mich auch mal als Blogger.

Ich möchte hier Dinge aufschreiben die ich mit Mühe herausgefunden habe und die ich irgendwann einmal via google wiederfinden möchte. Manchmal brauche ich nämlich Jahre später Sachen die ich bereits gelöst wurden, aber oft vergesse ich all die vielen Probleme, die ich nur einmal gelöst habe ;-) . Ich habe es mir zur Gewohnheit gemacht vor jedem Problem *immer* zu googeln, um zu schauen ob vielleicht jemand anderes das gleiche oder ein ähnliche Problem gelöst hat. Und wenn meine Gedanken und Ideen für Google sichtbar sind, brauche ich nur einmal suchen :-)

Ein Frage stellt sich mir noch, schreibe ich lieber in Englisch oder in Deutsch? Deutsch geht deutlich flüssiger, aber bei vielen technischen Problemen sucht man eh nach den englischen Keywords. Dann werde ich die Beitrage am besten gleich in Englisch schreiben.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7873754566403770354-3683278284372116920?l=atombrenner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://atombrenner.blogspot.com/feeds/3683278284372116920/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://atombrenner.blogspot.com/2009/09/eintrag-eins.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/3683278284372116920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7873754566403770354/posts/default/3683278284372116920'/><link rel='alternate' type='text/html' href='http://atombrenner.blogspot.com/2009/09/eintrag-eins.html' title='Eintrag Eins'/><author><name>Christian Rodemeyer</name><uri>http://www.blogger.com/profile/14186012205777714561</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/-MM_wVCoYjJY/TjxP-T84H3I/AAAAAAAAAFQ/622eCHZSp28/s220/entdecker.jpg'/></author><thr:total>0</thr:total></entry></feed>
