2013-04-20 7 views
22

मेरा प्रश्न यह है कि, मैं सबसे ऑब्जेक्ट को सबसे अधिक रखरखाव तरीके से किसी ऑब्जेक्ट को मैप कर सकता हूं। मैं जिस डीटीओ ऑब्जेक्ट को प्राप्त कर रहा हूं उसे बदल नहीं सकता है, इसलिए इसे अधिक सामान्यीकृत करने के लिए सेटअप किया गया है, इसलिए मुझे इसे अपने ऑब्जेक्ट के कार्यान्वयन के लिए मानचित्र बनाने का एक तरीका बनाना होगा।किसी ऑब्जेक्ट को किसी अन्य ऑब्जेक्ट पर मैप करने के लिए सर्वोत्तम अभ्यास

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; } 
} 

मुझे लगता है कि यह बहुत अच्छा होगा अगर मैं था कि मॉडल में ले जाएगा नक्शाकार वर्ग के कुछ प्रकार की वस्तुओं PropertyInfo है, प्रकार मैं:

यहाँ मैं क्या होने की जरूरत को दिखाने के लिए उदाहरण कोड है में कनवर्ट करना चाहते हैं, और "itemname" मैं बाहर खींचना चाहता हूं। क्या इस क्लीनर को बनाने के लिए किसी को कोई सुझाव है?

धन्यवाद!

+0

मानचित्रण के बारे में सुनिश्चित नहीं हैं, लेकिन आप निश्चित रूप से जेनरिक पर गौर करना चाहिए और सामान्य संग्रह का उपयोग: http://csharp-station.com/Tutorial/CSharp/Lesson20 – christiandev

+0

मैं जो एक लेता मॉडल की एक costructor सुझाव है डीटीओ और मानचित्र/रूपांतरण/तदनुसार हार्डकोड किए गए चेक के रूप में जब आप डीटीओ में कुछ बदलते हैं तो संकलन त्रुटियां प्राप्त होती हैं। प्रतिबिंब और इसलिए तारों से निपटने से आप रखरखाव को बढ़ाने में मदद नहीं करते हैं। – wonko79

उत्तर

4

यह एक संभव सामान्य प्रतिबिंब के एक बिट का उपयोग कार्यान्वयन है (छद्म कोड, अब वी.एस. नहीं है):

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; 
     } 
    } 

उपयोग:

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

यह धीमी गति से हो जाएगा जब आप मैपर उदाहरण बनाएं लेकिन बाद में बहुत तेज।

+0

दुर्भाग्यवश, यहां की आवश्यकता उतनी ही आगे नहीं है जितनी मैं चाहूंगा और आइटम नाम मॉडल पर गुणों के नामों से संबंधित नहीं है, इसलिए मुझे नहीं लगता कि यह काम करेगा। – Alex

15

मैं AutoMapper, एक ओपन सोर्स और फ्री मैपिंग लाइब्रेरी का चयन करता हूं जो सम्मेलनों के आधार पर एक प्रकार को दूसरे प्रकार में मैप करने की अनुमति देता है (यानी समान नाम वाले मानचित्र सार्वजनिक गुण और समान/व्युत्पन्न/परिवर्तनीय प्रकार, कई अन्य के साथ smart ones)। उपयोग करने के लिए बहुत आसान है, तो आप कुछ इस तरह प्राप्त करने देगा:

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

अपनी विशिष्ट आवश्यकताओं के बारे में सुनिश्चित नहीं हैं, लेकिन AutoMapper भी custom value resolvers, जो आप अपने विशेष नक्शाकार की एक जेनरिक कार्यान्वयन लेखन की मदद करनी चाहिए समर्थन करता है।

+5

हमने पहले ऑटोमैपर का उपयोग किया है, लेकिन इसके धीमे प्रदर्शन के कारण हमने इसे समझ लिया है। – Alex

+2

सहमत हुए। एक ही चीज हो गई, ऑटोमैपर छोड़ने के बाद और पहले कस्टम में एक कस्टम लिखने के साथ समाप्त हो गया। ऑटोमैपर का बहुत धीमा प्रदर्शन – ZolaKt

+1

हमारे पास प्रदर्शन के साथ बहुत अधिक समस्या थी, इसे फिर से उपयोग नहीं किया जाएगा। –

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

एक त्वरित और गंदे तरीके !! – DKM

संबंधित मुद्दे