21 November 2010

C# Object Initialization Wonders

Since I am coding a lot in JavaScript recently I tend to use C# Object Initialization more often than before. Last evening I had an astonishing experience …

I had a class Foo

public class Foo
{
    public List<string> Data { get; set; }
}

and wrote this object initializer:

var bar = new Foo {Data = {"a", "b"}};

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 Debug.WriteLine(string.Join(", ", bar.Data)); it contains 1, 2, a, b and not the expected a, b. 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.

public Foo()
{
    Data = new List<string>{"1", "2"};
}

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:

var bar = new Foo {Data = new List<string>{"a", "b"}};

I’m not really sure if this is a bug or a feature …

14 Oktober 2010

Always “Compare whitespaces” when merging

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.  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: “Compare whitespaces”

Compare Whitespace 

The default settings of this dialog are the correct ones but many developers automatically click on one of the "Ignore whitespace" 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!

<Insert picture here>

So remember one thing: Always choose "Compare whitespaces" in the merge options!

21 August 2010

Speed up your Subversion repository

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.

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.

So what’s the problem here? I have some guesses but are not yet sure about the real reasons. But here are my suggestions:

  • Use the FSFS mode (I hope nobody is using Berkeley DB anymore?)
  • Use Sharding. 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.
  • Pack your repository regularly. Normally, each revision is stored as a single file. If you have a sharded repository then svnadmin pack will convert all full shards into one big files. This saves space and helps the OS to reduce I/O and improve caching.
  • Use the svn:// protocol. The http and https protocols are just a tunnel for WebDAV delta-v 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://.
  • Check your commit hooks. Perhaps you have installed some expensive commit hooks. On Windows, try using RunDetached to prevent subversion from waiting for the hook to finish.
  • Beware of Polling Build Agents. 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 CruiseControl.NET and TeamCity 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.
  • Monitor I/O load. 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 exclusively reserved for this purpose. Use a SSD or at least a 10,000 RPM drive.
  • Store your repository on a  Intel Solid State Disk. 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.
  • Optimize your working copy. Change the layout so you can do partial updates. Try to use svn update –-svn-depth -exclude to exclude parts you don’t need in your day-to-day work. Remove files you don’t need. 

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.

08 August 2010

Requirements for a Dependency Injection Container

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 “If I’d asked people what they wanted, they would have said faster horses.” 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.

Today I have worked with Spring.NET and much more with Unity. I know StructureMap and Autofac (but Castle Windsor 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.

This is my list of important and useful features:

  • 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!
  • Wiring dependencies should be possible by conventions or attribute based. Use explicit wiring only as a last resort (bad maintainability).
  • Understandable error message and diagnostic help if something went wrong when constructing/resolving a type.
  • Constructor and property must be possible, event and method injections would be nice to have.
  • 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.
  • Extensibility: it should be possible to implement autofaking or automocking strategies (described here and here) which are extremely useful for unit testing.
  • Lifetime of objects should be configurable in different ways (free, singleton, container bound, thread bound, …).
  • If object lifetime can be bound to the container lifetime the disposal of the container should also dispose all contained objects.
  • Automatic factories. The possibility to not inject a single object but a generic factory, say Func<T>(), without explicit configuration.
  • The container should have at least two distinct interfaces, one for configuring the container and one for resolving/constructing types.
  • Static Service Locator Facade (with override possibility) for working with legacy code.
  • 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.
  • 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.
  • … (to be continued) …

25 Juli 2010

How to change the ReSharper naming style for test methods

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:

public void MethodUnderTest_Scenario_ExpectedResult()

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:

ReSharper Options –> Naming Style –> Advanced settingsimage
image
In “Affected entities” mark “Test method (property)” and disable inspections.image

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.

05 Juli 2010

Don’t use keyword substitution if you use branches

Many version control systems use some kind of keyword substitution, e.g. in Subversion the keyword $Author:$ gets replaced on every commit through the committing author, say $Author: crodemeyer$. 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  automatic reintegration of branches if you use keyword replacement.

Fortunately Subversion has the possibility to control keyword substitution with the svn:keywords property. Be a hero and use “svn pd svn:keywords –R” to disable keyword substitution completely.

02 Mai 2010

Always databind SelectedItem before ItemsSource

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.

<ComboBox ItemsSource="{Binding Repositories}"
          SelectedItem="{Binding SelectedRepository}" />

The constructor of the ViewModel initializes the Repositories with a non empty collection and sets the SelectedRepository to the first element.

public ViewModel()
{
    Repositories = new List<string> {"First", "Second", "Third"};
    SelectedRepository = Repositories[0];
}

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:

<ComboBox SelectedItem="{SelectedRepository}"
          ItemsSource="Repositories" />
Conclusion: the order of databinding declaration matters!

30 April 2010

Using Assembly.CodeBase to get the location if shadow copied

A long time I had problems with NUnit tests that needed to access files living relative to the tested dll. NUnit (and Resharper) are shadow copying a dll before running the test, so the Location 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.
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 CodeBase 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:///”  and uses slashes ‘/’ instead of backslashes ‘\’, so you need to modify the returned string a bit:
var assembly = Assembly.GetExecutingAssembly();
var path = assembly.CodeBase.Replace("file:///", "").Replace("/", "\\");
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.

25 Februar 2010

Mercurial tutorial by Joel Spolsky

A really good mercurial tutorial (especially for those who are damaged by subversion) by Joel Spolsky:

 http://hginit.com/index.html.

23 Februar 2010

Wissensvermittlung und ein Konfuzius Zitat

Ich habe gerade ein sehr passendes Zitat von Konfuzius gelesen (Papier, OBJEKTspektrum 03/2009) indem ich mich selbst wiedererkenne, wenn es um Wissensvermittlung geht:

“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.”

Expression Blend 3 Design Time Attributes

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 there. Nevertheless they are fully functional with VS 2008 because they are ignored by the compiler and only used by design tools like blend.

All Design Time Attributes live in the d: namespace:

d:DesignHeight

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.DesignTimeHeight

d:DesignWidth

DesignTimeWidth
d:DataContext Lets you specify the DataContext used at design time. Example: d:DataContext={StaticResource MyDataContextObject}, or even better    use d:DesignInstance

d:DesignInstance

d:DataContext="{d:DesignInstance Type=local:MyDataContext, IsDesignTimeCreatable=True}"

d:DesignData

needs VS2010, links to a sample data object defined in a xaml file

d:DesignSource

sets the Source property of a CollectionViewSource at design time

15 Februar 2010

You are not thy user

I have just finished reading Dave S. Platt’s book “Why Software SUCKS”, 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.

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 “Wrong!”. This is not new knowledge, in Germany we know it as “Der Trugschluß der egozentrischen Intuition”, but no one before described it in such a catchy way.

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.

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.

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.

23 Januar 2010

New NUnit syntax of how to expect exceptions

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:

[Test]
public void GetExternals_InvalidWorkingCopy_ThrowsSvnException()
{
    // Arange
    var ep = new WorkingCopyCache();

    // Act & Assert            
    Expect(() => ep.Get(@"X:\Dummy"), Throws.InstanceOf<SvnException>());
}

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 http://nunit.com/blogs/?p=63.