QAI
QAI

Reputation: 3

DTO Between two Classes

So this got asked here a thousand times but nothing helped me so far.

Problem:

I have a class that receives data from my Controller, transferring this data to an API and get a Result. So far it worked.

but now I am stuck because I have to do something like this

Controller --> ARequestClass --> BRequestClass-->CientClass recive data --> ClientClass response data -->BResultClass-->AResultClass-->Controller

The Connection between the Controller and ARequestClass works. The Connection between BRequestClass and the ClienClasst works

but how can I say witch Property from ArequestClass belongs to BRequestClass

I tried AutoMapper and watched and read tones of DTO stuff but all of them couldn't help me :|

it looks like this

public class ARequest
{
    public string AText { get; set; }
    public string AProductKey { get; set; }
    public string ASettings { get; set; }
}
public class BRequest
{
    public string BText { get; set; }
    public string BProductKey { get; set; }
    public string BSettings { get; set; }
}
public class ClientClass
{
    public BResult DoSomething(BRequest request)
    {
        client.something = $"www.anRandomApi.com/{request.BText}{request.BProductKey}{request.BSettings};
        return client;
    }
}

I know its an easy problem and the solution should be very easy but I'm having a brain fart and need some help

Upvotes: 0

Views: 425

Answers (1)

ProgrammingLlama
ProgrammingLlama

Reputation: 38767

I think whenever possible it's better to avoid having to manually specify mappings between properties. I'm not sure if there's a good reason in your case why it's AProductKey and BProductKey and not simply ProductKey in both (which AutoMapper would handle for you automatically). If the issue relates to serialization, a better approach in your classes might be to use the JsonProperty attribute to map from a JSON object into a more maintainable property in C#.

Anyway, you can specify the mapping for specific properties using AutoMapper (recommended way):

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<ARequest, BRequest>()
        .ForMember(dest => dest.BText, o => o.MapFrom(src => src.AText))
        .ForMember(d => d.BProductKey, o => o.MapFrom(s => s.AProductKey))
        .ForMember(d => d.BSettings, o => o.MapFrom(s => s.ASettings));
});

Or, if you want the more dangerous option that saves you mapping each property individually (I would avoid this in production code):

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<ARequest, BRequest>()
        .ForAllMembers(mo =>
        {
            var convertedName = mo.DestinationMember.Name;
            if (convertedName.StartsWith("B"))
            {
                convertedName = "A" + convertedName.Substring(1);
            }
            mo.MapFrom(convertedName);
        });
});

Alternatively, you could do this without AutoMapper by adding a constructor to BRequest that takes an ARequest:

public class BRequest
{
    public BRequest() { }

    public BRequest(ARequest source)
    {
        this.BText = source.AText;
        this.BProductKey = source.AProductKey;
        this.BSettings = source.ASettings;
    }

    public string BText { get; set; }
    public string BProductKey { get; set; }
    public string BSettings { get; set; }
}

Upvotes: 1

Related Questions