1
同僚、 私たちのプロジェクトでは、AutoMapperを使用してモデルをマップしています。汎用クラスの簡略化は可能ですか?
我々はモデルがあります:私たちは、次のようなものを定義することがビューモデルにモデルをマッピング
public class PersonView
{
public string Name { get; set; }
public string Location { get; set;}
}
:
public class Location
{
public string Address { get; set; }
}
public class Person
{
public string Name { get; set;}
public Collection<Location> Locations { get; set; }
}
また、我々はビューモデルを持っている
Mapper.CreateMap<Person, PersonView>(d=>d.Name, opt=>opt.FromMap(s=>s.Name);
Mapper.CreateMap<Person, PersonView>(d=>d.Address, opt=>opt.FromMap(s=>s.Locations.First().Address);
を
BUT:Locationsに要素が含まれていないか、nullの場合、例外が発生します。
反対側から、我々は値を取得する関数を定義することができます。これは読みにくい表現
Mapper.CreateMap<Person, PersonView>(d=>d.Address, opt=>opt.FromMap(s=>
{
var item = s.Locations.FirstOrDefault();
if(item == null)
{
return string.Empty;
}
return item.Address;
});
。そして、マッピングを単純化するためにIValueResolverを作成してみます。
Mapper.CreateMap<Person, PersonView>(d=>d.Address, opt=>opt.ResolveUsing(
new CollectionItemResolver<Person, Location, string>(p=>p.Locations, i=>i.Address)));
は、一般的なリゾルバを簡素化することが可能です:
public class CollectionItemResolver<TSource, TSourceItem, TResult>
where TSource : class
where TSourceItem : class
{
private readonly Func<TSource, IEnumerable<TSourceItem>> _sourceSelector;
private readonly Func<TSourceItem, TResult> _selector;
private readonly TResult _defaultValue;
public CollectionItemResolver(Func<TSource, IEnumerable<TSourceItem>> source, Func<TSourceItem, TResult> selector)
: this(source, selector, default(TResult))
{
}
public CollectionItemResolver(Func<TSource, IEnumerable<TSourceItem>> source, Func<TSourceItem, TResult> selector, TResult defaultValue)
{
_sourceSelector = source;
_selector = selector;
_defaultValue = defaultValue;
}
public TResult Resolve(TSource source)
{
var items = _sourceSelector(source);
if (items == null)
{
return _defaultValue;
}
var item = items.FirstOrDefault();
if (item == null)
{
return _defaultValue;
}
var value = _selector(item);
return value;
}
}
そして、このようなものを使うのか? たとえば、ネストされたアイテムのタイプを定義しないでください。
new CollectionItemResolver<Person, string>(p=>p.Locations, i=>i.Address)));
おかげで、この程度
'Gents'?あなたの質問を読んでいる女性はどうですか? –
@DarinDimitrov - ストレートな顔でそれを言って+1。 – Steve
私は式に戻ります。それは私のために読むのがずっと簡単でした。 – Enigmativity