Wednesday, March 07, 2007

Oops, Activator.CreateInstance with a Singleton

The Singleton pattern is one of the most widely used design patterns. The Singleton pattern ensures that exactly one and only one instance of a class is instantiated at any given time. It can also be somewhat confusing because it seems that there are multiple ways of implementing the pattern. In the article "Implementing Singleton in C#", MSDN recommends a slightly different approach for implementation than the Design Patterns classic in order to take advantage of C#'s features.

The Activator class is a useful .NET class for creating types of objects as well as obtaining references to remote objects. On the .NET Compact Framework side, the method which stands out prominently is the CreateInstance method. The .NET Compact Framework supports two overloads of the CreateInstance method. Both methods take a type. One takes a type as a parameter and returns an object. The other takes a type as a generic parameter and returns an object of that specific type.

As part of my current project, there is a navigation component responsible for returning a user to where he or she left off within the application. At the lowest levels, this component is calling Activator.CreateInstance(Type) where Type is a type of form. Everything was working fine until yesterday, when the application would repeatedly blow up anytime it was started. The issue was traced down all the way to the Activator.CreateInstance(Type) method throwing a MissingMethodException.

At first, I could not understand why a MissingMethodException was being thrown. A group of us theorized that maybe it was due to this particular form being in an assembly outside of the executing assembly. I was able to collapse the two assemblies together by adding all the files in the referenced assembly as links to the executing assembly. That did not fix the issue. The MissingMethodException was still occurring.

I decided to step back and verify what I thought was true. I then looked up the particular CreateInstance method on MSDN. It was there that I realized exactly what was happening and why a MissingMethodException was being thrown. Next to MissingMethodException was the explanation of "No matching public constructor was found". At this point it was obvious what was the cause of the issue. The form type being passed to CreateInstance had no public constructor due to the fact that there should only ever be one object of that form instantiated (because it interacts with a native application's window handles). CreateInstance was failing because it had no idea how to create an instance of that type of form.

This is just one of those times where the answer is blatantly obvious once found.

1 comment:

Trevor said...

Brilliant. Had similar exception when using non singleton derived classes that did not have a default constructor with no parameters.
Now Sorted. Thanks.