Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对多个成员使用AutoMapper自定义值解析器_C#_Asp.net Core_Automapper - Fatal编程技术网

C# 对多个成员使用AutoMapper自定义值解析器

C# 对多个成员使用AutoMapper自定义值解析器,c#,asp.net-core,automapper,C#,Asp.net Core,Automapper,我试图使用自定义值解析程序方法将源类型中的成员数据解析为目标类型中的成员。我已尽可能密切地关注AutoMapper网站上的文档。我已仔细检查,以确保我遵循提供的示例,但有一个区别。源上的成员与目标上的成员类型不同 IValueResolver.cs public interface IValueResolver<in TSource, in TDestination, in TSourceMember, TDestinationMember> { TDestinationMe

我试图使用自定义值解析程序方法将源类型中的成员数据解析为目标类型中的成员。我已尽可能密切地关注AutoMapper网站上的文档。我已仔细检查,以确保我遵循提供的示例,但有一个区别。源上的成员与目标上的成员类型不同

IValueResolver.cs

public interface IValueResolver<in TSource, in TDestination, in TSourceMember, TDestinationMember>
{
    TDestinationMember Resolve(TSource source, TDestination destination, TSourceMember sourceMember, TDestinationMember destinationMember, ResolutionContext context);
}
public class DisplayIdResolver : IValueResolver<object, object, int, string>
{
    // Seems like this may be useless unless its mapping to a destination member of the same type as the source member
    public string Resolve(object source, object destination, int sourceMember, string destinationMember, ResolutionContext context)
    {
        if (source.GetType().Equals(typeof(Developer)))
        {
            return IdentifierType.ConvertToAppId(sourceMember, IdentifierType.DEVELOPER.Code);
        }
        . . . etcetera . . .
     }
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Developer, DeveloperDetailModel>().ForMember(dest => dest.DisplayId, opt => opt.MapFrom<DisplayIdResolver, int>(src => src.DeveloperId));
    }
}
public interface IMemberValueResolver<in TSource, in TDestination, TSourceMember, TMember>
{
    TMember Resolve(TSource source, TDestination destination, TSourceMember sourceMember, TMember destinationMember, ResolutionContext context);
}
public class DisplayIdResolver : IMemberValueResolver<object, object, int, string>
{
    public string Resolve(object source, object destination, int sourceMember, string destinationMember, ResolutionContext context)
    {
        if (source.GetType().Equals(typeof(Developer)))
        {
            return IdentifierType.ConvertToDisplayId(sourceMember, IdentifierType.DEVELOPER.Code);
        }

        ... more type comparisons here, etc ...

        return null;
    }
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Developer, DeveloperDetailModel>().ForMember(dest => dest.DisplayId, opt => opt.MapFrom<DisplayIdResolver, int>(src => src.DeveloperId));
    }
}
AutoMapperProfile.cs

public interface IValueResolver<in TSource, in TDestination, in TSourceMember, TDestinationMember>
{
    TDestinationMember Resolve(TSource source, TDestination destination, TSourceMember sourceMember, TDestinationMember destinationMember, ResolutionContext context);
}
public class DisplayIdResolver : IValueResolver<object, object, int, string>
{
    // Seems like this may be useless unless its mapping to a destination member of the same type as the source member
    public string Resolve(object source, object destination, int sourceMember, string destinationMember, ResolutionContext context)
    {
        if (source.GetType().Equals(typeof(Developer)))
        {
            return IdentifierType.ConvertToAppId(sourceMember, IdentifierType.DEVELOPER.Code);
        }
        . . . etcetera . . .
     }
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Developer, DeveloperDetailModel>().ForMember(dest => dest.DisplayId, opt => opt.MapFrom<DisplayIdResolver, int>(src => src.DeveloperId));
    }
}
public interface IMemberValueResolver<in TSource, in TDestination, TSourceMember, TMember>
{
    TMember Resolve(TSource source, TDestination destination, TSourceMember sourceMember, TMember destinationMember, ResolutionContext context);
}
public class DisplayIdResolver : IMemberValueResolver<object, object, int, string>
{
    public string Resolve(object source, object destination, int sourceMember, string destinationMember, ResolutionContext context)
    {
        if (source.GetType().Equals(typeof(Developer)))
        {
            return IdentifierType.ConvertToDisplayId(sourceMember, IdentifierType.DEVELOPER.Code);
        }

        ... more type comparisons here, etc ...

        return null;
    }
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Developer, DeveloperDetailModel>().ForMember(dest => dest.DisplayId, opt => opt.MapFrom<DisplayIdResolver, int>(src => src.DeveloperId));
    }
}
如果是这种情况,那么这将没有什么用处,因为我确实需要源对象类型,以便将源成员映射到目标成员。我还尝试将它与一个附加的对象参数一起用作源,但是
ConvertUsing
方法没有包含3个参数的重载。我也不知道如何用新的文档来实现这一点

编辑2

有人建议我使用IMemberValueResolver。这就是我所做的:

IMemberValueResolver.cs

