【问题标题】:Constructor for different input types without code duplication in C#C#中不同输入类型的构造函数,没有代码重复
【发布时间】:2022-01-23 11:55:57
【问题描述】:

我的数据类的映射有问题。 它包含 164 个属性,这些属性填充了从肥皂网络服务接收到的数据。不要质疑属性数量,这是一个非常古老的预定义 .csv 类数据方案,我无法更改。

据我所知,现在一切正常,但由于有这么多属性,我明确设置了每一个(例如 data.a1 = import.a1 OR data.a1 = export.a1)我有一个大块重复的赋值代码。两种 Web 服务都提供相同的 164 个字段以及两个类不同的一些附加字段。我想我只需要映射 164 个相同的字段,可以忽略/丢弃其他字段。

解决这个问题的正确方法是什么?我曾考虑在构造函数中使用“对象”或其他东西作为数据类型,这样我就可以从两个服务中传递数据,但它似乎不像我想象的那样工作。

任何建议将不胜感激。

    /// <summary> Initializes a new instance of the <see cref="DataTypeTest" /> class. </summary>
    /// <param name="incomingData"> Record from Export Webservice that will be mapped to the constructed instance. </param>
    public Stddat(webExport incomingData)
    {
        // stddat fields
        this.Fields.SndRec = webExport.SndRec;
        this.Fields.PrtNum = webExport.PrtNum;
        this.Fields.MsgTyp = webExport.MsgTyp;
        .
        .
        .
    }   
    
    /// <summary> Initializes a new instance of the <see cref="DataTypeTest" /> class. </summary>
    /// <param name="incomingData"> Record from Exchange Webservice that will be mapped to the constructed instance. </param>
    public Stddat(webExchange incomingData)
    {
        // stddat fields
        this.Fields.SndRec = webExchange.SndRec;
        this.Fields.PrtNum = webExchange.PrtNum;
        this.Fields.MsgTyp = webExchange.MsgTyp;
        .
        .
        .
    }

【问题讨论】:

  • WebExchange 是否继承自 WebExport,反之亦然? (或者它们都继承自具有 164 个通用道具的基类)
  • 它们都有自己的由 svcutil.exe 生成的类。我宁愿只有一个类,因为它包含相同的数据。我发现了 WSDL.exe (wsdl.exe /sharetypes) 的命令。这是我第一次使用 Web 服务,而且我在编程世界中通常是“新人”,所以我可能会忽略一些事情。 WSDL.exe 似乎不再受支持,因为我使用的是 .NET 6 而不是 .NET Framework
  • 我想如果你不重新生成它们,你可以修改生成的类.. ?
  • (另外,刚刚注意到,您的构造函数头中的代码有(webExport incomingData) 但正文是... = webExport.X 有点困惑 - webExport 是类型?这些是静态的吗?或者这段代码是释义/... = incomingData.X的错字
  • 您在那里发现了复制/粘贴错误。它必须是 'this.Fields.SndRec = incomingData.SndRec;'我现在正试图将这两个 Web 服务整合到一个类中,但我无法正确获取命名空间。我收到错误消息:“消息中的命名空间“urn:microsoft-dynamics-schemas/page/NxsWebservice”无效,应为“urn:microsoft-dynamics-schemas/page/nxsexport”。但由于消息是服务器响应,我无法更改它,所以我必须以某种方式动态更改预期的命名空间

标签: c# web-services mapping svcutil.exe


【解决方案1】:

好吧,如果有这么多属性,那么我会说地图软件是合理的。

有经典的自动映射器,

AutoMapper 是一个简单的小库,旨在解决看似复杂的问题 - 摆脱将一个对象映射到另一个对象的代码。

https://automapper.org/

但也有 Mapster:

https://github.com/MapsterMapper/Mapster

它有一个可能有用也可能没用的代码生成工具。

还有其他各种正面和负面的方面——这些都是我的想法。

【讨论】:

  • 我肯定还有其他人..
  • @CaiusJard 显然! :3
  • 使用外部库来完成这项工作听起来是个好主意。我想有些人认为轻量级就足够了,因为我现在只需要映射功能。我会先检查 AutoMapper,因为我现在只需要映射功能。
  • 是的 - 谨慎使用它,因为你失去了静态类型检查。这就是为什么我发现 mapster 很有趣,它允许您只生成映射代码。
  • 这很棒,使用 AutoMapper 我可以将 500 行代码减少到 5 行。太糟糕了,我似乎无法在 cmets 中发布格式化代码。
【解决方案2】:

如果您可以修改生成的类,使您的 X 和 Y 中的每一个都继承相同的基础,或者实现指定 164 个道具的相同接口,那么您可以从另一个调用一个构造函数

public Stddat(BaseClass incomingData){
  //set 164 props here
}

public Stddat(WebExport incomingData) : this((BaseClass)incomingData) //set 164 props
{
  this.UniqueToWebExport1 = incomingData.UniqueToWebExport1;
  ...
}

public Stddat(WebExchange incomingData) : this((BaseClass)incomingData) //set 164 props
{
  this.UniqueToWebExchange1 = incomingData.UniqueToWebExchange1;
  ...
}

【讨论】:

    猜你喜欢
    • 2017-12-17
    • 2020-09-22
    • 2020-03-14
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    相关资源
    最近更新 更多