2010-05-23 17 views
10

मैं अक्सर मॉडल (डोमेन) मैप करने के लिए ViewModel वस्तुओं, जो तब मेरी दृश्य द्वारा खपत होती है करने के लिए वस्तुओं एक मॉडल/देखें/ViewModel पैटर्न में, AutoMapper का उपयोग करें।'CreateMap' कथन कहां जाना चाहिए?

इसमें कई 'Mapper.CreateMap' कथन शामिल हैं, जिन्हें सभी को निष्पादित किया जाना चाहिए, लेकिन आवेदन के जीवन चक्र में केवल को निष्पादित किया जाना चाहिए।

तकनीकी रूप से, तो, मुझे उन्हें सभी को एक स्थिर विधि में रखना चाहिए, जिसे मेरी एप्लिकेशन_स्टार्ट() विधि से कहा जाता है (यह एक एएसपी.नेट एमवीसी एप्लीकेशन है)।

हालांकि, यह एक केंद्रीय स्थान में विभिन्न मानचित्रण चिंताओं का एक बहुत एक साथ समूह में गलत लगता है।

खासकर जब मानचित्रण कोड जटिल हो जाता है और स्वरूपण और अन्य तर्क शामिल है।

वहाँ मानचित्रण कोड इतना है कि यह ViewModel कि यह चिंताओं के पास रखा जाता है व्यवस्थित करने के लिए एक बेहतर तरीका है?

(मैं एक विचार के साथ आया था - प्रत्येक ViewModel पर एक 'CreateMappings' विधि है, और BaseViewModel में, इन्स्टेन्शियशन पर इस विधि बुला हालांकि, बाद से विधि केवल एक बार आवेदन जीवन चक्र में बुलाया जाना चाहिए,। ViewModel प्रकारों की एक सूची को कैश करने के लिए इसे कुछ अतिरिक्त तर्क की आवश्यकता है जिसके लिए CreateMappings विधि को कॉल किया गया है, और फिर केवल उस समय कॉलमोडल्स के लिए इसे कॉल करें, जो उस सूची में नहीं हैं।)

उत्तर

2

यदि आप प्रोफ़ाइल का उपयोग करते हैं, तो आप वहां आपके सभी "CreateMap" कॉल कर सकते हैं। इसके अतिरिक्त, आप एक स्थिर बूटस्ट्रैप क्लास बना सकते हैं जिसमें आपकी कॉन्फ़िगरेशन हो, और स्टार्टअप टुकड़ा केवल बूटस्ट्रैपर को कॉल करें।

+0

लेकिन वह अभी भी सभी अलग दृष्टिकोण मॉडल एक साथ lumped के लिए सभी मैपिंग होने की समस्या का समाधान नहीं होता है, जब मैं नहीं बल्कि होगा वे किसी भी तरह से उन कक्षाओं से संबंधित हैं जो वे लागू होते हैं। – Jonathan

0

ठीक है, जिस तरह से मैं वर्तमान में यह कर रहा हूँ यह है:

मैं अपने BaseController है, जो 'CreateMappings' विधि चलाता है के निर्माता के लिए कुछ तर्क जोड़ सकते हैं, लेकिन केवल एक बार प्रति नियंत्रक प्रकार:

public abstract class BaseController : Controller 
{  
    public BaseController() 
    { 
     if (!controllersWithMappingsCreated.Contains(GetType())) 
     { 
      CreateMappings(); 
      controllersWithMappingsCreated.Enqueue(GetType()); 
     } 
    } 

    protected virtual void CreateMappings() { } 
} 

प्रत्येक ठोस नियंत्रक में, मैं CreateMappings उपयोग करने वाले सभी मॉडल/कि नियंत्रक के लिए प्रासंगिक ViewModels के लिए मैपिंग घोषित करने के लिए।

public class AccountController : BaseController 
{ 
    public AccountController() : base() { } 

    protected override void CreateMappings() 
    { 
     Mapper.CreateMap<Models.User, ViewModels.UserProfile>(); 
     Mapper.CreateMap<Models.User, ViewModels.ChangePassword>(); 
    } 
} 

मैं भी कुछ दिलचस्प से जुड़े गुण here और here, लेकिन वे मुझे थोड़ी overcomplicated के रूप में हड़ताल विकल्प मिल गया।

+2

मेरे पास अभी भी स्थिर बूटस्ट्रैप क्लास होगा, इसलिए आप अपने मैपिंग को एकजुट कर सकते हैं। – Martin

+0

अच्छा काम। लेकिन 'बेसकंट्रोलर' में 'नियंत्रक WithMappingsCreated' क्या है? – Blaise

6

तुम सच में एक bootstrapper का उपयोग नहीं करना चाहते हैं, तो कम से कम एक स्थिर निर्माता अपने CreateMap सुनिश्चित करने के लिए एक आसान तरीका सबसे एक ही बार में कहा जाता है। (कम चारों ओर और अधिक धागा प्रमाण जोनाथन के जवाब से खिलवाड़ के साथ।)

public class AccountController : Controller 
{ 
    static AccountController() 
    { 
     Mapper.CreateMap<Models.User, ViewModels.UserProfile>(); 
     Mapper.CreateMap<Models.User, ViewModels.ChangePassword>(); 
    } 
} 
+0

मै मैपिंग को स्थिर कन्स्ट्रक्टर में डालने के साथ कोई भाग्य नहीं है। मुझे लगता है कि मुझे उन्हें इंस्टेंस कन्स्ट्रक्टर में रखना होगा। – AaronLS

+0

@AaronLS ओह नहीं। क्या आपको अपवाद या ऐसा कुछ मिलता है? रचनाकारों और मैपिंग के लिए आप किन वर्गों का उपयोग कर रहे हैं? –

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