简体   繁体   中英

Can I use AutoMapper to map between two fields which are immutable?

I have the following two classes (many properties elided for brevity).

Service Layer POCO:

public class TicketFlag
{
    public ContactKey ContactKey;
}

LINQ to SQL generated POCO:

public class TicketFlag
{
    public string ContactKey;    
}

When trying to use AutoMapper to map between these two on service calls -> database save, I'm getting the following exception:

Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
 ---> System.ArgumentException: Type 'ContactKey' does not have a default constructor

ContactKey does not have a default constructor on purpose. Basically, it takes a string and a list of objects and can serialize/deserialize itself.

I have tried creating a mapping function (and it's inverse) like so:

Mapper.CreateMap<string, ContactKey>().ConvertUsing(s => ContactKeySerializer.Serialize(s));

But I'm still getting complaints because ContactKey doesn't have a default constructor.

Is there a way to get AutoMapper to not use the default constructor to do it's property mapping? Really, just mapping properties on the ContactKey isn't sufficient - I need to have it call the constructor, or get spit out from my ContactKeySerializer class.

First, you should probably be using properties for these things, not fields. However, I doubt that's part of your problem.

Instead of trying to create a map from string to ContactKey , you could try to make this part of the map from one TicketFlag to the other:

Mapper.CreateMap<LINQtoSQL.TicketFlag, Service.Layer.TicketFlag>()
 .ForMember(dest => dest.ContactKey,
 mem => mem.ResolveUsing(src => ContactKeySerializer.Serialize(src.ContactKey)));

I think that would prevent the error you're getting.

AutoMapper is complaining that you don't have a default constructor because AutoMapper needs to create an empty instance of the target class before it can map values to it. It can't call your ContractKey's parameterized constructor - how would it?

In this case it might seem simple, if the constructor looks like this:

public ContracktKey(string keyValue){}

But what if it had two parameters?

public ContracktKey(string keyValue, string otherValue){}

How would it know where to put the value? What if you only provided one string?

I think it would be best to follow others' advice and map the two TicketFlag objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM