2011-04-14 6 views
17

ile değer çözümleyiciyi global olarak uygula AutoMapper'ın bizim için tüm modellerimizde bulunan tüm DateTime özelliklerini yerelleştirmemize çalışıyorum. Sistemimizde her yerde UTC kullanıyoruz ve veritabanındaki her şeyi UTC'de saklıyoruz, ancak bunu otomatik olarak bir kullanıcının görüntüleme için saat dilimine dönüştürmek istiyoruz.AutoMapper

Tüm seçeneklere baktıktan sonra, bir ValueResolver kullanmaya karar verdim.

public class LocalizedDateTimeFormatter : ValueResolver<DateTime, DateTime> 
{ 
    protected override DateTime ResolveCore(DateTime source) 
    { 
     // get company 

     return company.TimeZone.ConvertFromUtc(source); 
    } 
} 

ben şöyle eşleme kuruyorum: İşte Resolver özü hepsi gayet iyi çalışıyor

Mapper.CreateMap<Entity, Model>() 
    .ForMember(dest => dest.Foo, opt => opt.ResolveUsing<LocalizedDateTimeFormatter>() 
              .FromMember(src => src.Foo)); 

Bu, ve onunla mutluyum. Ancak, ideal olarak, bu çözümleyiciyi varsayılan olarak kullanmak için bir görünüm modelindeki tüm DateTime özelliklerinin bir sözleşmesini isteriz. Görünüm modeli özelliklerinin üzerine yansıtma, DateTime öğelerini seçme ve özellik dize adlarını kullanan ForMember ve FromMember aşırı yüklenmelerini kullanma yoluna başladım, ama çirkin görünüyordu. Artı yinelenen AutoMapper'ın yuvalanmış özellik adı bina mantığı oldukça hızlı bir şekilde bozulacaktı.

Soru: AutoMapper'a bunun gibi bir ValueResolver'ı global olarak kullanmanın kolay bir yolu var mı? "Bir kaynaktaki bir DateTime özelliğini bir hedefte bir DateTime özelliği ile eşleştirdiğinizde, bu çözümleyiciyi kullanın" demek için?

AutoMapper'ın testlerini inceledim ve işe yarayan hiçbir şey görmedim.

Teşekkürler!

+0

Bu harika bir soru ve ortak bir gereklilik olacağım. Jimmy'nin cevabı gereği uygulamak için hiç şansım olmadı. Çalışan bir örneği takip eden var mı? –

cevap

14

Evet, ancak MapperRegistry öğesinin sıralamasında küçük bir değişiklik oldu. Birincisi, DateTime DateTime bir tür dönüştürücü oluşturmak: Bu TypeConverter devralır dışında

Mapper.CreateMap<DateTime, DateTime>().ConvertUsing<CompanyTimeConverter>(); 

Sizin CompanyTimeConverter kodu, hemen hemen yaşadığınız değer Resolverde benziyor.

Ardından, MapperRegistry sırasını (bu ileriye değiştirmek için gidiyorum, daha mantıklı) değiştirmek zorunda: Başlangıçta

MapperRegistry.AllMappers =() => new IObjectMapper[] { 
    new DataReaderMapper(), 
    new TypeMapMapper(TypeMapObjectMapperRegistry.AllMappers()), 
    new StringMapper(), 
    new FlagsEnumMapper(), 
    new EnumMapper(), 
    new ArrayMapper(), 
    new EnumerableToDictionaryMapper(), 
    new DictionaryMapper(), 
    new ListSourceMapper(), 
    new CollectionMapper(), 
    new EnumerableMapper(), 
    new TypeConverterMapper(), 
    new AssignableMapper(), 
    new NullableMapper() 
}; 

, "Atanabilir" mapper önce gelen " TypeConverter "mapper, böylece iki tip birbirlerine atanabilirse, bunu yapardı.

+1

Harika, teşekkürler Jimmy! Aslında çalışmak için MapperRegistry'in sırasını değiştirmem gerekli değildi. AutoMapper 1.1.0.188 çalıştırıyorum. –

+0

Bir profil düzeyinde bunu yapmak için bir yolu var mı? MapperRegistry'de değişikliklerin izole edileceğini sanmıyorum – chester89

+1

Gerek AutoMapper'i hem modelden modele, hem de görünüm modelinden öğeye (bir varlıkları düzenlerken yaptığı gibi) eşlemek için ne yapıyorsunuz? AutoMapper'a sadece bir yönde haritalama ya da ConvertFromUtc'i bir yönde ve diğerinde ConvertToUtc'i kullanma konusunda nasıl söyleyebilirsin? – Farinha