Jordi
Jordi

Reputation: 23207

AutoMapper - map a property without a `set;` implementation

Is there some way to map a IList<> property which does not have a set; method?

Source Class:

public class SourceClass
{
    private IList<string> strings;

    public IList<string> Strings { get { return this.strings; } }

    public SourceClass() { this.strings = new List<string>() { "s1", "s2", "s3" };
    //...
}

Destionation Class:

public class DestinationClass
{
    private IList<string> strings;

    public IList<string> Strings { get { return this.strings; } }

    public DestinationClass() { this.strings = new List<string>();
    //...
}

As you can see, neither class has set; implemented. The result is that when I perform AutoMapper.Mapper.Map<SourceClass, DestinationClass>(source, destination), the Strings property is empty.

The obvious solution is to provide a set; implementation is DestinationClass, however, I would like to know how to provide a custom configuration in order to deal with these troubles.

Currently, my configuration is:

public class XProfile : AutoMapper.Profile
{
    protected override void Configure()
    {
        AutoMapper.Mapper.CreateMap<SourceClass, DestinationClass>();
    }
}

Upvotes: 3

Views: 1077

Answers (3)

Joel R Michaliszen
Joel R Michaliszen

Reputation: 4222

If you're working with immutable object, i suggest to you pass it as parameter to destination class, and it will be like this:

AutoMapper.Mapper.CreateMap<SourceClass, DestinationClass>()
  .ConstructUsing(s => new DestinationClass(s.Strings))

And the DestinationClass:

public class DestinationClass
{
    private IList<string> strings;

    public IList<string> Strings { get { return this.strings; } }

    public DestinationClass(List<string> strings = null)
    { 
        this.strings = strings ?? new List<string>();
    }
   //...
}

Upvotes: 1

Frank Bryce
Frank Bryce

Reputation: 8446

You could create a constructor like this.

public class DestinationClass
{
    private IList<string> strings;

    public IList<string> Strings { get { return this.strings; } }

    public DestinationClass() : this(new List<string>()) { }

    public DestinationClass(IList<string> strs) {
        strings = strs.ToList(); // clone it
    }
    //...
}

Then you can make the mapping with the ConstructUsing method, to tell AutoMapper to call the constructor that you created.

public class XProfile : AutoMapper.Profile
{
    protected override void Configure()
    {
        AutoMapper.Mapper.CreateMap<SourceClass, DestinationClass>()
            .ConstructUsing(x => new DestinationClass(x.Strings));
    }
}

Upvotes: 2

Martino Bordin
Martino Bordin

Reputation: 1471

You can configure AutoMapper to recognize non-public members. Check out the documentation

Upvotes: 2

Related Questions