AutoMapper बनाम ValueInjecter [बंद]


209

मैं StackOverflow पर AutoMapper सामान की तलाश कर रहा हूँ, मैं ValueInjecter के बारे में कुछ पढ़ रहा हूँ ।

क्या कोई मुझे उनके बीच के पेशेवरों और विपक्षों (प्रदर्शन, सुविधाएँ, एपीआई उपयोग, विस्तार, परीक्षण) के बारे में बता सकता है?


2
एक और जो मैंने उल्लेख किया है वह एमिटमैपर है
एड्रिएनबैंक्स

1
गोंद के बारे में क्या? गोंद .codeplex.com एक महान परियोजना के रूप में अच्छी तरह से दिखता है, लेकिन मैंने अभी तक इसकी कोशिश नहीं की है। मैं हालांकि अगले महीने के दौरान करूंगा। मैंने EmitMapper emitmapper.codeplex.com
Trygve

उन दो औजारों के बारे में बोलते हुए एक लेख देखें - devproconnections.com/development/…
जॉर्ज बिरबिलिस

जवाबों:


170

ValueInjecter के निर्माता के रूप में , मैं आपको बता सकता हूं कि मैंने ऐसा इसलिए किया क्योंकि मैं कुछ सरल और बहुत लचीला चाहता था

मुझे वास्तव में बहुत लिखना या बहुत monkey codeपसंद करना पसंद नहीं है:

Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.

ValueInjecter यह प्लगइन्स के साथ मोज़िला की तरह कुछ है , आप ValueInjections बनाते हैं और उनका उपयोग करते हैं

वहाँ चपटे, unflattening, और कुछ है कि विरासत में मिला इरादा कर रहे हैं के लिए निर्मित इंजेक्शन हैं

और यह एक प्रकार के पहलू में अधिक काम करता है , आपको सभी गुण 1-से -1 निर्दिष्ट करने की आवश्यकता नहीं है, इसके बजाय आप कुछ ऐसा करते हैं:

"आईडी" नाम से समाप्त होने वाले स्रोत से सभी अंतर गुण लें, मान को परिवर्तित करें और प्रत्येक वस्तु को स्रोत वस्तु में ईद प्रत्यय के बिना एक ही नाम के साथ सेट करें और यह टाइप एंटिटी से विरासत में मिला है, जैसे सामान

तो एक स्पष्ट अंतर, ValueInjecter का उपयोग विंडोज़ के रूप में भी चपटा और अप्रभावित करने के लिए किया जाता है, यह कितना लचीला है

(नियंत्रण और वापस बनाने के लिए ऑब्जेक्ट से मैपिंग)

स्वचालित रूप से, विंडोज़ के रूप में उपयोग करने योग्य नहीं, कोई अप्रभावी नहीं है, लेकिन इसमें संग्रह मानचित्रण जैसी अच्छी सामग्री है, इसलिए यदि आपको इसकी आवश्यकता है तो ValueInjecter के साथ आपको कुछ ऐसा करना होगा:

foos.Select(o => new Bar().InjectFrom(o));

आप अनाम और गतिशील वस्तुओं से मैप करने के लिए ValueInjecter का भी उपयोग कर सकते हैं

मतभेद:

  • स्वचालित मैपिंग प्रत्येक मैपिंग की संभावना के लिए कॉन्फ़िगरेशन बनाएँ CreateMap ()

  • किसी भी वस्तु से किसी भी वस्तु के लिए इंजेक्टर इंजेक्टर (ऐसे भी मामले हैं जब आप ऑब्जेक्ट से वैल्यूएटाइप पर इंजेक्ट करते हैं)

  • आटोमैपर ने समतल बनाया है, और केवल सरल प्रकारों के लिए या उसी प्रकार से, और इसमें अप्रभावी नहीं है

  • valueinjecter आपको इसकी आवश्यकता केवल तभी जब आप करते हैं target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection> और आप से चाहते हैं Foo.Bar.Name of type Stringके लिए FooBarName of type Class1आप FlatLoopValueInjection वारिस और यह निर्दिष्ट

  • ऑटोमैप्पर डिफ़ॉल्ट रूप से एक ही नाम के साथ गुणों को मैप करता है और बाकी के लिए आपको एक-एक करके निर्दिष्ट करना होगा, और Prop1.Ignore (), Prop2.Ignore () आदि जैसे सामान करना होगा।

  • valueinjecter में एक डिफ़ॉल्ट इंजेक्शन है। InjectFrom () जो एक ही नाम और प्रकार के साथ गुण करता है; बाकी सभी चीज़ों के लिए आप अलग-अलग मैपिंग लॉजिक / रूल्स के साथ अपने कस्टम वैल्यूएन्जेन्स बनाते हैं, जैसे पहलुओं को और अधिक, जैसे टाइप फू के सभी प्रॉप्स से लेकर टाइप बार के सभी प्रॉप्स को


5
प्यार के देवता के लिए कृपया मुझे बताएं कि ValueInjector एक गहरे ग्राफ ViewModel और मैप को / से एक गहरे ग्राफ बिजनेस एंटिटी तक ले जा सकता है और वह सब कुछ कर सकता है जो बिना किसी काम के बिल्कुल समान है, और मुझे केवल यह निर्दिष्ट करने की आवश्यकता है कि व्हाट्स अलग को कैसे हैंडल किया जाए। मुझे उम्मीद है कि AutoMapper इस क्षमता को जोड़ देगा, लेकिन यह कभी भी भौतिक नहीं हुआ है और मेरे पास अपना ऑटो मैपर लिखने का समय नहीं है।
क्रिस मैरिसिक

3
@ क्रिस मैरिसिक आप इसका उपयोग कर सकते हैं, यदि आप गहरी क्लोनिंग का मतलब है, तो मैंने एक इंजेक्शन लगाया था कि थोड़े एक बार यह पुनरावृत्ति करता है, लेकिन संग्रह गुणों के लिए काम नहीं करता है valueinjecter.codeplex.com/Thread/View.aspx?ThreadId=236126 , या आप एक फ्लैट ViewModel कर सकते हैं और चपटे और भद्दे का उपयोग कर सकते हैं, यह आसान होगा
ओमू

ViewModel और Domain Entities समान हैं, लेकिन अलग-अलग हैं, इसलिए शुद्ध क्लोन नहीं है। 90% संपत्तियां आमतौर पर सटीक प्रकार और नाम होती हैं, ViewModels अक्सर SelectLists और उनके साथ बंधे सामान के साथ समाप्त होता है जो मैं डोमेन पर वापस आने की उपेक्षा करना चाहता हूं। दोनों उन पर वस्तुओं का संग्रह होने की बहुत संभावना है, हालांकि।
क्रिस मैरिकिक

27
<pedant>अच्छा लग रहा है, लेकिन शायद यह ValueInjectOr होना चाहिए? </pedant>
क्रेग स्टंट

1
लेकिन किसी कारण के लिए यह एर है :)
ओमू

59

चूंकि मैंने कभी किसी अन्य उपकरण का उपयोग नहीं किया है, इसलिए मैं केवल ऑटोमैपर के बारे में बात कर सकता हूं। ऑटोमैपर निर्माण के लिए मेरे मन में कुछ लक्ष्य थे:

  • डीटीओ ऑब्जेक्ट्स को डंबल करने के लिए सपाट समर्थन
  • बॉक्स से बाहर स्पष्ट परिदृश्यों का समर्थन करें (संग्रह, गणना आदि)
  • परीक्षण में मैपिंग को आसानी से सत्यापित करने में सक्षम हो
  • अन्य स्थानों से मानों को हल करने के लिए किनारे के मामलों की अनुमति दें (कस्टम प्रकार-> प्रकार मानचित्रण, व्यक्तिगत सदस्य मानचित्रण, और कुछ वास्तव में पागल किनारे मामले)।

अगर आप इन चीजों को करना चाहते हैं, तो AutoMapper आपके लिए बहुत अच्छा काम करता है। चीजें AutoMapper अच्छी तरह से नहीं कर रहे हैं:

  • मौजूदा वस्तुओं को भरना
  • Unflattening

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


1
@ जिमी बोगार्ड क्या आप देखते हैं कि मौजूदा ऑब्जेक्ट्स को भरना ऑटोमैपर के लिए फीचर लिस्ट में शामिल होगा?
रोमन

मैंने ValueInjecter की कोशिश नहीं की है, लेकिन हमें जो चाहिए है, उसके लिए ऑटोमैपर बहुत शक्तिशाली है।
ऋग्वेद ०

मुझे लगता है कि यहाँ सबसे महत्वपूर्ण बात है, सत्यता। जब चीजों का नाम बदलना और उन्हें फिर से लाना एक बहुत बड़ी मदद है।
कुगेल

55

मैंने दोनों की कोशिश की और ValueInjecter को प्राथमिकता दी क्योंकि यह बहुत सरल है:

myObject.InjectFrom(otherObject);

यह सब मेरी इंजेक्शन की जरूरतों के विशाल बहुमत के लिए जानना है। यह संभवतः इससे अधिक सरल और सुरुचिपूर्ण नहीं हो सकता।


1
this objectविस्तार विधि?
क्रिस मैरिसिक

2
मैं ValueInjecter से अपना कोड कैसे कम कर सकता हूं? मेरे लिए ऐसा लगता है कि मेरे वेब प्रोजेक्ट में हमेशा ValueInjecter की एक प्रतिपुष्टि होती है, क्योंकि मैं दिए गए ऑब्जेक्ट पर ValueInjecter (विस्तार विधि) का उपयोग प्रत्यक्ष रूप से करता हूं।
रूकियन

1
@Rookian ईमानदारी से यह एक चिंता का विषय नहीं है जिसे आपको बहुत अधिक विचार में रखना चाहिए। आप इंटरफ़ेस पर निर्भर कर सकते हैं जैसे @Omu का उल्लेख इसलिए यदि आप कभी भी मैपर बदलते हैं तो आप कुछ काम बचा सकते हैं (शायद ज्यादा नहीं)। इस प्रकार की निर्भरता केवल तब तक दूर करना कठिन है जब तक कि आप पूर्ण विकसित एओपी में नहीं आना चाहते हैं जो दुर्भाग्य से कई बार सिर्फ अवांछनीय है क्योंकि .NET सही ढंग से एओपी सहायता प्रदान करने में मदद नहीं करता है। अब आप कुछ मैपिंग को AOP से दूर कर सकते हैं, खासकर यदि आप MVC का उपयोग करते हैं और एक्शन फिल्टर्स लिखते हैं जो ViewModel / DomainModel मैपिंग को संभालते हैं।
क्रिस मैरिकिक

13
क्यों एक आवरण सबसे अच्छा समाधान है? केवल एक चीज जो आपको करने की आवश्यकता है यदि आप मैपर स्विच करना चाहते हैं, तो अपने आप से InjectFrom()विस्तार विधि को लागू करना है ।
jgauffin

1
मैंने दोनों की कोशिश की है और मैं AutoMapper पसंद करता हूं। मैंने इसे अपने सिस्टम के एक छोटे से हिस्से के लिए इस्तेमाल किया, जहाँ मैं Linq2Sql जनरेट की गई कक्षाओं के साथ एंटिटीज़ को मैप करता हूँ। StockTotalQuantity -> stock_size_quantity या UserId -> user_id के रूप में सरल मैपिंग ने डिफ़ॉल्ट रूप से AutoMapper के साथ काम किया। यह जोड़ने के बाद भी ValeInjecter के साथ काम नहीं किया। अब के लिए AutoMapper से चिपके रहते हैं।
अर्तुर कदज़ीर

27

यह एक ऐसा प्रश्न है जिस पर मैं शोध कर रहा हूं, और मेरे उपयोग के मामले के लिए, यह मूल्य-सूचक हाथ नीचे लगता है। इसका उपयोग करने के लिए किसी पूर्व सेटअप की आवश्यकता नहीं है (प्रदर्शन पर मेरे विचार से प्रभावित हो सकता है, हालाँकि यदि चालाकी से इसे लागू किया जाता है तो यह भविष्य के चालान के लिए मैपिंग को हर बार प्रतिबिंबित करने के बजाय कैश कर सकता है), इसलिए आपको उनका उपयोग करने से पहले किसी मैपिंग को पूर्वनिर्धारित करने की आवश्यकता नहीं है।

