nabeelfarid
nabeelfarid

Reputation: 4224

Issue with ignoring base class property in child classes mappings using Automapper

I have a scenario where I would like to ignore some properties of classes defined in base class.

I have an initial mapping like this

   Mapper.CreateMap<Node, NodeDto>()
                .Include<Place, PlaceDto>()
                .Include<Asset, AssetDto>();

Then I customised it more like this to ignore one of the properties defined in base class NodeDto

 Mapper.CreateMap<Node, NodeDto>()
                .ForMember(dest => dest.ChildNodes, opt => opt.Ignore());

However when I try to map, Place to PlaceDto or Asset to AssetDto, the ChildNodes property does not get ignored. So I ended up doing soething like this

  Mapper.CreateMap<Node, NodeDto>()
                .ForMember(dest => dest.ChildNodes, opt => opt.Ignore());
            Mapper.CreateMap<Place, PlaceDto>()
                .ForMember(dest => dest.ChildNodes, opt => opt.Ignore());
            Mapper.CreateMap<Asset, AssetDto>()
                .ForMember(dest => dest.ChildNodes, opt => opt.Ignore());

Since I have lots of child classes for NodeDto, the above process is cumbersome, and I would like to know if there is a better approach?

Thanks Nabeel

Upvotes: 5

Views: 2065

Answers (3)

zidane
zidane

Reputation: 632

There is a better way. For our project we created mappings.xml file with following structure.

<mappings>
  <mapping name="EntityOne">
    <configuration name="Flat">
      <ignore name="ChildCollectionOne"/>
      <ignore name="ChildCollectionTwo"/>
      <ignore name="ChildCollectionThree"/>
    </configuration>
    <configuration name="Full">
      <include name="ChildCollectionOne" configuration="Flat" type="One"/>
      <include name="ChildCollectionTwo" configuration="Flat" type="Two"/>
      <include name="ChildCollectionThree" configuration="Flat" type="Three"/>
    </configuration>
  </mapping>
</mappings>

Special class AutoMapperUtilis is used for parsing data form xml and configuring Automapper according to given rules.

Call is:

AutoMapperUtil.Init(typeof(EntityOne),typeof(EntityOneDto), AutoMapperUtilLoadType.Flat);

After that all required mappings are automatically loaded, and specified ChildCollections are ignored.

With this mappings descriptions we can choose between Flat or Full configuration depending of our Use Case. We are using AutoMapper for mapping between nHibernate entities and Dto`s that are used with Ria Services, and we are very happy with this solution.

Upvotes: 2

Matt B
Matt B

Reputation: 8653

It gets even more cumbersome if you then decide that you want to ignore not just 1, but 2, 3 or maybe even more properties from the base class. It might not help you much in this case and I'm sure 9 months on you've probably found a solution already, but for the benefit of anyone else stumbling across this question an extension method could reduce some of the complexity.

    public static class MappingExtensions
    {
        public static IMappingExpression<Node, NodeDto> MapNodeBase<Node, NodeDto>(
            this IMappingExpression<Node, NodeDto> mappingExpression)
        {
            // Add your additional automapper configuration here
            return mappingExpression.ForMember(
                dest => dest.ChildNodes, 
                opt => opt.Ignore()
            );
        }
    }

Which you would then call thus:

Mapper.CreateMap<Node, NodeDto>()
            .MapNodeBase()
            .Include<Place, PlaceDto>()
            .Include<Asset, AssetDto>();

Upvotes: 5

Omu
Omu

Reputation: 71288

sorry but, no, there isn't any other way, that's how automapper works

Upvotes: 2

Related Questions