question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ConstructUsing is not working as expected

See original GitHub issue

I expect that the Destination will be constructed using the ConstructUsing and then the concrete mappings will happen. I am not seeing my values mapped on the concrete mappings. Is there something wrong with the mappings?

If I call Mapper.Map and let automapper do the construction. The mappings are not called.

//this does not work
Mapper.AddProfile(new MappingProfile());
var task = new TaskCustomProperty{Name = "test", Choices  = new [] {"Yes", "No"}};
var dto = Mapper.Map<TaskCustomPropertyDTO>(task);

    //this works
TaskCustomPropertyDTO otherDto;

switch (task.Type) {
    case "string":
        otherDto = new TaskCustomPropertyString (); 
        break;
    case "choices":
        otherDto = new TaskCustomPropertyChoices ();
        break;
    default:
        throw new ArgumentOutOfRangeException ();
}
dto = Mapper.Map(task, otherDto);

Profile

CreateMap<TaskCustomProperty,TaskCustomPropertyDTO> ()
            .ConstructUsing (t => {
                switch (t.Type) {
                    case "string":
                        return new TaskCustomPropertyString ();
                    case "numeric":
                        return new TaskCustomPropertyNumeric ();
                    case "choices":
                        return new TaskCustomPropertyChoices ();
                    default:
                        throw new ArgumentOutOfRangeException ();
                }
            })
            .ForMember (property => property.Task, expression => expression.Ignore ())
            .Include<TaskCustomProperty, TaskCustomPropertyChoices> ()
            .Include<TaskCustomProperty, TaskCustomPropertyNumeric> ()
            .Include<TaskCustomProperty, TaskCustomPropertyString> ();

        CreateMap<TaskCustomProperty, TaskCustomPropertyChoices> ()
            .ForMember (property => property.Values, expression => expression.MapFrom (property => property.Choices != null ? string.Join ("|", property.Choices) : null))
            .ForMember (property => property.StringValue, expression => expression.Ignore ());

        CreateMap<TaskCustomProperty, TaskCustomPropertyNumeric> ()
            .ForMember (property => property.Task, expression => expression.Ignore ())
            .ForMember (property => property.NumericValue, expression => expression.Ignore ());

        CreateMap<TaskCustomProperty, TaskCustomPropertyString> ()
            .ForMember (property => property.Task, expression => expression.Ignore ())
            .ForMember (property => property.StringValue, expression => expression.Ignore ());

Classes

public class TaskCustomProperty {
    public Guid? Id { get; set; }
    public Guid TaskId { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
    public bool IsRequired { get; set; }
    public object Value { get; set; }
    public string [] Choices { get; set; }
}


public abstract class TaskCustomPropertyDTO {
    public Guid Id { get; set; }
    public Guid TaskId { get; set; }
    public string Name { get; set; }
    public bool IsRequired { get; set; }
    public abstract object Value { get; set; }
    public abstract bool IsEmpty ();
}

public class TaskCustomPropertyString : TaskCustomPropertyDTO {
    public string StringValue { get; set; }
    public override object Value {
        get {
            return StringValue;
        }
        set {
            StringValue = (string)value;
        }
    }

    public override bool IsEmpty () {
        return string.IsNullOrWhiteSpace (StringValue);
    }
}

public class TaskCustomPropertyChoices : TaskCustomPropertyString {
    public string Values { get; set; }
    public string [] GetValues () {
        if (string.IsNullOrEmpty (Values)) {
            return new string [0];
        }

        return Values.Split ('|');
    }
}

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jbogardcommented, Sep 4, 2013

No, that’s not really how ConstructUsing works. ConstructUsing says - “Given you want to map Type A to type B, construct type B using this constructor”. Mapping inheritance is a bit different, it’s more like "Given Type A map to type B, and Type A’ : A and Type B’ : B, duplicate member configuration from A -> B to A’ -> B’. I can’t copy down ConstructUsing because I really need a function that creates A’, not A or any derived type of A.

Suppose you had B2 : B and B1 : B. I don’t want CreateMap<A, B>().ConstructUsing(a => new B2()). That wouldn’t work for B1. You might have set up your ConstructUsing to work like that, but I can’t assume it, so you have to do ConstructUsing per derived type (which I think is easier to manage as it’s more explicit, instead of a bunch of if/thens to create the right derived type in the base case)

On Wed, Sep 4, 2013 at 9:31 AM, youngcm2 notifications@github.com wrote:

So that would lead me to believe that I am using ConstructUsing wrong. I assumed that I would be able to map an object to the base base type using the the ConstructUsing which would return the concrete type. After the concrete type is returned, it would used the derived maps.

— Reply to this email directly or view it on GitHubhttps://github.com/AutoMapper/AutoMapper/issues/376#issuecomment-23793727 .

0reactions
lock[bot]commented, May 8, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Automapper ConstructUsing not working as expected
I am using automapper in my asp.net core project and it's my first time with that library. The data flow is as follows: ......
Read more >
Evaluating Program Effectiveness: Validity and ... - Google Books Result
... and the connection to “correlation” should not be interpreted as referring ... groups that would be expected to vary on the construct...
Read more >
Creative Technologies for Multidisciplinary Applications
architect working across sculpture, furniture design and architecture (including ... single piece outcome not possible to construct using a mould or ...
Read more >
Disruptive Technology: Concepts, Methodologies, Tools, and ...
However, in order to realize her ideas, van Herpen needed to work closely with 3D ... single piece outcome not possible to construct...
Read more >
International Review of Cytology: A Survey of Cell Biology
The frequency of recombination is not equally distributed across the genome. ... at the repair construct using target locus sequences are the predicted, ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found