C# – Alternatives to Translate Data Models

cinterfacesobject-oriented-design

I have a need to translate data from provider A to provider B. The data is typically pretty consistent, but, often has minor differences; for example:

public sealed class ProviderOneFoo {
    public int Bar { get; set; }
}
public sealed class ProviderTwoFoo {
    public long Barr { get; set; }
}

My present idea is to utilize interfaces to work with the data instead of dedicated types:

public interface IFoo {
    object Bar { get; set; }
}
public sealed class ProviderOneFoo : IFoo {
    public object Bar { get; set; }
}
public sealed class ProviderTwoFoo : IFoo {
    private long _bar { get; set; }
    public long Barr { get => _bar; set => _bar = value; }
    public object Bar { get => _bar; set => _bar = long.Parse(value.ToString()); }
}

However, I don't like this setup for a few reasons:

  • The types might not match the provider's type specifications.
  • The property can be duplicated which confuses consumers working directly with ProviderTwoFoo.
  • Increased maintenance requirements due to the addition of fields that wouldn't typically be required, and additional properties.
  • Danger in the assignments to both provider's models due to the use of object when types don't match.
    • I'm aware there are better ways, I just wrote this quickly to summarize my current thoughts.

Currently, I have an idea to utilize reflection and allow properties that can be translated, to be assigned an attribute like Translatable that specifies the internal name of the property. However, I don't like this route for two very specific reasons:

  • Since enum isn't compile time constant, magic strings have to be used to define the internal name leading to inconsistencies.
  • Reflection will introduce some potentially pretty high overhead.

The major advantages to the reflection approach is that each data model can use the types specified by the provider and there's reduced maintenance requirements since a centralized source performs the translation through the attributes.


Are there any other alternative ways to translate data models that could allow lightweight translation between types with inconsistencies?

Best Answer

need to translate data from provider A to provider B

public static ProviderTwoFoo ConvertToBProvider(this ProviderOneFoo data)
{
    return new ProviderTwoFoo 
    {
        Barr = data.Bar
    };
}  

// Usage
var providerBdata = providerAdata.ConvertToBProvider();
  • Type it only once
  • Supports all possible conversion logics (main benefit)
  • Readable and comprehensible for anybody working with the code

Notice that programmers writing the code only 10% of their time - so trying to save time on typing with third party dependency or complex reflection logic will increase reading time or time required to understand how conversion works for other programmers.

Related Topic