将包含属性的上下文传递给 TypeConverter
Passing a context containing properties to a TypeConverter
我正在寻找一种将附加信息传递给 TypeConverter
的方法,以便在不创建自定义构造函数的情况下为转换提供一些上下文。
传递的额外信息将是包含我正在转换的 属性 的原始对象(在编译时称为接口)。它包含自己的属性,例如 Id
,可用于查找转换相关信息。
我已经查看了 ITypeDescriptorContext 的文档,但我还没有找到关于如何实现该接口的明确示例。我也不相信这是我需要的工具。
目前,在我的代码中,我正在调用:
// For each writeable property in my output class.
// If property has TypeConverterAttribute
var converted = converter.ConvertFrom(propertyFromOriginalObject)
propertyInfo.SetValue(output, converted, null);
我想做的事情是这样的。
// Original object is an interface at compile time.
var mayNewValue = converter.ConvertFrom(originalObject, propertyFromOriginalObject)
我希望能够使用其中一个重载来执行我需要的操作,以便任何自定义转换器都可以继承自 TypeConverter
而不是具有自定义构造函数的基础 class这将使依赖注入变得更轻松,并使用 MVC 中的 DependencyResolver.Current.GetService(type)
来初始化我的转换器。
有什么想法吗?
您要使用的方法显然是这个重载:TypeConverter.ConvertFrom Method (ITypeDescriptorContext, CultureInfo, Object)
它将允许您传递非常通用的上下文。 Instance
属性 表示您正在处理的对象实例,PropertyDescriptor
属性 表示 属性 值的 属性 定义已转换。
例如,Winforms 属性 网格正是这样做的。
因此,您必须提供自己的上下文。这是一个示例:
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;
}
}
所以,让我们考虑一个自定义转换器,如您所见,它可以使用一行代码获取现有对象的 属性 值(注意此代码与标准现有 ITypeDescriptorContext 兼容,例如 属性网格一虽然在现实生活中,你必须检查上下文是否无效):
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
...
}
}
现在,如果您要修改此自定义对象:
public class MySampleObject
{
public MySampleObject()
{
MySampleProp = "hello world";
}
public string MySampleProp { get; set; }
}
您可以这样调用转换器:
MyTypeConverter tc = new MyTypeConverter();
object newValue = tc.ConvertFrom(new MyContext(new MySampleObject(), "MySampleProp"), null, "whatever");
我正在寻找一种将附加信息传递给 TypeConverter
的方法,以便在不创建自定义构造函数的情况下为转换提供一些上下文。
传递的额外信息将是包含我正在转换的 属性 的原始对象(在编译时称为接口)。它包含自己的属性,例如 Id
,可用于查找转换相关信息。
我已经查看了 ITypeDescriptorContext 的文档,但我还没有找到关于如何实现该接口的明确示例。我也不相信这是我需要的工具。
目前,在我的代码中,我正在调用:
// For each writeable property in my output class.
// If property has TypeConverterAttribute
var converted = converter.ConvertFrom(propertyFromOriginalObject)
propertyInfo.SetValue(output, converted, null);
我想做的事情是这样的。
// Original object is an interface at compile time.
var mayNewValue = converter.ConvertFrom(originalObject, propertyFromOriginalObject)
我希望能够使用其中一个重载来执行我需要的操作,以便任何自定义转换器都可以继承自 TypeConverter
而不是具有自定义构造函数的基础 class这将使依赖注入变得更轻松,并使用 MVC 中的 DependencyResolver.Current.GetService(type)
来初始化我的转换器。
有什么想法吗?
您要使用的方法显然是这个重载:TypeConverter.ConvertFrom Method (ITypeDescriptorContext, CultureInfo, Object)
它将允许您传递非常通用的上下文。 Instance
属性 表示您正在处理的对象实例,PropertyDescriptor
属性 表示 属性 值的 属性 定义已转换。
例如,Winforms 属性 网格正是这样做的。
因此,您必须提供自己的上下文。这是一个示例:
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;
}
}
所以,让我们考虑一个自定义转换器,如您所见,它可以使用一行代码获取现有对象的 属性 值(注意此代码与标准现有 ITypeDescriptorContext 兼容,例如 属性网格一虽然在现实生活中,你必须检查上下文是否无效):
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
...
}
}
现在,如果您要修改此自定义对象:
public class MySampleObject
{
public MySampleObject()
{
MySampleProp = "hello world";
}
public string MySampleProp { get; set; }
}
您可以这样调用转换器:
MyTypeConverter tc = new MyTypeConverter();
object newValue = tc.ConvertFrom(new MyContext(new MySampleObject(), "MySampleProp"), null, "whatever");