Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject custom type conversion to .NET library classes

Tags:

c#

.net

guid

I would like to implement conversion between two library classes by Convert.ChangeType in C#. I can change neither of the two types. For example converting between Guid and byte[].

Guid g = new Guid(); object o1 = g; byte[] b = (byte[]) Convert.ChangeType(o1, typeof(byte[])); // throws exception 

I am aware that Guid provides a ToByteArray() method, but I would like to have that called when Guid is converted to byte[]. The reason behind this is that the conversion also takes place in library code (AseDataAdapter) which I can not modify. So is it possible to define a conversion rule between two types without modifying the sourcecode of either of the two classes?

I was experimenting with TypeConverter, but doesn't seem to work either:

Guid g = new Guid(); TypeConverter tc = TypeDescriptor.GetConverter(typeof(Guid)); byte[] b2 = (byte[])tc.ConvertTo(g, typeof(byte[])); // throws exception 

The variable tc gets set to System.ComponentModel.GuidConverter which doesn't support conversions to byte[]. Can I have two TypeConverters for the same class? Even if I could, wouldn't I need to prepend an attribute to the source code of the class to assign a TypeConverter?

Thanks

like image 546
shojtsy Avatar asked Mar 03 '09 15:03

shojtsy


People also ask

What is an object type conversion?

Type conversion creates a value in a new type that is equivalent to the value of an old type, but does not necessarily preserve the identity (or exact value) of the original object. Conversion from a derived class to a base class. This means, for example, that an instance of any class or structure can be converted to an Object instance.

What is initialize in typeconverter?

Initializes a new instance of the TypeConverter class. Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. Returns whether this converter can convert an object of the given type to the type of this converter.

What are the conversions supported by the NET Framework?

The .NET Framework automatically supports the following conversions: Conversion from a derived class to a base class. This means, for example, that an instance of any class or structure can be converted to an Object instance. This conversion does not require a casting or conversion operator.

Does first-class support dependency injection in classes?

As you can see, it’s very easy to provide first-class support for dependency injection in .NET Core class libraries. The library itself can leverage dependency injection internally, as well as being available service-style to other libraries or applications that consume the library.


1 Answers

You can change the registered TypeConverter for something using TypeDescriptor.AddAttributes; this isn't quite the same as Convert.ChangeType, but it may suffice:

using System; using System.ComponentModel; static class Program {     static void Main()     {         TypeDescriptor.AddAttributes(typeof(Guid), new TypeConverterAttribute(             typeof(MyGuidConverter)));          Guid guid = Guid.NewGuid();         TypeConverter conv = TypeDescriptor.GetConverter(guid);         byte[] data = (byte[])conv.ConvertTo(guid, typeof(byte[]));         Guid newGuid = (Guid)conv.ConvertFrom(data);     } }  class MyGuidConverter : GuidConverter {     public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)     {         return sourceType == typeof(byte[]) || base.CanConvertFrom(context, sourceType);     }     public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)     {         return destinationType == typeof(byte[]) || base.CanConvertTo(context, destinationType);     }     public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)     {         if (value != null && value is byte[])         {             return new Guid((byte[])value);         }         return base.ConvertFrom(context, culture, value);     }     public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)     {         if (destinationType == typeof(byte[]))         {             return ((Guid)value).ToByteArray();         }         return base.ConvertTo(context, culture, value, destinationType);     } } 
like image 154
Marc Gravell Avatar answered Sep 25 '22 10:09

Marc Gravell