I am currently working on a little thing in Silverlight and came across an interesting “feature”. The thing I am working on requires me to dynamically create types based on strings in a configuration file, and for this purpose, I created a simple TypeConverter called TypeTypeConverter. It is a very simple converter that takes a string and converts it to a Type. So I created a very simple implementation that looks like this
public class TypeTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
return Type.GetType((string)value, true);
}
return base.ConvertFrom(context, culture, value);
}
}
As you can see, it is probably a little TOO simple as it doesn’t handle errors at all. But to be honest, in my case it is actually a bit by design.
So why does this simple little thing end up on my blog? Well, because it failed… Not the code as such, but the thing I was trying to do…
The string that I am trying to convert is a type definition obviously, and they take the form of “<namespace>.<className>, <assemblyName>”. Or at least that is the simplest form of them. They can become a lot more complicated if you add versioning, signing and cultures in to the mix. But for me, the simplest version was enough.
So that would turn my code into something like this
return Type.GetType("MyNamespace.MyClass, MyAssembly");
Right…? Well, I would have thought so… But the above line throws a FileLoadException with the message
“Could not load file or assembly 'MyNamespace.MyClass, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest.”
Ok…that’s weird… I haven’t even defined a specific version to load, so how can the version conflict with a loaded type? Not to mention that there is only one version available, and that I thought that .NET ignored versioning unless the assembly was signed. Apparently not so in this case…
Luckily, it is a fairly simple thing to fix. Always make sure that you have a version defined in the type name. Replacing the above sample with the following
return Type.GetType("MyNamespace.MyClass, MyAssembly, Version=1.0.0.0");
Makes the exception go away and makes everybody happy…almost… It is kind of annoying that I can’t find a way to iterate through all the loaded types and dynamically add the version… But that’s just the way it is…
Hope putting it up here helps at least someone…
Cheers!