Type Converter to Type

来源:转载

What happens when you need to pass a type as a string? Well, if the string is an assembly qualified type name, and if the assembly is either in Global Assembly Cache or in a known location – such as the Binfolder or a probed path– you’re likely to succeed. But, what if that isn’t the case? Well, we can follow these steps:

Try to locate the type the usual way, by calling Type.GetType;

Look the type in the current executing, entry and calling assemblies;

Look it up in all of the loaded assemblies for the current domain (could be a lot);

Hook up the TypeResolveevent of the current app domain (I am not going to show that).

Normally, in .NET we use type convertersfor doing this kind of stuff in configuration files or ASP.NET markup. Following that, a type converter for turning a string into a type might look like this:

public sealed class TypeTypeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof (string)) { return true; } return base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof (Type)) { return true; } return base.CanConvertTo(context, destinationType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { var typeName = value.ToString(); //first attempt var type = Type.GetType(typeName, false, true); if (type == null) { //second attempt var assemblies = new[] { Assembly.GetEntryAssembly(), Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly() }.Where(asm => asm != null).Distinct(); foreach (var assembly in assemblies) { type = assembly.GetType(typeName, false, true); if (type != null) { break; } } } if (type == null) { //third attempt var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { type = assembly.GetType(typeName, false, true); if (type != null) { break; } } } return type; } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof (Type)) { return this.ConvertFrom(context, culture, value); } return base.ConvertTo(context, culture, value, destinationType); } }

We just need to apply a TypeConverterAttributeattribute to a property and the magic occurs naturally:

[TypeConverter(typeof(TypeTypeConverter))] public Type Type { get; set; }

Or if we need to invoke it explicitly:

var converter = TypeDescriptor.GetConverter(typeof(Type)); var type = converter.ConvertFromString("MyNamespace.MyClass");

And that’s it. Keep in mind that it is always preferable that you specify an assembly qualified type name, but if that can’t be done, this might come in handy.


分享给朋友:
您可能感兴趣的文章:
随机阅读: