2012-04-07 9 views
9

के बिना डब्ल्यूसीएफ सेवा का उपभोग कैसे करें देशी कोड में मोनोटouch संकलन करें, इसलिए इसमें कुछ सीमाएं हैं जैसे गतिशील चालान की अनुमति नहीं है।मोनोटच/डब्ल्यूसीएफ: svcutil

लेकिन मेरे पास .NET में बहुत कक्षा है, कि मैं wcf सेवा का आह्वान करने के लिए चैनलफैक्टरी गतिशील का उपयोग करता हूं: नया चैनलफैक्टरी (myBinding, myEndpoint); अब मोनोचच में मुझे डब्ल्यूसीएफ प्रॉक्सी क्लास उत्पन्न करने के लिए स्लस्वाकिल का उपयोग करना चाहिए, लेकिन स्लस्वाकिल क्लाइंटबेस क्लास के माध्यम से डब्ल्यूसीएफ इंफ्रास्ट्रक्चर के साथ उच्च युग्मन के कारण यूनिट परीक्षण के लिए बहुत अनावश्यक अतिरिक्त कोड (विशाल) उत्पन्न करता है, और उपभोक्ताओं को यूनिट परीक्षण के लिए मुश्किल बनाता है।

क्या चैनलफ़ैक्टरी को छोड़कर कोई बेहतर समाधान है? मैं मैन्युअल रूप से कोड लिखूंगा, चैनलफैक्टरी जैसे सेवाओं को कैसे लागू किया जाए, इस पर अधिक नियंत्रण रखें।

==========

 ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>(binding, endpointAddress); 
     return factory.CreateChannel(); 

// ==> यह फेंक अपवाद: MonoTouch गतिशील प्रॉक्सी कोड पीढ़ी का समर्थन नहीं करता। इस विधि या उसके फोन करने वाले ओवरराइड विशिष्ट ग्राहक प्रॉक्सी उदाहरण वापस जाने के लिए

उत्तर

13

ChannelFactory<T> में वर्चुअल विधि CreateChannel() है। यदि यह ओवरराइड नहीं है, तो यह गतिशील कोड पीढ़ी का उपयोग करता है, जो मोनो टच पर विफल रहता है।

समाधान इसे ओवरराइड करना और अपना स्वयं का संकलन-समय कार्यान्वयन प्रदान करना है।

नीचे मेरा एक पुराना सेवा कार्यान्वयन है जो कम से कम मोनो टच पर काम करने के लिए उपयोग किया जाता है। मैंने इसे 2 आंशिक कक्षाओं में विभाजित किया - पहला निर्माण सभी बिल्डों में जोड़ा जा रहा है, दूसरा आईओएस बनाता है (गतिशील पीढ़ी तंत्र को अभी भी विंडोज़ पर काम करने की इजाजत देता है)।
मैंने इसे केवल 1 सेवा कॉल में शामिल कर दिया है।

TransactionService.cs:

public partial class TransactionService : ClientBase<IConsumerService>, IConsumerService 
{ 

    public TransactionService() 
    { 
    } 

    public TransactionService(string endpointConfigurationName) : 
     base(endpointConfigurationName) 
    { 
    } 

    public TransactionService(string endpointConfigurationName, string remoteAddress) : 
     base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    public TransactionService(string endpointConfigurationName, EndpointAddress remoteAddress) : 
     base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    public TransactionService(Binding binding, EndpointAddress remoteAddress) : 
     base(binding, remoteAddress) 
    { 
    } 

    public AccountBalanceResponse GetAccountBalance(AccountBalanceQuery query) 
    { 
     return Channel.GetAccountBalance(query); 
    } 
} 

TransactionService.iOS.cs: ConsumerServiceClientChannel जो प्रतिबिंब के माध्यम से कॉल)

public partial class TransactionService 
{ 
    protected override IConsumerService CreateChannel() 
    { 
     return new ConsumerServiceClientChannel(this); 
    } 

    private class ConsumerServiceClientChannel : ChannelBase<IConsumerService>, IConsumerService 
    { 

     public ConsumerServiceClientChannel(System.ServiceModel.ClientBase<IConsumerService> client) : 
      base(client) 
     { 
     } 

     // Sync version 
     public AccountBalanceResponse GetAccountBalance(AccountBalanceQuery query) 
     { 
      object[] _args = new object[1]; 
      _args[0] = query; 
      return (AccountBalanceResponse)base.Invoke("GetAccountBalance", _args); 
     } 

     // Async version 
     public IAsyncResult BeginGetAccountBalance(AccountBalanceQuery query, AsyncCallback callback, object asyncState) 
     { 
      object[] _args = new object[1]; 
      _args[0] = query; 
      return (IAsyncResult)base.BeginInvoke("GetAccountBalance", _args, callback, asyncState); 
     } 


     public AccountBalanceResponse EndGetAccountBalance(IAsyncResult asyncResult) 
     { 
      object[] _args = new object[0]; 
      return (AccountBalanceResponse)base.EndInvoke("GetAccountBalance", _args, asyncResult); 
     } 

    } 
} 

संपादित करें निष्पादित करता है: मैं बस नवीनतम के साथ इस परीक्षण किया मीट्रिक टन (5.2) - अब मुझे उस अतिरिक्त बॉयलर प्लेट की आवश्यकता नहीं है, जो पहले वहां थी, केवल CreateChannel() ओवरराइड करें। मैंने मिलान करने के लिए नमूना कोड साफ़ कर लिया है।

EDIT2: मैंने एक एसिंक विधि कार्यान्वयन जोड़ा।

+0

आपके साझाकरण के लिए धन्यवाद, मैं इसे आजमाएं। – BlueSky

+0

आपका समाधान सफल है, धन्यवाद। – BlueSky

+0

यहां यह कहता है कि यह क्लास चैनलबेस नहीं ढूंढ सकता है। और मैं नहीं देखता कि मैं इसका उपयोग एसिंक्रोनस विधियों के साथ कैसे कर सकता हूं। धन्यवाद! – cheeesus

0

मुझे लगता है कि तुम यहाँ भ्रमित पद हो सकते हैं - ChannelFactory एक सामान्य प्रकार, नहीं एक गतिशील है।

मोनो टच दस्तावेज के अनुसार, हालांकि limitations to the Generics support in MonoTouch है, हालांकि चैनलफैक्टरी ठीक होना चाहिए।

क्या आपने चैनलफैक्टरी का उपयोग करने का प्रयास किया है?

+0

हां, मैंने चैनलफैक्टरी का उपयोग करने की कोशिश की, मैंने उपरोक्त कोड पोस्ट किया है, धन्यवाद, धन्यवाद। – BlueSky

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