2012-04-10 15 views
6

मैंने तीन असेंबली बनाई हैं। एक वेबसाइट, एक डब्ल्यूसीएफ सेवा और एक अनुबंध असेंबली जो सेवाओं को लागू करने वाले इंटरफेस रखती है। मैं क्लाइंट (वेबसाइट) पर मेरे लिए सेवाएं बनाने के लिए कैसल विंडसर का उपयोग करना चाहता हूं ताकि मुझे प्रत्येक सेवा के लिए वेब साइट के web.config में अंतराल न हो।क्लाइंट एंडपॉइंट्स बनाने के लिए कैसल विंडसर WcfFacility का उपयोग

मैं अनुबंध असेंबली को देखना चाहता हूं और नामस्थान में सभी सेवा इंटरफेस प्राप्त करना चाहता हूं। कंटेनर के साथ घटकों को पंजीकृत करते समय अभी प्रत्येक सेवा के लिए मेरे पास कुछ ऐसा है।

container.Register(Component.For<ChannelFactory<IMyService>>().DependsOn(new { endpointConfigurationName = "MyServiceEndpoint" }).LifeStyle.Singleton); 
container.Register(Component.For<IMyService>().UsingFactoryMethod((kernel, creationContext) => kernel.Resolve<ChannelFactory<IMyService>>().CreateChannel()).LifeStyle.PerWebRequest); 

और मेरे web.config में मेरे पास सेटअप कोड है।

<system.serviceModel> 
     <extensions> 
     <behaviorExtensions> 
      <add name="AuthToken" type="MyNamespace.Infrastructure.AuthTokenBehavior, MyNamespace.Contracts" /> 
     </behaviorExtensions> 
     </extensions> 
     <behaviors> 
     <endpointBehaviors> 
      <behavior> 
       <AuthToken /> 
      </behavior> 
     </endpointBehaviors> 
     </behaviors> 

     <bindings> 
     <wsHttpBinding> 
      <binding maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"> 
       <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"></readerQuotas> 
       <security mode="None" /> 
      </binding> 
     </wsHttpBinding> 
     </bindings> 

     <client> 
     <endpoint name="MyServiceEndpoint" address="http://someurl/MyService.svc" binding="wsHttpBinding" contract="MyNamespace.Contracts.IMyService"></endpoint> 
     </client> 
    </system.serviceModel> 

मैं कई सेवा अंतिमबिंदुओं कि सभी लगभग बिल्कुल एक जैसे दिखाई और जब हम ग्राहकों मशीनों पर तैनात वे हर endpoint की पता सेट करने के भले ही आधार यूआरएल हर एक के लिए एक ही है साथ खत्म।

मैं अपने वेब.कॉन्फिग में आधार यूआरएल रखना चाहता हूं जो कोड के माध्यम से पकड़ा जाता है और उसके बाद ठेके असेंबली पर प्रतिबिंब का उपयोग करके कंटेनर के साथ पंजीकृत सेवाएं होती हैं। मुझे उपरोक्त कॉन्फ़िगरेशन फ़ाइल में विशिष्ट एंडपॉइंट व्यवहार की आवश्यकता है।

जहां से मैं शुरू करता हूं? WcfFacility बहुत अच्छा लग रहा है लेकिन डॉको की कमी है ...

उत्तर

12

मैं सहमत हूं कि डब्ल्यूसीएफ सुविधा के लिए दस्तावेज़ों की कमी है और यह दुखद है क्योंकि यह वास्तव में एक महान उपकरण है और यह वास्तविक शर्म की बात होगी अगर लोग ' टी इसका इस्तेमाल करते हैं क्योंकि वे आरंभ नहीं कर सकता है, इसलिए यदि मैं अगर मैं कर सकते हैं तुम बाहर एक छोटा सा मदद कर सकते हैं मुझे देखते हैं ...

की है कि एक तीन परियोजना आवेदन बनाएँ:

  1. एक वर्ग साझा अनुबंधों के लिए लाइब्रेरी
  2. एक कंसोल एप्लिकेशन जो सर्वर के रूप में कार्य करता है
  3. एक सांत्वना अनुप्रयोग है कि एक ग्राहक

विचार के रूप में कार्य करता है कि हम जब हम सेवाओं रजिस्टर सेवा के नाम का उपयोग करने के लिए और एक बुनियादी URL साझा करने के लिए सक्षम होना चाहते हैं (मुझे लगता है कि तुम क्या पूछ रहे थे है और यदि नहीं, उम्मीद है कि आप यहां से बाहर निकल सकते हैं)। तो, सबसे पहले, साझा अनुबंध बस इस उस में है (कुछ भी नहीं विशेष, सामान्य WCF किराया):

[ServiceContract] 
public interface IMyService1 
{ 
    [OperationContract] 
    void DoSomething(); 
} 

[ServiceContract] 
public interface IMyService2 
{ 
    [OperationContract] 
    void DoSomethingToo(); 
} 

अब सर्वर कंसोल आवेदन इस तरह दिखता है, हम सबसे पहले सेवा अनुबंध (फिर से कुछ खास नहीं देखते, बस लागू इंटरफेस को लागू करने वाले वर्ग) और फिर उन्हें सभी सेवाओं के रूप में पंजीकृत करें (यहां किसी भी कॉन्फ़िगरेशन फ़ाइल की आवश्यकता नहीं है और विंडसॉर आपको प्रदान करने वाले सभी विकल्पों का उपयोग करके आप सेवाओं का निर्णय लेने के तरीके को बदल सकते हैं - मेरी योजना थोड़ा सीमित है लेकिन यह आपको एक विचार देता है):

