2010-11-17 15 views
17

मैं वर्तमान में निम्नलिखित मानचित्रण है:Automapper एक साथ निर्भरता इंजेक्शन के साथ

Mapper.CreateMap<Journal, JournalDto>(); 

अब, JournalRefTypeID नाम के एक सदस्य है, जो इसी मूल्य डेटाबेस में एक और तालिका में मौजूद होता है; इस मूल्य को देखने के लिए, मेरे पास एक सेवा है जो एक साधारण int -> string अनुरोध को संभालती है। स्वचालित रूप से प्रोग्राम की शुरुआत में एक स्थिर वर्ग में ऑटोमैपर कॉन्फ़िगरेशन होता है। क्या मैपिंग कोड को उस वर्ग में स्थानांतरित करना ठीक है जो मेरे डी कंटेनर में इंजेक्शन दिया जाता है या क्या कोई बेहतर तरीका है? ,

public interface IMappingCreator 
{ 
    void CreateMappings(); 
} 

मैं आगे चला गया और कि इंटरफेस (मैं डि कंटेनर के रूप में MEF उपयोग कर रहा हूँ के साथ एक वर्ग को लागू किया है कि जहां है:

मैं एक IMappingCreator इंटरफेस परिभाषित:

+0

एकमात्र कारण जिसे मैं नहीं सोच सकता कि पूरी तरह संगठनात्मक नहीं होगा। आपके पास संभावित रूप से आपके प्रोजेक्ट में मैपिंग कोड होगा। यदि आपका डोमेन ऑब्जेक्ट बदलता है या डीटीओ आदर्श से कम हो सकता है। लेकिन मैं अन्य लोगों से उनकी राय जानने के लिए उत्सुक हूं। – Daniel

+0

ठीक है, मैं अभी भी मैपिंग कोड को एक ही स्थान पर रखूंगा - यानी।वह कक्षा, जो डी कंटेनर से सभी आवश्यक सेवाओं को पकड़ लेगी। मुझे बस स्वचालित रूप से निष्पादित स्थिर कन्स्ट्रक्टर पर भरोसा करने में सक्षम होने के बजाय मैपिंग शुरू करना होगा। – Femaref

+0

नवीनतम संस्करण के लिए, [this] (http://stackoverflow.com/a/35431096/1977871) पर एक नज़र डालें, इसलिए – VivekDev

उत्तर

8

यहाँ कैसे मैं इसे हल है गुण IMappingCreator रूप से आ रहे हैं) जो डि कंटेनर में डाल दिया है:

[Export(typeof(IMappingCreator))] 
    public class Mapping : IMappingCreator 
    { 
     private readonly IRefTypesLookup iRefTypesLookup; 


     [ImportingConstructor] 
     public Mapping(IRefTypesLookup rtl) 
     { 
      iRefTypesLookup = rtl; 
     } 

     public void CreateMappings() 
     { 
      Mapper.CreateMap<Journal, DisplayJournal>().AfterMap((j, dj) => dj.RefTypeName = iRefTypesLookup.Lookup(j.RefTypeID)); 
     } 
    } 

अंत में, अपने आवेदन स्टार्टअप में, मैं सभी instanc लाने कंटेनर में है कि इंटरफेस और की तों उन पर CreateMappings विधि कॉल:

var mappings = container.GetExportedValues<IMappingCreator>(); 

    foreach (IMappingCreator mc in mappings) 
    { 
     mc.CreateMappings(); 
    } 

यह प्रारंभिक सेटअप काफी आसान बना देता है, के रूप में सारी सृष्टि एक ही स्थान पर होता है, और आप के रूप में कई मानचित्रण रचनाकारों हो सकता है के रूप में आप चाहते हैं (हालांकि, आपको उन परियोजनाओं में विशिष्ट प्रकारों को मैप करने के लिए सभी आवश्यक सेवाओं को पकड़ने के लिए, प्रति परियोजना या तो एक बार न्यूनतम रखना चाहिए)।

+0

उत्तर दें यह बहुत अच्छा है ... मुझे इससे उधार लेना पड़ सकता है! : डी एमईएफ ढांचे के लिए इतना बड़ा जोड़ा है। – Daniel

+0

नि: शुल्क महसूस करें, मुझे नहीं लगता कि मैं अकेले ही इस समस्या के खिलाफ आ रहा हूं। – Femaref

14

आप के बजाय स्थिर वर्ग Mapper का उपयोग करने का IMappingEngine पर निर्भरता लग सकता है।

इसके बारे में यहाँ एक अच्छा ब्लॉग पोस्ट नहीं है: Mocking out AutoMapper with Dependency Injection

14

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

Mapper.Initialize(cfg => { 
    cfg.ConstructServicesUsing(type => WhateverMefUsesToGetInstances.GetInstance(type)); 

    cfg.CreateMap<Journal, DisplayJournal>() 
     .ForMember(dest => dest.RefTypeName, 
      opt => opt.ResolveUsing<RefTypeNameResolver>()); 
}); 

फिर अपने समाधानकर्ता हो जाता है:

[Export(typeof(IRefTypeNameResolver))] 
public class RefTypeNameResolver : ValueResolver<Journal, string>, IRefTypeNameResolver 
{ 
    private readonly IRefTypesLookup iRefTypesLookup; 

    [ImportingConstructor] 
    public RefTypeNameResolver (IRefTypesLookup rtl) 
    { 
     iRefTypesLookup = rtl; 
    } 

    protected override string ResolveCore(Journal source) 
    { 
     return iRefTypesLookup.Lookup(source.RefTypeID); 
    } 
} 

विन्यास एक बार निष्पादित करने के लिए की जरूरत है, जिसके कारण विन्यास एपीआई निष्पादन एपीआई में हुक (प्रकार कन्वर्टर्स, मूल्य रिसोल्वर आदि)

+1

मुझे ValueResolver के बारे में पता था, लेकिन मैंने सोचा कि वे बेकार थे क्योंकि मैं कॉन्स्ट्रक्चर सर्विसेज कॉन्फ़िगरेशन को याद कर रहा था। अच्छा है! – Kugel

1

यहाँ यह कर के नवीनतम तरीका है ... प्रदान करता है

https://pintoservice.wordpress.com/2016/01/31/dependency-injection-for-automapper-4-2-in-asp-net-vnext-mvc-project/

हालांकि मैं व्यक्तिगत रूप से, नियंत्रक में ऑटो-मैपिंग जोड़ने भंडार में नहीं। इस तरह आप विभिन्न नियंत्रकों के लिए एक ही भंडार का उपयोग कर सकते हैं और अलग मैपिंग कर सकते हैं। हालांकि, वही अवधारणा, भंडार के बजाय नियंत्रक में IMapper इंजेक्ट करें।

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