public interface IValueResolver<in TSource, in TDestination, in TSourceMember, TDestinationMember>
{
    TDestinationMember Resolve(TSource source, TDestination destination, TSourceMember sourceMember, TDestinationMember destinationMember, ResolutionContext context);
}
public class DisplayIdResolver : IValueResolver<object, object, int, string>
{
    // Seems like this may be useless unless its mapping to a destination member of the same type as the source member
    public string Resolve(object source, object destination, int sourceMember, string destinationMember, ResolutionContext context)
    {
        if (source.GetType().Equals(typeof(Developer)))
        {
            return IdentifierType.ConvertToAppId(sourceMember, IdentifierType.DEVELOPER.Code);
        }
        . . . etcetera . . .
     }
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Developer, DeveloperDetailModel>().ForMember(dest => dest.DisplayId, opt => opt.MapFrom<DisplayIdResolver, int>(src => src.DeveloperId));
    }
}
public interface IMemberValueResolver<in TSource, in TDestination, TSourceMember, TMember>
{
    TMember Resolve(TSource source, TDestination destination, TSourceMember sourceMember, TMember destinationMember, ResolutionContext context);
}
public class DisplayIdResolver : IMemberValueResolver<object, object, int, string>
{
    public string Resolve(object source, object destination, int sourceMember, string destinationMember, ResolutionContext context)
    {
        if (source.GetType().Equals(typeof(Developer)))
        {
            return IdentifierType.ConvertToDisplayId(sourceMember, IdentifierType.DEVELOPER.Code);
        }

        ... more type comparisons here, etc ...

        return null;
    }
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Developer, DeveloperDetailModel>().ForMember(dest => dest.DisplayId, opt => opt.MapFrom<DisplayIdResolver, int>(src => src.DeveloperId));
    }
}
AutoMapperProfile.cs

public interface IValueResolver<in TSource, in TDestination, in TSourceMember, TDestinationMember>
{
    TDestinationMember Resolve(TSource source, TDestination destination, TSourceMember sourceMember, TDestinationMember destinationMember, ResolutionContext context);
}
public class DisplayIdResolver : IValueResolver<object, object, int, string>
{
    // Seems like this may be useless unless its mapping to a destination member of the same type as the source member
    public string Resolve(object source, object destination, int sourceMember, string destinationMember, ResolutionContext context)
    {
        if (source.GetType().Equals(typeof(Developer)))
        {
            return IdentifierType.ConvertToAppId(sourceMember, IdentifierType.DEVELOPER.Code);
        }
        . . . etcetera . . .
     }
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Developer, DeveloperDetailModel>().ForMember(dest => dest.DisplayId, opt => opt.MapFrom<DisplayIdResolver, int>(src => src.DeveloperId));
    }
}
public interface IMemberValueResolver<in TSource, in TDestination, TSourceMember, TMember>
{
    TMember Resolve(TSource source, TDestination destination, TSourceMember sourceMember, TMember destinationMember, ResolutionContext context);
}
public class DisplayIdResolver : IMemberValueResolver<object, object, int, string>
{
    public string Resolve(object source, object destination, int sourceMember, string destinationMember, ResolutionContext context)
    {
        if (source.GetType().Equals(typeof(Developer)))
        {
            return IdentifierType.ConvertToDisplayId(sourceMember, IdentifierType.DEVELOPER.Code);
        }

        ... more type comparisons here, etc ...

        return null;
    }
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Developer, DeveloperDetailModel>().ForMember(dest => dest.DisplayId, opt => opt.MapFrom<DisplayIdResolver, int>(src => src.DeveloperId));
    }
}
正如您所看到的-他们正在使用一个通用接口来
IMemberValueResolver
,使用签名,这就是我正在做的,只是返回值是一个字符串,而不是一个整数,所以它变成了(正如我之前发布的):

公共接口IMemberValueResolver
{
t成员解析(TSource-source、TDestination-destination、TSourceMember-sourceMember、TMember-destinationMember、ResolutionContext上下文);
}
但是,以与示例中相同的方式调用它会导致非编译代码,如前所述(我已经发布了两次堆栈跟踪错误):

CreateMap().formMember(dest=>dest.DisplayId,opt=>opt.MapFrom(src=>src.DeveloperId));

OK,如果您需要源类型a值转换器,则它将不起作用。但你在这里所做的是混淆IMemberValueResolver和IValueResolver。您必须选择一个:)但是如果您需要源类型,那么使用单独的解析器似乎更容易。为什么要重用它们,然后检查源类型。“IMemberValueResolver with IValueResolver”-我不知道我在这么做,我只是按照第一个文档链接上的示例进行了操作。IMemberValueResolver仅在生成错误的堆栈跟踪中提及。我在AutoMapperProfile类中使用了什么方法调用IMemberValueResolver?我不清楚“为什么重用它们,然后检查源类型”是什么意思。“重用”是什么意思?从我的代码中,我看不到我在哪里重用任何东西。我想我只使用了一次解析器。