2013-04-20 24 views
22

Sorum şu ki, bir nesneyi diğerine en iyi şekilde ulaştırmak için en iyi yol hangisidir. Aldığımız Dto nesnesinin daha normalize edilmeye hazırlanma şeklini değiştiremem, bu yüzden nesnelerimizin uygulanışına eşlemek için bir yol yaratmalıyım. , Tip I ı modelde alacağını mapper sınıfının bir çeşit PropertyInfo nesneleri olsaydı neyi iyi olurdu benceBir nesneyi diğerine eşleme için en iyi yöntemler

class Program 
{ 
    static void Main(string[] args) 
    { 
     var dto = new Dto(); 

     dto.Items = new object[] { 1.00m, true, "Three" }; 
     dto.ItemsNames = new[] { "One", "Two", "Three" };    

     var model = GetModel(dto); 

     Console.WriteLine("One: {0}", model.One); 
     Console.WriteLine("Two: {0}", model.Two); 
     Console.WriteLine("Three: {0}", model.Three); 
     Console.ReadLine(); 
    } 

    private static Model GetModel(Dto dto) 
    { 
     var result = new Model(); 

     result.One = Convert.ToDecimal(dto.Items[Array.IndexOf(dto.ItemsNames, "One")]); 
     result.Two = Convert.ToBoolean(dto.Items[Array.IndexOf(dto.ItemsNames, "Two")]); 
     result.Three = dto.Items[Array.IndexOf(dto.ItemsNames, "Three")].ToString(); 

     return result; 
    } 
} 

class Dto 
{ 
    public object[] Items { get; set; } 
    public string[] ItemsNames { get; set; } 
} 

class Model 
{ 
    public decimal One { get; set; } 
    public bool Two { get; set; } 
    public string Three { get; set; } 
} 

: Burada

Ben gerçekleşmesi gereken göstermek için örnek kod dönüştürmek istiyorum ve "itemname" çıkarmak istiyorum. Bu temizleyici yapmak için herhangi bir önerisi var mı?

Teşekkürler!

+0

haritalama konusunda emin, ama kesinlikle jenerik bakmak gerekir ve jenerik koleksiyonları kullanmama: http://csharp-station.com/Tutorial/CSharp/Lesson20 – christiandev

+0

Bir sürer Modelinin bir costructor öneririm Dto'da bir şey değiştiğinde derleme hataları alırken, Dto ve haritalar/dönüştürür/uygun şekilde kodlanmış olarak denetler. Yansıma ve dolayısıyla dizelerle uğraşmak, sürekliliği arttırmanıza yardımcı olmaz. – wonko79

cevap

4

Bu yansıma biraz kullanılarak muhtemel bir genel uygulamasıdır (sözde kod, şimdi VS yok):

public class DtoMapper<DtoType> 
{ 
    Dictionary<string,PropertyInfo> properties; 

    public DtoMapper() 
    { 
     // Cache property infos 
     var t = typeof(DtoType); 
     properties = t.GetProperties().ToDictionary(p => p.Name, p => p); 
    } 

    public DtoType Map(Dto dto) 
    { 
     var instance = Activator.CreateInstance(typeOf(DtoType)); 

     foreach(var p in properties) 
     { 
      p.SetProperty(
       instance, 
       Convert.Type(
        p.PropertyType, 
        dto.Items[Array.IndexOf(dto.ItemsNames, p.Name)]); 

      return instance; 
     } 
    } 

Kullanımı:

var mapper = new DtoMapper<Model>(); 
var modelInstance = mapper.Map(dto); 

Bu yavaş olacaktır sizi mapper örneğini oluşturmak ancak daha sonra daha hızlı.

+0

Maalesef, buradaki gereksinim, istediğim kadar doğru değil ve Adlar gerekli değil, modeldeki özelliklerin isimleriyle ilişkilidir, dolayısıyla bunun işe yaramayacağını düşünmüyorum. – Alex

15

0-, açık kaynak kodlu ve ücretsiz bir eşleme kütüphanesi tercih ediyorum. smart ones). özel gereksinimleri hakkında

Model model = Mapper.Map<Model>(dto); 

Emin değilim, ama AutoMapper da belirli Eşleyicisi, tek ve genel uygulama yazma yardımcı olacaktır custom value resolvers, destekler: Kullanımı çok kolay, böyle bir şey başarmak izin verir.

+5

Daha önce otomatik biçimlendirici kullandık, ancak yavaş performans nedeniyle duyumuzu düşürdük. – Alex

+2

Anlaşıldı. Aynı şey bitti, daha fazla iş otomatik dökücü bırakarak sonra özel bir ilk yazma bitti. Automapper çok yavaş performansa sahiptir – ZolaKt

+1

Performansla aynı sorunu yaşadık, tekrar kullanmayacağız. –

1
/// <summary> 
/// map properties 
/// </summary> 
/// <param name="sourceObj"></param> 
/// <param name="targetObj"></param> 
private void MapProp(object sourceObj, object targetObj) 
{ 
    Type T1 = sourceObj.GetType(); 
    Type T2 = targetObj.GetType(); 

    PropertyInfo[] sourceProprties = T1.GetProperties(BindingFlags.Instance | BindingFlags.Public); 
    PropertyInfo[] targetProprties = T2.GetProperties(BindingFlags.Instance | BindingFlags.Public); 

    foreach (var sourceProp in sourceProprties) 
    { 
     object osourceVal = sourceProp.GetValue(sourceObj, null); 
     int entIndex = Array.IndexOf(targetProprties, sourceProp); 
     if (entIndex >= 0) 
     { 
      var targetProp = targetProprties[entIndex]; 
      targetProp.SetValue(targetObj, osourceVal); 
     } 
    } 
} 
+0

Hızlı ve kirli bir şekilde! – DKM

İlgili konular