2009-01-12 14 views
11

मुझे कई डब्ल्यूसीएफ सेवाओं वाली एक असेंबली मिली है, प्रत्येक के अपने अनुबंध के साथ। यह सब अच्छी तरह से काम करता है। सेवा के लिए app.config में सेवा config इस तरह दिखता है:क्या कई डब्ल्यूसीएफ सेवाएं एक आम बेस एड्रेस साझा कर सकती हैं?

<services> 
    <service behaviorConfiguration="WcfService.AlyzaServiceBehavior" 
    name="Sam.Alyza.WcfService.ServiceWebsites"> 
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Websites/" /> 
     </baseAddresses> 
    </host> 
    </service> 
    <service behaviorConfiguration="Sam.Alyza.WcfService.LogReaderServiceBehavior" 
    name="Sam.Alyza.WcfService.ServiceLogReader"> 
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/LogReader/" /> 
     </baseAddresses> 
    </host> 
    </service> 
    <service behaviorConfiguration="Sam.Alyza.WcfService.ServiceSystemverwaltungBehavior" 
    name="Sam.Alyza.WcfService.ServiceSystemverwaltung"> 
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Systemverwaltung/" /> 
     </baseAddresses> 
    </host> 
    </service> 
    [...] 
</services> 

के बाद से मेरे मन में एक बड़ा परियोजना है, और अधिक अनुबंध के साथ मिल गया है, मैं के बीच BaseAddress साझा करने के लिए एक तरह से करना चाहते हैं विभिन्न सेवा अनुबंध।
यदि यह अलग-अलग अनुबंधों और अंतराल के साथ एक सेवा होगी, तो मैं एक ओमोन बेसड्रेस सेट कर सकता हूं, लेकिन मैं एक से अधिक सेवा के लिए एक सामान्य बेसड्रेस कैसे सेट करूं?

बेशक मुझे क्लाइंट के लिए कुछ इसी तरह की आवश्यकता होगी।

उत्तर

8

आप एक वर्ग में सभी अनुबंधों को जोड़ सकते हैं, इसलिए आपके पास बेसड्रेस और प्रति अनुबंध (एक) अधिक अंतराल (एस) के साथ एक सेवा है।