सबसे महत्वपूर्ण बात यह है कि यह रिवर्स मैपिंग की अनुमति देता है। अब मुझे यहाँ कुछ याद आ रहा है क्योंकि जिमी ने कहा कि उसे कोई उपयोग का मामला नहीं दिख रहा है जहाँ इसकी आवश्यकता है, इसलिए शायद मेरा पैटर्न गलत है, लेकिन मेरा उपयोग मामला यह है कि मैं अपने ORM से एक ViewModel ऑब्जेक्ट बना रहा हूँ। मैं इसे अपने वेबपेज पर प्रदर्शित करता हूं। एक बार जब उपयोगकर्ता समाप्त हो जाता है, तो मैं ViewModel को एक कैंपस के रूप में वापस प्राप्त करता हूं, यह मूल ORM कक्षाओं में वापस कैसे परिवर्तित होता है? मुझे ऑटोमैपर के साथ पैटर्न जानना अच्छा लगेगा। ValueInjector के साथ यह तुच्छ है, और यह अप्रभावित भी रहेगा। उदा। एक नई इकाई बनाना

Unitframework द्वारा बनाया गया मॉडल (पहले मॉडल):

public partial class Family
{ 
    public int Id { get; set; }
    public string FamilyName { get; set; }

    public virtual Address Address { get; set; }
}

public partial class Address
{
    public int Id { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string TownCity { get; set; }
    public string County { get; set; }
    public string Postcode { get; set; }

    public virtual Family Family { get; set; }
}

ViewModel (जिसे मैं सत्यापनकर्ताओं के साथ सजा सकता हूं):

public class FamilyViewModel
{
    public int Id { get; set; }
    public string FamilyName { get; set; }

    public int AddressId { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string AddressTownCity { get; set; }
    public string AddressCounty { get; set; }
    public string AddressPostcode { get; set; }
}

ViewController:

    //
    // GET: /Family/Create

    public ActionResult Create()
    {
        return View();
    } 

    //
    // POST: /Family/Create

    [HttpPost]
    public ActionResult Create(FamilyViewModel familyViewModel)
    {
        try
        {
            Family family = new Family();
            family.InjectFrom<UnflatLoopValueInjection>(familyViewModel);
            db.Families.Add(family);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

मेरे दिमाग में, यह उससे ज्यादा सरल नहीं है?

(तो यह सवाल है, पैटर्न है कि मैं इस में चलाने के साथ क्या गलत है (और ऐसा लगता है कि कई अन्य करते हैं), कि यह AutoMapper के मूल्य के रूप में नहीं देखा है?)

हालाँकि, यदि यह पैटर्न डिस्क्राइब्ड है, तो क्या आप इसका उपयोग करना चाहते हैं, तो मेरा वोट देश मील के हिसाब से महत्वपूर्ण है।


1
शायद आपको इसे asp.net-mvc और सर्वोत्तम प्रथाओं, ViewModel के साथ टैग किए गए एक अलग प्रश्न में भी पूछना चाहिए ..., atm मुझे कोई समस्या नहीं दिखती है जब तक कि यह आपके लिए अच्छा काम करता है, लेकिन मुझे यकीन है कि किसी की अलग-अलग राय हो सकती है
ओमू

अच्छी तरह से अधिक mvc सीखा है। मैं अब अपने प्रश्न का उत्तर दे सकता हूं। मूल मॉडल को अपडेट करने का तरीका जब आपको एक पॉप्युलेटेड व्यू मॉडल वापस मिलता है, तो अपडेटमॉडल () फंक्शन mvc प्रदान करता है।
दानह

1
UpdateModel () एक्शन (MyModelClasss मॉडल) कर के रूप में मॉडल दृश्य का प्रतिनिधित्व कि पॉप्युलेट करने के लिए प्रयोग किया जाता है, और है ही
Omu

सच है, लेकिन यदि आप एक रिपॉजिटरी मॉडल उदाहरण के लिए एक अलग दृश्य मॉडल रखना चाहते हैं, तो इसका उपयोग यह पॉप्युलेट करने के लिए किया जा सकता है कि मानचित्रण तुच्छ है (और यह अक्सर होता है)। बेशक अगर अधिक जटिल ValueInjector अपने आप में आता है।
दानह

1
मुझे लगता है कि यह तर्क दिया जा सकता है कि आपको अपने गुणों को अपने डोमेन मॉडल पर वापस सेट नहीं करना चाहिए - आपको उन तरीकों का उपयोग करना चाहिए जो इसमें अर्थ जोड़ते हैं।
माइक कोल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.