可选的休息服务参数



昨天我遇到了一个问题。我被要求编写一个 rest 服务,它公开了一个类的所有属性。消费者都会使用不同的属性,并且在提交时,他们都会发送不同的属性子集。例如,让我们打电话给合同公司。

class Company{
    public string Address {get;set;}
    public string CompanyNumber {get;set;}
    public string Turnover {get;set;}
    public string Employees {get;set;}
}

假设我们有两个已知的系统想要同步公司类。系统 1 处理会计,想要读取地址和更新营业额。系统 2 处理人力资源,并希望读取地址并更新员工。现在,通常当遇到这个问题时,人们会编写许多接口,每个接口都有一个量身定制的合约以适应最终系统。然而,我被告知这不是他们想要的。相反,如果属性是在 JSON 中提供的,则必须对其进行设置。

问题是,当从 JSON 反序列化类 Company 时,如果未提供属性,则该属性为 null,这将在映射到数据库类时覆盖数据。

我想出的解决方案是创建一个可选结构,如 Nullable,但其中 null 也可以是有效值。反序列化时,此结构可以跟踪属性是否已设置,因此在 JSON 中提供。然后,我可以在从 DTO 映射到数据库类时检查这一点,并且仅在设置属性时进行映射:)

https://dotnetfiddle.net/QmHtSW

public interface IOptional
{
    bool HasBeenSet { get; }
}
public struct Optional<T> : IOptional
{
    internal readonly T Val;
    public Optional(T value)
    {
        Val = value;
        HasBeenSet = true;
    }
    public Optional(Optional<T> value)
    {
        Val = value.Value;
        HasBeenSet = value.HasBeenSet;
    }
    public bool HasBeenSet { get; }
    public override bool Equals(object obj)
    {
        return obj.Equals(Val);
    }
    public override int GetHashCode()
    {
        return Val.GetHashCode();
    }
    public static implicit operator T(Optional<T> optional)
    {
        return optional.Val;
    }
    public static implicit operator Optional<T>(T optional)
    {
        return new Optional<T>(optional);
    }
    public T Value => Val;
}

和我的自动映射器映射配置文件

 CreateMap<TRestObject, TDomainObject>()
            .ForAllMembers(mo=>mo.Condition(f =>
            {
                var opt = f.SourceValue as IOptional;
                return opt==null || opt.HasBeenSet;
            }));

相关内容

  • 没有找到相关文章

最新更新