एक बड़ी कक्षा-फ़ाइल रखने से बचने के लिए आप कई फाइलों में कक्षा को विभाजित करने के लिए आंशिक-कीवर्ड (जैसे आप सी # का उपयोग करते हैं) का उपयोग कर सकते हैं। प्रत्येक फ़ाइल एक अनुबंध को कार्यान्वित कर सकती है, जो व्यक्तिगत इंटरफेस को अधिक आसान बनाए रखती है।

सी ++ आप #includes या एकाधिक वंशानुक्रम का उपयोग कर सकते हैं, लेकिन वह अनुशासन की एक बड़ी राशि का मतलब है ...

आपका config इस प्रकार दिखाई देगा:

<services> 
    <service behaviorConfiguration="WcfService.AlyzaServiceBehavior" 
    name="Sam.Alyza.WcfService.ServiceAll"> 
    <endpoint address="Websites/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="LogReader/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="Systemverwaltung/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/" /> 
     </baseAddresses> 
    </host> 
    </service> 
</services> 
+0

अच्छा विचार! केवल समस्या यह है कि आंशिक सेवा सभी कक्षाएं बहुत बड़ी और बहुत सी विधियों के साथ बड़ी होंगी। – Sam

+0

यह सही है। फिलहाल मुझे कोड-आधारित तत्कालता पर स्विच करने के अलावा कोई अन्य समाधान नहीं दिखता है। – Lars

2

सेवाएं बेसएड्रेस मूल्यों को साझा कर सकती हैं (पोर्ट # सहित, नेट नेटसीपी पोर्ट शेयरिंग सेवा चल रही है)। यह एंडपॉइंट पते है जो अद्वितीय होना चाहिए। अपनी कॉन्फ़िगरेशन फ़ाइल में नोटिस करें कि प्रत्येक सेवाहोस्ट के लिए MEX एंडपॉइंट्स में "mex" का पता है। आपके अन्य एंडपॉइंट्स में खाली स्ट्रिंग का पता है। जब आप डब्ल्यूसीएफ (कम से कम कॉन्फ़िगरेशन फ़ाइल में) के अंतराल के लिए एक सापेक्ष पता प्रदान करते हैं, तो आधार पता इसके लिए तैयार किया जाता है। इसलिए, LogReader सेवा के लिए MEX एंडपॉइंट पता "net.tcp: // localhost: 8731/Design_Time_Addresses/SamAlyza/LogReader/mex" है।

चूंकि एक सापेक्ष पता मुख्य सेवा एंडपॉइंट पर सेट नहीं किया गया था, इसलिए सर्विसहोस्ट का मूल पता मुख्य सेवा एंडपॉइंट के लिए वास्तविक पता के रूप में उपयोग किया जाता है। चूंकि कोई भी दो अंतराल Uri.AbsolutePath मानों को ओवरलैप नहीं कर सकता है, तो आपका उदाहरण आपको विश्वास दिलाएगा कि आधार पता मान साझा नहीं किए जा सकते हैं। डब्ल्यूसीएफ सेवाओं को होस्ट करने वाली सर्विसहोस्ट क्लास में अंतर्निहित एंडपॉइंट नहीं है, जबकि सर्विसइंडपॉइंट क्लास में एक सुनोउरी प्रॉपर्टी है जो आपके द्वारा प्रदान की जाने वाली सेटिंग्स के आधार पर पॉप्युलेट की जाएगी।

यदि आप सभी उदाहरणों के लिए अपने उदाहरण में बेस एड्रेस मान बदलते हैं, जब तक आप एंडपॉइंट तत्वों पर अद्वितीय सापेक्ष पता मान सेट करते हैं, तो सब कुछ काम करना चाहिए। हालांकि, ऐसा लगता है कि आप एमईएक्स एंडपॉइंट्स के साथ कुछ चुनौतियों में भाग ले सकते हैं, क्योंकि उनके पास वर्तमान में "मेक्सिको" पता है। उन अद्वितीय बनाएं और आपको ठीक होना चाहिए।

अब, मुझे पूछना चाहिए, क्या आप निश्चित हैं कि आप बस इन सेवाओं को आधार पते के बजाय नामस्थान साझा करने के लिए नहीं चाहते हैं?

+0

एक और बिंदु यह होगा कि आधार एड्रेस वर्तमान स्थान से अधिक कुछ नहीं है, इसलिए बोलने के लिए। विचार यह है कि सभी अंतराल आमतौर पर आधार एड्रेस के सापेक्ष होते हैं। इसलिए, यदि आप सभी सेवाओं में समान बेस एड्रेस साझा करने का प्रयास कर रहे हैं, तो आप अपने परिनियोजन विकल्पों को सीमित कर रहे हैं। –

+0

यदि आप कॉन्फ़िगरेशन को आसान बनाने के लिए एक तरीका ढूंढ रहे हैं, तो आपको कॉन्फ़िगरेशन तारों के बजाय कोड का उपयोग करने के लिए स्विच करना होगा। आप प्रोग्रामेटिक रूप से ServiceHost और ServiceEndpoint उदाहरण बना सकते हैं और शायद डेटाबेस से Uri.AbsolutPath मान खींच सकते हैं। –

+0

हां, मैं कॉन्फ़िगरेशन फ़ाइल को बदलने में आसान बनाने का एक तरीका ढूंढ रहा हूं। तो यदि आपके पास इसके बारे में कोई विचार है, तो मैं सभी कान जाऊंगा। – Sam

1

तुम भी आधार सेट कर सकते हैं यदि आप कस्टम सेवाहोस्ट फैक्टरी का उपयोग करते हैं तो कोड में पते।

: आप यह भी कहा कि कारखाने का उपयोग करने के अपने .svc फ़ाइलें बदलना होगा

public sealed class MyServiceHostFactory : ServiceHostFactory 
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
    { 
     var baseAddy = ConfigurationManager.AppSettings["BaseAddress"]; 
     baseAddresses.Add(new Uri(baseAddy)); 
     return new ServiceHost(serviceType, baseAddresses); 
    } 

} 

तब:

<configuration> 
    <appSettings> 
    <add key="BaseAddress" value="http://localhost:1234" /> 
    </appSettings> 
<configuration> 

फिर एक कस्टम ServiceHostFactory बनाने:

config में आप कुछ एप्लिकेशन सेटिंग हो सकता है

<%@ ServiceHost Language="C#" Debug="true" Service="MyApp.MyService" CodeBehind="MyService.svc.cs" Factory="MyApp.MyServiceHostFactory" %>