Proper way of mapping in C#

Posted on

Problem

I have a WCF service that itself uses another third party WCF service. It’s basically a proxy. So I’m getting a request to my own one and I have just to “forward” it to the third party one.

I would like then to map from my flattened request (that’s the way it’s been decided to be coded) to the slightly more complex request the other service needs.

Although quite a few of the properties in each request are a naming match my issues are the following

  1. There are properties flattened in my request in relation to theirs

  2. There’s a huge load of my properties that should go into theirs “generic” Data[] ApplicationDetails property being both as follows:

public class ApplicationDetails
{
    public Data[] Data { get; set; }
}

public class Data
{
    public string category { get; set; }

    public string attribute { get; set; }

    public string Value { get; set; }
}

And those will come from my request as a property named as the attribute should be, i.e. my request will have a property named AIM and I should put that as an the attribute of one of the elements of the Data array, it’s value as the element’s value and hardcode the category (there are 3 of them).

I couldn’t see many advantages (apart for the equally named properties) for using Automapper (or any other it could be) and ended up with a massive static Mapper class that looks this way

public static class Mapper
{
    public static Request FromDecisionRequestToZRequest(DecisionRequest request)
    {
        var applicationDetails = new Data[]
        {
            new Data {category = "ID", attribute = "PubID", Value = request.PubID},
            new Data {category = "ID", attribute = "AID", Value = request.AID},
            new Data {category = "APP", attribute = "NID", Value = request.NID},
            new Data {category = "BOOK", attribute = "DupeApps90", Value = request.DupeApps90},
            new Data {category = "BOOK", attribute = "DupeApps30", Value = request.DupeApps30},

            //And many others of each of the three categories

        };

        var address = new Address[]
        {   new Address{
                City = request.City,
                Country = request.Country,
                HouseNumber = request.HouseNumber,
                HouseNumberExtension = request.HouseNumberExtension,
                Street = request.Street,
                ZIP = request.ZIP,
                kind = "MAIN"
            }
        };

        var ret = new Request()
        {
            UserName = request.UserName,
            RequestDateTime = Convert.ToDateTime(request.RequestDateTime),
            CompanyRegistrationID = request.CompanyRegistrationID,

            //And many others "direct" mappings

            Addresses = new Addresses { Address = address },
            Phone1 = new Phone1 { type = "1", Value = request.Phone1 },
            Phone2 = new Phone2 { type = "2", Value = request.Phone2 },
            Phone3 = new Phone3 { type = "3", Value = request.Phone3 },
            Email = request.Email,
            Amount = new Amount { Value = request.Amount },

            ApplicationDetails = new ApplicationDetails { Data = applicationDetails }
        };

        return ret;
    }
}

How would you tackle this? To me this static class looks horrible (taking into account that the full one has more than 150 lines but not sure how I could improve it).

Solution

I would create two extension method , ToApplicationData and ToAddress and will define mapping over there. it will sorten you code and much better readablity. you can break this methods too if you want.

 public static class Mapping
    {
        public static Data[] ToApplicationData (this DecisionRequest request)
        {
            return new[]
            {
                new Data {category = "ID", attribute = "PubID", Value = request.PubID},
                new Data {category = "ID", attribute = "AID", Value = request.AID},
                new Data {category = "APP", attribute = "NID", Value = request.NID},
                new Data {category = "BOOK", attribute = "DupeApps90", Value = request.DupeApps90},
                new Data {category = "BOOK", attribute = "DupeApps30", Value = request.DupeApps30}
            };
        }

        public static Address[] ToAddresses(this DecisionRequest request)
        {
            return new Address[]
            {
                new Address
                {
                    City = request.City,
                    Country = request.Country,
                    HouseNumber = request.HouseNumber,
                    HouseNumberExtension = request.HouseNumberExtension,
                    Street = request.Street,
                    ZIP = request.ZIP,
                    kind = "MAIN"
                }
            };
        }
    }

This is how I will use this code

    public static class Mapper
    {
        public static Request FromDecisionRequestToZRequest(DecisionRequest request)
        {
            var applicationDetails = request.ToData();

            var address = request.ToAddresses();

            var mappedRequest = new Request
            {
                UserName = request.UserName,
                RequestDateTime = Convert.ToDateTime(request.RequestDateTime),
                CompanyRegistrationID = request.CompanyRegistrationID,
                Addresses = new Addresses {Address = address},
                Phone1 = new Phone1 {type = "1", Value = request.Phone1},
                Phone2 = new Phone2 {type = "2", Value = request.Phone2},
                Phone3 = new Phone3 {type = "3", Value = request.Phone3},
                Email = request.Email,
                Amount = new Amount {Value = request.Amount},
                ApplicationDetails = new ApplicationDetails {Data = applicationDetails}
            };

            return mappedRequest;
        }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *