2009-07-06 6 views
12

मैं svcutil.exe के बिना क्लाइंट प्रॉक्सी कैसे बना सकता हूं या wcf में सेवा संदर्भ जोड़ सकता हूं? मैं संकलन समय पर एक क्लाइंट प्रॉक्सी बनाना चाहता हूं।svcutil के बिना क्लाइंट प्रॉक्सी कैसे बनाएं या wcf में सेवा संदर्भ जोड़ें?

+2

क्या आपको इसे रनटाइम, या संकलन समय पर, या आईडीई में बनाने की आवश्यकता है? क्या आप कह सकते हैं कि आप क्या करने की कोशिश कर रहे हैं? अन्यथा आपको ऐसे उत्तर मिलेंगे जो आपके लक्ष्यों को पूरा नहीं करेंगे। –

+1

क्या आप पहले से अनुबंध जानते हैं? यानी आपके पास शायद सेवा इंटरफ़ेस कोड के रूप में है? –

+3

मुझे पागल कहो, लेकिन आप एक बक्षीस क्यों लगाएंगे और फिर सवालों का जवाब देने में विफल रहेगा? मुझे संदेह है कि यदि आप लोगों की मदद करने में आपकी मदद करते हैं तो आप एसओ से अधिक प्राप्त करेंगे ... वे सवाल पूछ रहे हैं क्योंकि उचित उत्तर देने के लिए यह महत्वपूर्ण है। –

उत्तर

10

तो आपको एक अलग DLL में सेवा अनुबंध (IService इंटरफेस) की पहुंच है, तो आप उस सेवा अनुबंध DLL के लिए एक संदर्भ जोड़ सकते हैं और उसके बाद की तरह कुछ कार्य करें:

NetTcpBinding binding = new NetTcpBinding(); 
EndpointAddress address = new EndpointAddress("net.tcp://localhost:9000/YourService") 

ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, address); 
IService proxy = factory.CreateChannel(); 

और फिर आप अपने राशि प्रोग्रामेटिक रूप से बनाई गई प्रॉक्सी, जिसे आप अब अपनी इच्छानुसार उपयोग कर सकते हैं।

+0

क्या 'चैनलफैक्टरी' को हर बार एक नई 'बाध्यकारी' वस्तु की आवश्यकता होती है? या एक बार बाध्यकारी और एंडपॉइंट पता बनाने के लिए ठीक होना चाहिए, और 'चैनलफैक्टरी' बनाने के लिए उनका उपयोग करना चाहिए? – epalm

+0

@ एपल्म: आप निश्चित रूप से बाध्यकारी और एंडपॉइंट ऑब्जेक्ट्स को चारों ओर रख सकते हैं और उन्हें कई बार उपयोग कर सकते हैं - कोई समस्या नहीं। –

5

आपको जेनरेट करने की आवश्यकता नहीं है (या डब्ल्यूसीएफ विनिर्देशों से भरे कॉन्फ़िगरेशन फ़ाइल का उपयोग करें)।

पहले सेवा कार्यान्वयन से अलग असेंबली में किसी भी सहायक डेटा अनुबंध के साथ सेवा ([ServiceContract]) को परिभाषित करने वाला इंटरफ़ेस बनाएं।

क्लाइंट असेंबली में इंटरफ़ेस असेंबली का संदर्भ लें।

फिर IMyService के लिए, एक ग्राहक प्रॉक्सी बनाने की जरूरत:

BasicHttpBinding binding = new BasicHttpBinding(); 
EndpointAddress endpoint = new EndpointAddress(url); 
ChannelFactory<IMyService> chanFac = new ChannelFactory<IMyService>(binding, endpoint); 
IMyService clientProxy = chanFac.CreateChannel(); 
+1

एक ऐसे समाधान की तरह लगता है जो मैं अपनी वेब सेवाओं में से किसी एक में उपयोग करता हूं। :-) –

7

यह नहीं हो सकता है कि आप क्या ढूंढ रहे हैं, लेकिन यह बहुत दिलचस्प है।

विपुल मोदी की एक पुस्तकालय है जो आपको अपने डब्लूएसडीएल को चलाने के बाद डब्लूसीएफ सेवाओं को कॉल करने की अनुमति देती है, सभी रनटाइम पर।

ProxyFactory सेवा के डबल्यूएसडीएल यूआरआई को निर्दिष्ट बनाएँ:

Vipul Modi's library (latest version)

आप बात इस तरह का करने के लिए अनुमति देता है।

DynamicProxyFactory factory = new DynamicProxyFactory("http://localhost:8080/WcfSamples/DynamicProxy?wsdl"); 

ब्राउज अंतिमबिंदुओं, मेटाडाटा, अनुबंध आदि

  • factory.Endpoints
  • factory.Metadata
  • factory.Contracts
  • factory.Bindings

एंडपॉइंट या अनुबंध नाम निर्दिष्ट करके एंड्रॉइड पर डायनामिक प्रॉक्सी बनाएं।

DynamicProxy proxy = factory.CreateProxy("ISimpleCalculator"); 

// या

DynamicProxy proxy = factory.CreateProxy(endpoint); 

DynamicProxy पर आह्वान संचालन

double result = (double)proxy.CallMethod("Add", 1d ,2d); 

DynamicProxy

proxy.Close(); 
बंद एक बुनियादी सुविधाओं के विधानसभा में:
+0

वास्तव में बहुत अच्छा है! – grenade

0

यहाँ समाधान मैं उपयोग कर रहा है WCF के बाद से शुरू किया गया था

:

internal class PerCallDisposeRealProxy<T> : RealProxy where T : class 
{ 
    private readonly Binding _binding; 
    private readonly EndpointAddress _endpointAddress; 

