ब्लॉग हटा दिया गया है तय - यहाँ @DannyDouglass
करके पोस्ट का बिंग संग्रह है
सरल AutoMapper और Linq करने वाली Xml
साथ XML डेटा का उपयोग करना
मैं हाल ही में काम पर एक परिदृश्य में भाग गया जिसकी मैन्युअल रूप से कई एसओएपी वेब सेवाओं का उपभोग करने की आवश्यकता है, जो मुझे यकीन है कि आप कल्पना कर सकते हैं बल्कि एकान्त था। एक सहकर्मी (सेठ कार्नी) और मैंने कुछ अलग दृष्टिकोणों की कोशिश की, लेकिन हम अंततः एक समाधान पर बस गए जो एक्सएमएल की सरलीकृत खपत और आखिरकार कोड को अधिक टेस्टेबल बना दिया। एसओएपी संदेशों और हमारे द्वारा बनाए गए कस्टम अनुबंधों में लौटाए गए XElements (http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.aspx) के बीच एक लिंक बनाने के लिए एक ओपन सोर्स ऑब्जेक्ट-ऑब्जेक्ट मैपिंग टूल, ऑटोमैपर का लाभ उठाने के आसपास केंद्रित समाधान - एक पुन: प्रयोज्य तरीके से।
मैंने एक त्वरित डेमो लगाया जो दिखाता है कि आप ट्विटर पब्लिक टाइमलाइन (http://api.twitter.com/1/statuses/public_timeline.xml) (एपीआई के एक्सएमएल प्रतिक्रिया प्रकार का उपयोग करके) का उपभोग और प्रदर्शन करने के लिए एक ही दृष्टिकोण का उपयोग कैसे कर सकते हैं।
नोट: निम्न उदाहरण के लिए स्रोत कोड मेरी GitHub पृष्ठ पर पाया जा सकता है: https://github.com/DannyDouglass/AutoMapperXmlMappingDemo
- परियोजना सेटअप
हो रही एक बुनियादी MVC3 (डाउनलोड बीटा) परियोजना और बनाने के बाद संबंधित परीक्षण परियोजना, पहला कदम ऑटोमैपर पैकेज स्थापित करना था।मैं किसी भी ओपन सोर्स निर्भरताओं को स्थापित करने के लिए माइक्रोसॉफ्ट की हाल ही में घोषित पैकेज प्रबंधन प्रणाली NuGet का उपयोग कर रहा हूं। निम्न आदेश सभी कि मेरे MVC3 परियोजना में सेटअप AutoMapper की जरूरत थी था (NuGet यहाँ (http://weblogs.asp.net/scottgu/archive/2010/10/06/announcing-nupack-asp-net-mvc-3-beta-and-webmatrix-beta-2.aspx) और यहाँ (http://weblogs.asp.net/scottgu/archive/2010/10/06/announcing-nupack-asp-net-mvc-3-beta-and-webmatrix-beta-2.aspx) के बारे में अधिक पढ़ सकते हैं):
PM> add-package AutoMapper
- मानचित्रण बनाना
ऑटोमैपर स्थापित के साथ मैं xml-to-object मैपिंग के लिए आवश्यक घटकों को बनाने शुरू करने के लिए तैयार हूं। - बस एक साधारण इकाई
public interface ITweetContract
{
ulong Id { get; set; }
string Name { get; set; }
string UserName { get; set; }
string Body { get; set; }
string ProfileImageUrl { get; set; }
string Created { get; set; }
}
यहाँ पागल कुछ भी नहीं है: पहला कदम एक त्वरित अपने आवेदन में इस्तेमाल किया ट्वीट वस्तु का प्रतिनिधित्व करने के अनुबंध पैदा कर रही है। ये सभी फ़ील्ड हैं जो कुछ क्षेत्रों के लिए एक अलग नाम का उपयोग कर ट्विटर एपीआई से प्रतिक्रिया में प्रदान की जाती हैं। सरल मामलों में जहां स्रोत और गंतव्य वस्तुओं में एक ही नाम आप सेटअप कर सकते हैं है में एक नक्शे के बहुत जल्दी इस सिंटैक्स का उपयोग:
Mapper.CreateMap<SourceObj, DestinationObj>();
हालांकि, AutoMapper Xml का समर्थन नहीं करता डिफ़ॉल्ट रूप से मैं क्षेत्रों है कि मैं हो जाएगा निर्दिष्ट करना मानचित्रण। ऑटोमैपर में फ़्लुएंट एपीआई का उपयोग करके मैं अपने फील्ड मैपिंग को चेन करने में सक्षम हूं। मेरे उदाहरण में मैप एक उदाहरण क्षेत्र पर एक नजर डालें - ट्वीट बॉडी:
Mapper.CreateMap<XElement, ITweetContract>()
.ForMember(
dest => dest.Body,
options => options.ResolveUsing<XElementResolver<string>>()
.FromMember(source => source.Element("text")))
यह पहली बार जटिल लग सकता है, लेकिन यह सब वास्तव में यहाँ क्या हो रहा है कि हम क्या मान का उपयोग करने पर AutoMapper करने के लिए विवरण प्रदान कर रहे हैं मेरे स्रोत ऑब्जेक्ट में और इसे गंतव्य ऑब्जेक्ट की संपत्ति पर कैसे मैप करना है।
options => options.ResolveUsing<XElementResolver<ulong>>()
.FromMember(source => source.Element("id")))
XElementResolver एक कस्टम मूल्य रिसोल्वर (http://automapper.codeplex.com/wikipage?title=Custom%20Value%20Resolvers) कि सेठ XmlElement स्रोत ऑब्जेक्ट को पार्स एक पुनः प्राप्त करने संभाल करने के साथ आया है: वहाँ एक विशेष लाइन मैं ऊपर शारीरिक क्षेत्र मानचित्रण में पर ध्यान केंद्रित करना चाहते हैं मानचित्रण में उपयोग के लिए दृढ़ता से टाइप मूल्य।
Mapper.CreateMap<XElement, ITweetContract>()
.ForMember(
dest => dest.Id,
options => options.ResolveUsing<XElementResolver<ulong>>()
.FromMember(source => source.Element("id")))
.ForMember(
dest => dest.Name,
options => options.ResolveUsing<XElementResolver<string>>()
.FromMember(source => source.Element("user")
.Descendants("name").Single()))
.ForMember(
dest => dest.UserName,
options => options.ResolveUsing<XElementResolver<string>>()
.FromMember(source => source.Element("user")
.Descendants("screen_name").Single()))
.ForMember(
dest => dest.Body,
options => options.ResolveUsing<XElementResolver<string>>()
.FromMember(source => source.Element("text")))
.ForMember(
dest => dest.ProfileImageUrl,
options => options.ResolveUsing<XElementResolver<string>>()
.FromMember(source => source.Element("user")
.Descendants("profile_image_url").Single()))
.ForMember(
dest => dest.Created,
options => options.ResolveUsing<XElementResolver<string>>()
.FromMember(source => source.Element("created_at")));
- जेनेरिक XElementResolver
यह कस्टम: मुझे लगता है कि एक पल में अधिक है, लेकिन इससे पहले कि हम अपना पूरा मानचित्रण पर एक नज़र डालें आगे बढ़ने विस्तार करेंगे मूल्य समाधानकर्ता वास्तविक कुंजी है जो इन XElement-to-Contract मानचित्रों को मूल समाधान में काम करने की अनुमति देती है। जैसा कि हमने उपरोक्त देखा है, मैंने इस उदाहरण में इस रिज़ॉल्यूवर का पुन: उपयोग किया है। यह सब है कि कस्टम समाधानकर्ता वर्ग बनाने के लिए जरूरी हो गया था था:
public class XElementResolver<T> : ValueResolver<XElement, T>
{
protected override T ResolveCore(XElement source)
{
if (source == null || string.IsNullOrEmpty(source.Value))
return default(T);
return (T)Convert.ChangeType(source.Value, typeof(T));
}
}
यह सामान्य XElementResolver उपयोग आसानी से ऊपर अपनी मैपिंग में लिया गया मान का प्रकार पारित करने के लिए अनुमति देता है। उदाहरण के लिए, निम्न सिंटैक्स दृढ़ता से() घोषणा से ऊपर क्रमांक क्षेत्र के .ForMember में XmlElement से लिया गया मान टाइप करने के लिए प्रयोग किया जाता है:
ResolveUsing<XElementResolver<ulong>>()
मेरी मानचित्रण पूरी तरह से विन्यस्त और instantiated साथ
, मैं आह्वान करने के लिए तैयार हूँ उस नवीनतम सार्वजनिक टाइमलाइन को प्रदर्शित करने के लिए ट्विटर एपीआई और लीवरेज ऑटोमैपर।
- टुकड़े लाना एक साथ
मैं एक साधारण वर्ग ट्विटर एपीआई प्रतिक्रिया पुन: प्राप्त करने के लिए जिम्मेदार बनाया:
public class TwitterTimelineRetriever
{
private readonly XDocument _twitterTimelineXml;
public TwitterTimelineRetriever()
{
_twitterTimelineXml = XDocument
.Load("http://api.twitter.com/1/statuses/public_timeline.xml");
}
public IEnumerable<ITweetContract> GetPublicTimeline(int numberOfTweets)
{
var tweets = _twitterTimelineXml.Descendants("status")
.Take(numberOfTweets);
return tweets.Select(Mapper.Map<XElement, ITweetContract>).ToList();
}
}
GetPublicTimeline विधि एक सरल तरीका है लौटने पर, आपने अनुमान लगाया है कि हमने पहले बनाए गए मानचित्र का लाभ उठाकर ट्विटर पब्लिक टाइमलाइन:
return tweets.Select(Mapper.Map<XElement, ITweetContract>).ToList();
मेरी MVC3 साइट की HomeController में मैं पुनः प्राप्ति विधि के लिए एक त्वरित कॉल कर सकते हैं, पिछले 10 परिणाम का अनुरोध:
public class HomeController : Controller
{
private TwitterTimelineRetriever _twitterTimelineRetriever;
public ActionResult Index()
{
_twitterTimelineRetriever = new TwitterTimelineRetriever();
ViewModel.Message = "Twitter Public Timeline";
return View(_twitterTimelineRetriever.GetPublicTimeline(10));
}
}
और अंत में, Microsoft से नए उस्तरा दृश्य इंजन का उपयोग कर मेरी दृश्य में एक छोटे से स्वरूपण के बाद, मैं मेरी सार्वजनिक टाइमलाइन प्रदर्शित हो रही है!
ऑटोमैपर का उपयोग इस तरह के "ऑटो" का उपयोग कैसे कर रहा है, फिर मैन्युअल रूप से पीओसीओ में एक्सएमएल का उपयोग कर रहा है? – user2864740