gpt4 book ai didi

c# - 使用通用目的地映射不起作用?

转载 作者:行者123 更新时间:2023-12-02 20:05:39 24 4
gpt4 key购买 nike

我正在尝试构建映射配置文件的层次结构,以简化为适合此层次结构的新对象创建映射的过程。但我无法让一些映射正常工作。我使用泛型类型参数添加的映射在目标类型时似乎不起作用,但在源类型时却起作用。

考虑以下类型:

public interface IRequest
{
string Input { get; }
}
public interface IResponse
{
string Output { get; }
}
public class SomeObject
{
public string Value { get; set; }
}
abstract class BaseProfile<TSource, TDestination> : Profile
where TSource : IRequest
where TDestination : IResponse
{
protected BaseProfile()
{
CreateMap<TSource, SomeObject>()
.ForMember(src => src.Value, opt => opt.MapFrom(dest => dest.Input));
CreateMap<SomeObject, TDestination>()
.ForMember(src => src.Output, opt => opt.MapFrom(dest => dest.Value));
}
}

我希望能够做到这一点,以便具体类型的配置文件可以使用此父配置文件中的映射,这样我就能够定义它:

class FooRequest : IRequest
{
public string Input { get; set; }
}
class FooResponse : IResponse
{
public string Output { get; set; }
}
class FooProfile : BaseProfile<FooRequest, FooResponse>
{
public FooProfile()
{
}
}

但是,到响应对象的映射根本不映射。

Mapper.Initialize(c => c.AddProfiles(typeof(FooProfile).Assembly));
var request = new FooRequest { Input = "FOO" };
var obj = Mapper.Map<SomeObject>(request); // this works
// obj.Value = "FOO"
var response = Mapper.Map<FooResponse>(obj); // this doesn't
// response.Output = null

似乎可以解决这个问题,我必须复制我认为已经创建的映射,但使用具体类型。

public FooProfile()
{
// Adding this works
CreateMap<SomeObject, FooResponse>()
.ForMember(src => src.Output, opt => opt.MapFrom(dest => dest.Value));
}

我是否缺少一些东西来完成这项工作?或者我每次都必须创建这些显式映射?


正如 Scott 的回答所指出的,最终的问题是通用参数所约束的接口(interface)没有可设置的属性。但 Nader 还发现使用 ForMember() 方法的特定重载是有效的。因此,我们不是直接绑定(bind)到成员,而是绑定(bind)到成员名称。这很适合我的需要。

protected BaseProfile()
{
CreateMap<TSource, SomeObject>()
.ForMember(src => src.Value, opt => opt.MapFrom(dest => dest.Input));
CreateMap<SomeObject, TDestination>()
.ForMember(nameof(IResponse.Output), opt => opt.MapFrom(dest => dest.Value));
}

最佳答案

将 setter 添加到 IResponseOutput 属性。

public interface IResponse
{
string Output { get; set; }
}

它正在尝试映射到 IReponse,但无法设置该属性,因为该属性不可写。

也许这不是您想要的,因为您不希望 IResponse 具有可写属性。但这就是它没有被设置的原因。

在这种情况下,我可以确定的唯一解决方法是创建一个实现 IResponse 并具有可写属性的基本响应。

class ResponseBase : IResponse
{
public string Output { get; set; }
}

class FooResponse : ResponseBase
{
}

然后将通用约束更改为基类而不是接口(interface):

abstract class BaseProfile<TSource, TDestination> : Profile
where TSource : IRequest
where TDestination : ResponseBase

该通用约束将确定如何转换目标类型,进而确定该属性是否可写。

关于c# - 使用通用目的地映射不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54793983/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com