namespace Services 
{ 
    public class MyService1 : IMyService1 
    { 
     public void DoSomething() 
     { 
     } 
    } 

    public class MyService2 : IMyService2 
    { 
     public void DoSomethingToo() 
     { 
     } 
    } 
} 

//... In some other namespace... 

class Program 
{ 
    // Console application main 
    static void Main() 
    { 
     // Construct the container, add the facility and then register all 
     // the types in the same namespace as the MyService1 implementation 
     // as WCF services using the name as the URL (so for example 
     // MyService1 would be http://localhost/MyServices/MyService1) and 
     // with the default interface as teh service contract 
     var container = new WindsorContainer();    
     container.AddFacility<WcfFacility>(
      f => f.CloseTimeout = TimeSpan.Zero); 
     container 
      .Register(
       AllTypes 
        .FromThisAssembly() 
        .InSameNamespaceAs<MyService1>() 
        .WithServiceDefaultInterfaces() 
        .Configure(c => 
           c.Named(c.Implementation.Name) 
            .AsWcfService(
             new DefaultServiceModel() 
              .AddEndpoints(WcfEndpoint 
                  .BoundTo(new WSHttpBinding()) 
                  .At(string.Format(
                   "http://localhost/MyServices/{0}", 
                   c.Implementation.Name) 
                  ))))); 

     // Now just wait for a Q before shutting down 
     while (Console.ReadKey().Key != ConsoleKey.Q) 
     { 
     } 
    } 
} 

और यह सर्वर है, अब इन सेवाओं का उपभोग कैसे करें? ठीक है, वास्तव में काफी आसान है, यहाँ है एक ग्राहक सांत्वना आवेदन (यह सिर्फ ठेके वर्ग पुस्तकालय का संदर्भ):

class Program 
{ 
    static void Main() 
    { 
     // Create the container, add the facilty and then use all the 
     // interfaces in the same namespace as IMyService1 in the assembly 
     // that contains the aforementioned namesapce as WCF client proxies 
     IWindsorContainer container = new WindsorContainer(); 

     container.AddFacility<WcfFacility>(
      f => f.CloseTimeout = TimeSpan.Zero); 

     container 
      .Register(
       Types 
        .FromAssemblyContaining<IMyService1>() 
        .InSameNamespaceAs<IMyService1>() 
        .Configure(
         c => c.Named(c.Implementation.Name) 
           .AsWcfClient(new DefaultClientModel 
                { 
                 Endpoint = WcfEndpoint 
                  .BoundTo(new WSHttpBinding()) 
                  .At(string.Format(
                   "http://localhost/MyServices/{0}", 
                   c.Name.Substring(1))) 
                }))); 

     // Now we just resolve them from the container and call an operation 
     // to test it - of course, now they are in the container you can get 
     // hold of them just like any other Castle registered component 
     var service1 = container.Resolve<IMyService1>(); 
     service1.DoSomething(); 

     var service2 = container.Resolve<IMyService2>(); 
     service2.DoSomethingToo(); 
    } 
} 

यह है कि - उम्मीद है कि इस आप आरंभ होगा (मुझे लगता है कि प्रयोग करने और आम तौर पर IntelliSense का उपयोग कर मुझे वह जगह मिलती है जहां मुझे जाना है)।मैंने आपको सेवा और ग्राहक दोनों पक्ष दिखाए हैं लेकिन यदि आप चाहें तो आप केवल एक या दूसरे का उपयोग कर सकते हैं।

आपको यह देखने में सक्षम होना चाहिए कि बाध्यकारी कॉन्फ़िगर किया गया है और मैं यूआरएल बनाने के बारे में कैसे गया हूं, इसलिए आपके मामले में आप आसानी से कॉन्फ़िगरेशन फ़ाइल से अपना बेस यूआरएल निकाल सकते हैं या जो भी आप करना चाहते हैं।

एक आखिरी बात का उल्लेख आप, समाप्ति बिंदु को एक विस्तार के रूप में जोड़कर अपने कस्टम endpoint व्यवहार जोड़ सकते हैं कि इतने ग्राहक उदाहरण में आप कुछ इस तरह होता है:

Endpoint = WcfEndpoint 
    .BoundTo(new WSHttpBinding()) 
    .At(string.Format("http://localhost/MyServices/{0}", c.Name.Substring(1))) 
    .AddExtensions(new AuthTokenBehavior()) 
+0

है कि एक तरह काम करता है आकर्षण, बहुत बहुत धन्यवाद। –

+0

यह क्या करता है? (f => f.CloseTimeout = TimeSpan.Zero) –

+0

यह सभी सेवाओं के लिए डिफ़ॉल्ट क्लोजटाइम सेट करता है - यह "एक टाइमस्पैन मान है जो पूर्ण करने के लिए बंद किए गए ऑपरेशन के लिए प्रदान किए गए समय के अंतराल को निर्दिष्ट करता है। यह मान अधिक से अधिक होना चाहिए या शून्य के बराबर। डिफ़ॉल्ट 00:01:00 है। " - http://msdn.microsoft.com/en-us/library/ms731361.aspx से। यहां एक अच्छा धागा भी है जो सभी संभावित टाइमआउट के बारे में बात करता है: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/84551e45-19a2-4d0d-bcc0-516a4041943d/ – kmp

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