将包含属性的上下文传递给类型转换器

10

我正在寻找一种在不创建自定义构造函数的情况下,向 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 而不是一个具有自定义构造函数的基类,这将使依赖注入更加容易,并使用 MVC 中的 DependencyResolver.Current.GetService(type) 来初始化我的转换器。
有什么好的建议吗?

你能解释一下“附加上下文”的意思吗? - krillgar
没问题,我已经加了一点来描述额外的上下文。 - James South
谁给踩了一下,可以解释一下吗? - James South
2
我们都希望有更多的上下文信息 - 更多关于您想要做什么,而不是您想如何做到这一点。 - Ňɏssa Pøngjǣrdenlarp
1
标题和问题非常明确。 - James South
1个回答

10
您想要使用的方法显然是这个重载: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");

太好了!是的,我在自定义转换器中使用了这个重载。实现ITypeDescriptorContext是导致我困扰的原因,我从来没有真正使用过Winforms,主要是Web开发。等允许时我会添加赏金。非常感谢! - James South

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接