Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapping to existing object of same type returns the source instead of modifying the destination #656

Closed
thomaslevesque opened this issue Dec 30, 2014 · 8 comments

Comments

@thomaslevesque
Copy link
Contributor

EDIT: actually, the problem is not related to CreateMissingTypeMaps; see comments below

Just noticed a bug where CreateMissingTypeMaps = true has no effect when you pass an existing destination object to Mapper.Map. Here's a quick repro using LinqPad:

void Main()
{
    var foo1 = new Foo { X = 42, Y = 123, Bar = new Bar { Z = 999 } };
    var foo2 = new Foo();
    var foo3 = Mapper.Map<Foo, Foo>(foo1, foo2, o => o.CreateMissingTypeMaps = true);
    Console.WriteLine ("foo3 == foo1: {0}", foo3 == foo1); // true; expected false
    Console.WriteLine ("foo3 == foo2: {0}", foo3 == foo2); // false; expected true
    Console.WriteLine (foo2.ToString()); // Foo(X = 0, Y = 0, Bar = ); expected Foo(X = 42, Y = 123, Bar = Bar(Z = 999))
}

class Foo
{
    public int X { get; set; }
    public int Y { get; set; }
    public Bar Bar { get; set; }

    public override string ToString() { return string.Format("Foo(X = {0}, Y = {1}, Bar = {2})", X, Y, Bar); }
}

class Bar
{
    public int Z { get; set; }
    public override string ToString() { return string.Format("Bar(Z = {0})", Z); }
}

Mapping to a new instance with Mapper.Map<Foo>(foo1) works as expected.

Also, if I explicitly create the map for Foo -> Foo, then the map for Bar -> Bar is correctly created, so it seems the problem only affects the root of the mapping.

Another issue (perhaps unrelated) that bothers me is that the mapping fails silently... the destination object is left untouched, and Mapper.Map just returns the source object (it returns the destination object when the mapping succeeds). Shouldn't it throw an exception?

@thomaslevesque
Copy link
Contributor Author

While investigating the issue, I noticed it occurs only if the source and destination type are the same. If they're different, it works as expected.

@thomaslevesque
Copy link
Contributor Author

OK, I think I know what's going on; if there is no map defined for Foo -> Foo, AutoMapper uses AssignableMapper, which just returns the source value. But in the case of a mapping with destination, it doesn't make sense: I explicitly want to copy the source object's properties to the destination object...

@thomaslevesque thomaslevesque changed the title CreateMissingTypeMaps is ignored when mapping to an existing object Mapping to existing object of same type returns the source instead of modifying the destination Dec 30, 2014
thomaslevesque added a commit to thomaslevesque/AutoMapper that referenced this issue Dec 30, 2014
thomaslevesque added a commit to thomaslevesque/AutoMapper that referenced this issue Dec 30, 2014
@jbogard jbogard closed this as completed Apr 24, 2015
@thomaslevesque
Copy link
Contributor Author

@jbogard, can you please explain why you closed this issue? Is the current behavior by design?

@jbogard
Copy link
Member

jbogard commented Apr 24, 2015

Yep - the assignable mapper is about assigning one object to another. If you want to override that, use CreateMap to explicitly tell AutoMapper "I intend to use the mapping conventions to go from one side to the other".

@thomaslevesque
Copy link
Contributor Author

OK, thanks

@lioobayoyo
Copy link

Ok, so to use map to auto-assign same properties on destination object of type A from source type A, I can create a profile :

CreateMap<A,A>();

But imagine that I want to be able to use this on my 100 classes likewise. I'll get something like :

CreateMap<A,A>();
CreateMap<B,B>();
CreateMap<C,C>();
// ...

Is there another "state of the Automapper art" way of doing it ? For instance in the .Map(source, destination, ????) call directly ? (my goal is to prevent silent logical errors if I forget to add the dummy <X, X> profile for my 99th class X)

@lbargaoanu
Copy link
Member

It's easy to create all those default maps using reflection, Assembly.GetTypes or smth similar.

@lock
Copy link

lock bot commented May 5, 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.

@lock lock bot locked as resolved and limited conversation to collaborators May 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants