2011-01-24 18 views
6

मैं एक डोमेन मॉडल से गुणों को मैप करने के लिए ValueInjecter का उपयोग कर रहा हूं, जो एक सेवा परत के माध्यम से एक डीटीओ पर कार्य करता है। प्रश्न में सेवा अद्यतन स्वीकार करती है ... इसलिए एक अद्यतन डीटीओ पारित किया जाता है और फिर इसे डोमेन ऑब्जेक्ट में इंजेक्शन दिया जाता है और सहेजा जाता है।वैल्यू इंजेक्टर: डीटीओ टू डोमेन मॉडल (एनएचबीर्नेट)

// Domain 
    public class Member 
    { 
     public Country Country { get; set; } 
    } 

    public class Country 
    { 
     public string Code { get; set; } 
     public string Name { get; set; } 
    } 

    //Dto 
    public class MemberDto 
    { 
     public string CountryCode { get; set; } 
    } 

    //Transformation Method attempt 1 
    public Member InjectFromDto (MemberDto dto, Member source) 
    { 
     source = source.InjectFrom<UnflatLoopValueInjection>(dto); 
     return source; 
    } 

अब यह सब ऊपर कोड करता है अद्यतन करता है संपत्ति Member.Country.Code जो स्पष्ट रूप से क्या मैं इसे की जरूरत है ऐसा करने के लिए नहीं है।

तो डॉक्स से, मैं समझ मैं एक ओवरराइड बनाने के लिए आवश्यक है और इस मिला:

public class CountryLookup: UnflatLoopValueInjection<string, Country> 
    { 
     protected override Country SetValue(string sourcePropertyValue) 
     { 
      return countryService.LookupCode(sourcePropertyValue); 
     } 
    } 


//revised transformation call 
//Transformation Method attempt 2 
    public Member InjectFromDto (MemberDto dto, Member source) 
    { 
     source = source.InjectFrom<UnflatLoopValueInjection>(dto) 
         .InjectFrom<CountryLookup>(dto); 
     return source; 
    } 

मेरे समस्या डीबगिंग के दौरान है, CountryLookup कभी नहीं कहा जाता हो जाता है।

करने के कारणों में मैं के बारे में सोच सकते हैं: injecter को देश प्रकार से मेल नहीं मूल्य के कारण

  • Nhibernate प्रॉक्सी वर्गों? यह समझ में नहीं आता है क्योंकि यह flattening के दौरान काम करता है।
  • शायद किसी कारण से unflattening फायरिंग नहीं है। यानी Dto CountryCode है और डोमेन Country.Code

है मैं सही वस्तु लौटने के लिए अद्यतन इंजेक्शन के दौरान उपयोग करने के लिए एक countryService.LookupCode कॉल करने के लिए Dto पर CountryCode संपत्ति का उपयोग करने की जरूरत है।

+0

हमें बताएं कि आप क्या हासिल करने की कोशिश कर रहे हैं, पहला प्रयास काम करता है, लेकिन यह आवश्यक नहीं है कि आपको क्या चाहिए, आपको क्या चाहिए? – Omu

+0

देश लुकअप नामक आपका इंजेक्शन स्ट्रिंग से देश में खुला होगा जिसका अर्थ है कि यह देशकोड प्रकार की स्ट्रिंग से मूल्य प्राप्त करने के लिए प्रतीत होता है और इसे देश में डालता है। प्रकार का कोड देश – Omu

+0

@ ओमु यह सही है उदाहरण के लिए यदि मेरा देश वस्तु देश है: {कोड : यूएसए, नाम: संयुक्त राज्य} और मेरा डीटीओ देशकोड में गुजरता है: "सीए" यह सिर्फ देश को सेट करता है। सीओ को संपत्ति को कोड करें और 'नाम' संपत्ति को संयुक्त राज्य अमेरिका के रूप में छोड़ दें। याद रखें कि मैं एक पूर्व-जनसंख्या वाले डोमेन ऑब्जेक्ट को अपडेट कर रहा हूं ... इस वजह से मुझे सही देश ऑब्जेक्ट देखने के लिए अपने देश सेवा को कॉल करने की आवश्यकता है। मैं डीटीओ से 'कोड' को कैप्चर करना चाहता हूं, और उसके बाद सही देश ऑब्जेक्ट को देखने के लिए उस कोड का उपयोग करना चाहता हूं। – Galen

उत्तर

3

विरासत सुझाव/संदर्भ Omu से इस समस्या के लिए विशिष्ट कोड था का उपयोग करना।

public class CountryLookup : ExactValueInjection 
    { 
     private ICountryService countryservice; 

     public CountryLookup(ICountryService countryService) 
     { 
      this.countryService = countryService; 
     } 

     protected override bool TypesMatch(Type s, Type t) 
     { 
      return (s == typeof(string)) && (t == typeof (Country)); 

     } 
     protected override Object SetValue(object v) 
     { 
      if (v == null) 
       return null; 

      var country = countryService.LookupCode((string) v); 
      return country; 
     } 

     public override string SourceName() 
     { 
      return "CountryCode"; 
     } 

     public override string TargetName() 
     { 
      return "Country"; 
     }  
    } 

public Member InjectFromDto (MemberDto dto, Member source) 
{ 
    source = source.InjectFrom<UnflatLoopValueInjection>(dto) 
        .InjectFrom<CountryLookup>(dto); 
    return source; 
} 
+1

हां, यह काम करना चाहिए (हालांकि मुझे नहीं लगता कि आप कन्स्ट्रक्टर पैरामीटर आईसीउंट्री सेवा कैसे सेट करते हैं), मैं चाहता था कि आप एक और सामान्य तरीका देखें, – Omu

+0

सब कुछ के लिए एक इंजेक्शन कैसल विंडसर के माध्यम से इस मामले में कन्स्ट्रक्टर पैरामीटर सेट किया गया है निर्भरता अन्तःक्षेपण। समाधान के लिए यह एक मूक बिंदु है क्योंकि वास्तविक रूप से सेवा कॉल प्रासंगिक नहीं है। – Galen

+0

इसके अलावा, मैं आपके सुझावों का उपयोग करके इस परियोजना के लिए एक सामान्य समाधान पर विचार कर रहा हूं, धन्यवाद :) – Galen

0

क्या एक ढांचा सेटटर विधि को बुला रहा है? अधिकांश डी ढांचे में, मानक setMethod() में मानक लोअरकेस है। बस एक पहली विचार सिफारिश।

+0

क्या आप SetValue विधि का जिक्र कर रहे हैं? यदि ऐसा है, तो यह ValueInjecter ढांचे का हिस्सा है। – Galen

+0

निक, यह .NET है, जावा नहीं, .NET मानक विधि नामों के लिए पास्कल केस है, ऊंट के मामले में नहीं। – Phill

3

unflattening यह करने के लिए होगा:

entity.Country.Code <- dto.CountryCode 

क्या आप की जरूरत है:

entity.Country <- dto.CountryCode 

तो समाधान आप एक ExactValueInjection जहां देश कोड से देश के लिए जाना जाएगा वारिस होगा के लिए।

क्या मैं तुम्हें करने के लिए सलाह देते हैं एक ही है कि मैं मेरा http://awesome.codeplex.com

की एक अन्य परियोजना के लाइव डेमो में किया था वह जगह है जहाँ मैं कुछ इस तरह है:

public class Entity 
    { 
     public int Id{get;set;} 
    } 
    public class Member : Entity 
    { 
     public Country Country{get;set;} 
    } 
    public class MemberDto : DtoWithId 
    { 
     public int? Country {get;set;} 
    } 

और इन का उपयोग इंजेक्शन से इकाई से डीटीओ और पीछे

public class NullIntToEntity : LoopValueInjection 
     { 
      protected override bool TypesMatch(Type sourceType, Type targetType) 
      { 
       return sourceType == typeof(int?) && targetType.IsSubclassOf(typeof(Entity)); 
      } 

      protected override object SetValue(object sourcePropertyValue) 
      { 
       if (sourcePropertyValue == null) return null; 
       var id = ((int?) sourcePropertyValue).Value; 

       dynamic repo = IoC.Resolve(typeof(IRepo<>).MakeGenericType(TargetPropType)); 

       return repo.Get(id); 
      } 
     } 
//(you also need to have a generic repository, notice IRepo<>)  
    public class EntityToNullInt : LoopValueInjection 
     { 
      protected override bool TypesMatch(Type sourceType, Type targetType) 
      { 
       return sourceType.IsSubclassOf(typeof (Entity)) && targetType == typeof (int?); 
      } 

      protected override object SetValue(object o) 
      { 
       if (o == null) return null; 
       return (o as Entity).Id; 
      } 
     } 

ये इंजेक्शन न केवल चलेंगे int से? देश और वापस करने के लिए, लेकिन यह भी किसी भी अन्य प्रकार जो इकाई

+0

यह टिप्पणी मेरी समस्या के विशिष्ट उत्तर की ओर ले जाती है लेकिन सटीक उत्तर नहीं दिखाती है, जो बीमार पोस्ट है। इसे सहायक के रूप में +1 किया जा सकता है। – Galen

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