views:

167

answers:

1

I'm mapping an ApplianceViewModel to a ApplianceDTO. Each Appliance has a collection of ActionViewModels which are mapped to ActionDTO. What I'd like to do is configure the mapper to ignore ActionViewModels whose IsPersisted value is False.

My ViewModel classes ...

public interface IApplianceViewModel : INotifyPropertyChanged
{
    ObservableCollection<IActionViewModel> Actions { get; set; }
    // other properties removed for simplicity
}

public interface IActionViewModel : INotifyPropertyChanged
{
    bool IsPersisted { get; set; }
    // other properties removed for simplicity
}

My DTO classes ...

public class ApplianceDTO
{
    public IEnumerable<ActionDTO> Actions { get; set; }
    // other properties removed for simplicity
}

public class ActionDTO
{
    // properties removed for simplicity
}

I set up my mapping like this ...

Mapper.CreateMap<IApplianceViewModel, ApplianceDTO>();
Mapper.CreateMap<IActionViewModel, ActionDTO>()

var appliance = new ApplianceViewModel {
    Actions = new ObservableCollection<IActionViewModel>(
        new List<IActionViewModel> {
           new ActionViewModel { IsPersisted = true },
           new ActionViewModel { IsPersisted = false }
    }};
var applianceDTO = Mapper.Map<IApplianceViewModel, ApplianceDTO>(applianceDTO);

Currently my applianceDTO will have two items in it's Actions collection, but I'd like to set up my mapping so that the ApplianceActionViewModel with the IsPersisted property set to false isn't mapped. Can I do this?

Update

Omu's comment lead me to a solution using a ValueResolver to map the collection of Actions. I'm not really happy with this solution but its the best option available.

First I created a custom ValueResolver.

public class IsPersistedCollectionResolver : ValueResolver<IApplianceViewModel, IEnumerable<ActionDTO>>
{
    protected override IEnumerable<ActionDTO> ResolveCore(IApplianceViewModel source)
    {
        return Mapper.Map<IEnumerable<IActionViewModel>, IEnumerable<ActionDTO>>(source.Actions.Where(x => x.IsPersisted));
    }
}

Then I modified my code to use it in the mapping configuration.

Mapper.CreateMap<IApplianceViewModel, ApplianceDTO>()
    .ForMember(dest => dest.Actions, opt => opt.ResolveUsing<IsPersistedCollectionResolver>());
Mapper.CreateMap<IActionViewModel, ActionDTO>();
A: 

have you tried doing something like :

Mapper.map(objects.Where(o => o.IsPersisted == true))
Omu
This doesn't work in the scenario I gave. Your solution assumes the IsPersisted property is on the object that is being mapped, but its on a different class. In the example given in the question I'm mapping a list of ApplianceViewModel classes, which has a property of type ActionViewModel. ActionViewModel is the class with the IsPersisted type. I could certainly filter ahead of time, but the code is a lot more complex than a single LINQ Where, and I was hoping AutoMapper had a better solution.
Matt Casto
@Matt Casto you can try to write something like this inside a ValueResolver for the Collection column, I mean to use Mapper.map(with the linq condition) inside the ValueResolver which is going to be used for that property is of type IEnumerable<TheTypeWithIsPersisted>
Omu