2016-10-12 14 views
6

Stworzyłem ListTypeConverter:Jak używać AutoMappera do odwzorowania obiektu z wieloma ogólnymi listami na inny obiekt z odpowiednimi nie ogólnymi listami?

type ListTypeConverter<'source, 'destination>() = 
    interface ITypeConverter<'source list, Proxies.List> with 
     member this.Convert(source, destination, context) = 
      let proxyList = new Proxies.List() 
      source 
      |> List.map(fun item -> _mapper.Map<'source, 'destination>(item)) 
      |> List.iter(fun item -> proxyList.addEnd(item) |> ignore) 
      proxyList 

i użytkowania: ForMemberFs by Ian Griffiths

this.CreateMap<SourceItemType list, Proxies.List>().ConvertUsing<ListTypeConverter<SourceItemType, DestItemType>>() 

this.CreateMap<SourceType, DestType>(). 
    ForMemberFs((fun d -> d.MyNonGenericList), (fun opts -> opts.MapFrom(fun s -> s.MyGenericList))). 

Działa to dobrze, jeśli mam tylko jedną właściwość na moim pierwotnym mapie, który mapuje z 'a list -> Proxy.List. Ale w momencie, gdy wprowadzam drugie mapowanie z 'b -> Proxy.List, otrzymuję wyjątek InvalidCastException.

Przedstawiamy drugą mapowanie powoduje wyjątek:

this.CreateMap<SourceItemType list, Proxies.List>().ConvertUsing<ListTypeConverter<SourceItemType, DestItemType>>() 
this.CreateMap<SourceItemType2 list, Proxies.List>().ConvertUsing<ListTypeConverter<SourceItemType2, DestItemType2>>() 

this.CreateMap<SourceType, DestType>(). 
    ForMemberFs((fun d -> d.MyNonGenericList), (fun opts -> opts.MapFrom(fun s -> s.MyGenericList))). 
    ForMemberFs((fun d -> d.MyNonGenericList2), (fun opts -> opts.MapFrom(fun s -> s.MyGenericList2))). 

Wyjątek:

Unable to cast object of type 'obj' to type 'DestItemType' 

Odpowiedz

1

Tak, mój problem jest nieco głębszy niż tylko F # i AutoMapper. Typ Proxies.List jest faktycznie pobierany za pośrednictwem TypeProvider dla Microsoft Dynamics AX, który napisaliśmy w domu. Chciałem wykluczyć tę zmienną z równania, więc napisałem prosty skrypt przy użyciu System.Collections.Generic.List<'t> -> System.Collections.ArrayList (który jest nietypowy) i udało mi się pomyślnie odrzucić elementy z mojego ArrayList z powrotem do ich prawidłowego typu "docelowego".

Choć jestem tu, wpadliśmy niektórych całkiem fajne F # pomocników dla AutoMapper:

type OptionExpressions = 
    static member MapFrom<'source, 'destination, 'sourceMember, 'destinationMember> (e: 'source -> 'sourceMember) = 
     System.Action<IMemberConfigurationExpression<'source, 'destination, 'destinationMember>> (fun (opts: IMemberConfigurationExpression<'source, 'destination, 'destinationMember>) -> opts.MapFrom(e)) 
    static member UseValue<'source, 'destination, 'value> (e: 'value) = 
     System.Action<IMemberConfigurationExpression<'source, 'destination, 'value>> (fun (opts: IMemberConfigurationExpression<'source, 'destination, 'value>) -> opts.UseValue(e)) 
    static member Ignore<'source, 'destination, 'destinationMember>() = 
     System.Action<IMemberConfigurationExpression<'source, 'destination, 'destinationMember>> (fun (opts: IMemberConfigurationExpression<'source, 'destination, 'destinationMember>) -> opts.Ignore()) 

Zastosowanie:

// Shortened local helpers 
let mapFrom = OptionExpressions.MapFrom 
let ignoreMap = OptionExpressions.Ignore 
let useValue = OptionExpressions.UseValue 

this.CreateMap<Source, Destination>() 
    .ForMemberFs((fun d -> d.DestMember1), mapFrom (fun s -> s.SourceMember1)) 
    .ForMemberFs((fun d -> d.DestMember2), useValue (MyValue)) 
    .ForMemberFs((fun d -> d.DestMember3), ignoreMap()) 
Powiązane problemy