15

它看起来像 anIValueFormatter接受一个 type 的值object并返回一个 type 的值string,而 aValueResolver<TSource, TDestination>接受一个任何类型的值并返回一个任何类型的值。所以,它更灵活。还有一个问题是,使用 a ValueResolver,您永远不需要将源转换为特定类型——您在类定义中明确定义它。

鉴于此,为什么要使用IValueFormatter?它会做一些不能做的事情ValueResolver吗?我误解了它是如何工作的吗?

4

3 回答 3

13

最大的区别是格式化程序可以应用于成员、配置文件、类型和全局级别。因此,您可以在配置文件中执行诸如“ForSourceType.AddFormatter() 之类的操作,现在 blammo!您所有的小数现在都显示为钱。解析器严格用于自定义成员映射。

于 2010-02-01T22:41:53.990 回答
3

好的,我想我已经弄清楚了:

  • 使用IValueFormatter,方法的输入FormatValue()是实际值。(好吧,从技术上讲,它是一个ResolutionContext可以让您使用SourceValue属性获得价值的对象,但您明白了)。

  • 使用 a ValueResolverResolveCore()方法的输入是整个源(不仅仅是源值)。

因此,如果您想在源值和目标值之间进行某种转换,则 anIValueFormatter仅在目标类型为 a时才有效string,并且 aValueResolver仅在ResolveCore()方法“知道”要使用的属性时才有效(这不会'如果您的解析器是通用的,即不适用于特定属性,则情况并非如此)。

解决方法

幸运的是,总是有MapFrom,它提供了解析器和格式化程序所缺乏的灵活性。

转换器接口

我最终编写了一个界面来简单灵活地处理我认为非常常见的场景:双向转换......

public interface ITwoWayConverter<TInput, TOutput>
{
    TOutput ConvertForward(TInput value);
    TInput ConvertBackward(TOutput value);
}

示例转换器:

public class PhoneNumberToString : ITwoWayConverter<long, string>
{
    public string ConvertForward(long value)
    {
        return string.Format("{0:(###) ###-####}", Convert.ToInt64(value));
    }

    public long ConvertBackward(string value)
    {
        return Convert.ToInt64(Regex.Replace(value, @"\D", string.Empty));
    }
}

示例用法:

Mapper.CreateMap<User, UserViewModel>()
    .ForMember(dest => dest.PhoneNumber, opt => opt
        .MapFrom(orig => new PhoneNumberToString().ConvertForward(orig.PhoneNumber)));
于 2010-02-01T05:10:17.443 回答
0

IValueFormatter 是一个接口,可以附加到您现有的类或与它产生的任何库一起使用,看起来 ValueResolver 是一个可能具有更广泛使用范围的类......换句话说,IValueFormatter可能用于帮助您将类与它来自的库一起使用,而值解析器旨在帮助您在代码中使用它们的类。

于 2010-02-01T03:13:43.807 回答