I'm looking for a way of passing additional information to a TypeConverter
in order to provide some context for conversions without creating a custom constructor.
That extra information passed would be original object (known at compile time as an interface) that contains the property that I am converting. It contains properties of its own like Id
that are useful for lookups to convert related information.
I've had a look at the documentation for ITypeDescriptorContext but I haven't found a clear-cut example of how to implement that interface. I'm also not convinced it's the tool I need.
At the moment, in my code I'm calling:
// For each writeable property in my output class.
// If property has TypeConverterAttribute
var converted = converter.ConvertFrom(propertyFromOriginalObject)
propertyInfo.SetValue(output, converted, null);
What I'd like to do is something like.
// Original object is an interface at compile time.
var mayNewValue = converter.ConvertFrom(originalObject, propertyFromOriginalObject)
I'd like to be able to use one of the overloads to do what I need so that any custom converters can inherit from TypeConverter
rather than a base class with a custom constructor as that would make life easier with dependency injection and use DependencyResolver.Current.GetService(type)
from MVC to initialise my converter.
Any ideas?
The method you want to use is clearly this overload: TypeConverter.ConvertFrom Method (ITypeDescriptorContext, CultureInfo, Object)
It will allow you to pass a pretty generic context. The Instance
property represents the object instance you're working on, and the PropertyDescriptor
property represents the property definition of the property value being converted.
For example, the Winforms property grid does exactly that.
So, you'll have to provide your own context. Here is a sample one:
public class MyContext : ITypeDescriptorContext
{
public MyContext(object instance, string propertyName)
{
Instance = instance;
PropertyDescriptor = TypeDescriptor.GetProperties(instance)[propertyName];
}
public object Instance { get; private set; }
public PropertyDescriptor PropertyDescriptor { get; private set; }
public IContainer Container { get; private set; }
public void OnComponentChanged()
{
}
public bool OnComponentChanging()
{
return true;
}
public object GetService(Type serviceType)
{
return null;
}
}
So, let's consider a custom converter, as you see it can grab the existing object's property value using one line of code (note this code is compatible with standard existing ITypeDescriptorContext like the property grid one although in real life scenarios, you must check the context for nullity):
public class MyTypeConverter : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
// get existing value
object existingPropertyValue = context.PropertyDescriptor.GetValue(context.Instance);
// do something useful here
...
}
}
Now, if you have this custom object being modified:
public class MySampleObject
{
public MySampleObject()
{
MySampleProp = "hello world";
}
public string MySampleProp { get; set; }
}
You can call the converter like this:
MyTypeConverter tc = new MyTypeConverter();
object newValue = tc.ConvertFrom(new MyContext(new MySampleObject(), "MySampleProp"), null, "whatever");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With