    private static string EndpointName 
    { 
     get 
     { 
      string endpointName = typeof(T).Name; 
      if (endpointName.StartsWith("I")) 
      { 
       endpointName = endpointName.Substring(1); 
      } 
      return endpointName; 
     } 
    } 

    internal PerCallDisposeRealProxy() 
     : base(typeof(T)) 
    {    
    } 

    internal PerCallDisposeRealProxy(Binding binding, EndpointAddress endpointAddress) 
     : base(typeof(T)) 
    { 
     if (binding == null) 
      throw new ArgumentNullException("binding"); 
     if (endpointAddress == null) 
      throw new ArgumentNullException("endpointAddress"); 

     _binding = binding; 
     _endpointAddress = endpointAddress; 
    } 

    private ChannelFactory<T> CreateChannel() 
    { 
     if (_binding != null && _endpointAddress != null) 
      return new ChannelFactory<T>(_binding, _endpointAddress); 
     else 
      return new ChannelFactory<T>(EndpointName); 
    } 

    [DebuggerStepThrough] 
    public override IMessage Invoke(IMessage message) 
    { 
     if (message == null) throw new ArgumentNullException("message"); 

     //Extract method info 
     var methodCall = message as IMethodCallMessage; 
     Debug.Assert(methodCall != null); 
     MethodInfo methodInfo = methodCall.MethodBase as MethodInfo; 
     Debug.Assert(methodInfo != null); 

     T channel = null; 
     ChannelFactory<T> channelFactory = null; 
     try 
     { 
      //setup channel 
      try 
      { 
       channelFactory = CreateChannel(); 
      } 
      catch (InvalidOperationException ex) 
      { 
       throw new ApplicationException(string.Format("Invalid endpoint configuration, make sure there is a servicemodel endpoint defined in configuration with the name {0}", EndpointName), ex); 
      } 
      channelFactory.Open(); 
      channel = channelFactory.CreateChannel(); 

      object result = methodInfo.Invoke(channel, methodCall.InArgs); 
      return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall); 
     } 
     catch (FaultException faultException) 
     { 
      string msg = "FaultException: " + faultException.Message; 
      MessageFault fault = faultException.CreateMessageFault(); 
      if (fault.HasDetail) 
      { 
       System.Xml.XmlReader reader = fault.GetReaderAtDetailContents(); 
       if (reader.Name == "ExceptionDetail") 
       { 
        ExceptionDetail detail = fault.GetDetail<ExceptionDetail>(); 
        msg += "\n\nStack Trace: " + detail.StackTrace; 
       } 
      } 
      return new ReturnMessage(faultException, methodCall); 
     } 
     catch (TargetInvocationException targetInvocationException) 
     { 
      return targetInvocationException.InnerException != null ? new ReturnMessage(targetInvocationException.InnerException, methodCall) : new ReturnMessage(targetInvocationException, methodCall); 
     } 
     catch (Exception exception) 
     { 
      return new ReturnMessage(exception, methodCall); 
     } 
     finally 
     { 
      if (channel as IClientChannel != null) 
      { 
       try 
       { 
        (channel as IClientChannel).Close(TimeSpan.FromSeconds(5)); 
       } 
       catch 
       { 
        try 
        { 
         (channel as IClientChannel).Abort(); 
        } 
        catch 
        { 
        } 
       } 
       try 
       { 
        (channel as IClientChannel).Dispose(); 
       } 
       catch 
       { 
       } 
      } 

      try 
      { 
       ((IDisposable)channelFactory).Dispose(); 
      } 
      catch 
      { 
      } 
     } 
    } 
} 

    public static class ClientProxyFactory 
{ 
    public static T CreateProxy<T>() where T : class 
    { 
     return CreateProxy<T>(ProxyType.PerCallChannel); 
    } 

    public static T CreateProxy<T>(ProxyType proxyType) where T : class 
    { 
     return CreateProxy<T>(proxyType, null, null); 
    } 

    public static T CreateProxy<T>(ProxyType proxyType, Binding binding, EndpointAddress endpointAddress) where T : class 
    { 
     switch (proxyType) 
     { 
      case ProxyType.PerCallChannel: 
       PerCallDisposeRealProxy<T> proxy = null; 
       proxy = binding == null && endpointAddress == null ? new PerCallDisposeRealProxy<T>() : new PerCallDisposeRealProxy<T>(binding, endpointAddress); 
       Debug.Assert(proxy != null); 
       object transparentProxy = proxy.GetTransparentProxy(); 
       Debug.Assert(transparentProxy != null); 
       Debug.Assert(transparentProxy is T); 
       return transparentProxy as T; 
      default: 
       throw new NotImplementedException("Did not implement proxytype:" + proxyType); 
     } 
    } 
} 

    public enum ProxyType 
{ 
    /// <summary> 
    /// PerCall indicates a proxy that will create a channel pr. proxy method call and dispose of it before returning. 
    /// </summary> 
    PerCallChannel 
} 

और कॉल साइट (सेवा एजेंट में या आप से बाह्य सेवा कॉल करना चाहते हैं जहाँ

INumeralConverterService proxy = ClientProxyFactory.CreateProxy<INumeralConverterService>(); 
string result = proxy.DecimalToRoman(i); 

ServiceContract (और datacontracts) को देखते हुए अभी तक एक और asssembly, यहाँ बस में परिभाषित:

[ServiceContract] 
public interface INumeralConverterService 
{ 
    [OperationContract] 
    Decimal RomanToDecimal(string roman); 

    [OperationContract] 
    string DecimalToRoman(Decimal @decimal); 
} 
संबंधित मुद्दे