2008-12-02 7 views
49

एक भी अनुबंध के साथ एक ServiceHost चल रहा है के साथ भागो WCF ServiceHost इस तरह ठीक काम कर रहा है:कई ठेके

servicehost = new ServiceHost(typeof(MyService1)); 
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1"); 
servicehost.Open(); 

अब मैं एक दूसरे (3, 4, ...) अनुबंध जोड़ना चाहते हैं। मेरा पहला अनुमान सिर्फ इस तरह अधिक अंतिमबिंदुओं जोड़ने के लिए होगा:

servicehost = new ServiceHost(typeof(MyService1)); 
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1"); 
servicehost.AddServiceEndpoint(typeof(IMyService2), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService2"); 
servicehost.Open(); 

लेकिन निश्चित रूप से यह काम नहीं करता है, क्योंकि ServiceHost के निर्माण में मैं पैरामीटर के रूप में MyService1 पारित कर सकते हैं या तो या MyService2 - तो मैं एक बहुत जोड़ सकते हैं मेरी सेवा के अंतराल के लिए, लेकिन सभी को एक ही अनुबंध का उपयोग करना है, क्योंकि मैं केवल एक कार्यान्वयन प्रदान कर सकता हूं?
मुझे लगा कि मुझे इस बिंदु को याद आ रहा है, यहां। निश्चित रूप से मेरे द्वारा जोड़े गए प्रत्येक एंडपॉइंट-अनुबंध के लिए कार्यान्वयन प्रदान करने का कोई तरीका होना चाहिए या नहीं?

उत्तर

56

आपको एक ही कक्षा में दोनों सेवाओं (इंटरफेस) को लागू करने की आवश्यकता है।

servicehost = new ServiceHost(typeof(WcfEntryPoint)); 
servicehost.Open(); 

public class WcfEntryPoint : IMyService1, IMyService2 
{ 
    #region IMyService1 
    #endregion 

    #region IMyService2 
    #endregion 
} 

FYI करें: मैं अक्सर बनाने के लिए आंशिक वर्गों का उपयोग अपने मेजबान वर्ग कोड को पढ़ने में आसान: अगर तुम ठीक हो के साथ अनुबंध सेवा के द्वारा साझा किया जा रहा

// WcfEntryPoint.IMyService1.cs 
public partial class WcfEntryPoint : IMyService1 
{ 
    // IMyService1 methods 
} 

// WcfEntryPoint.IMyService2.cs 
public partial class WcfEntryPoint : IMyService2 
{ 
    // IMyService2 methods 
} 
+9

डांग।मुझे केवल 2 सेवा अनुबंधों की आवश्यकता है, मुझे लगता है कि 10-50, और उस संख्या के लिए यह दृष्टिकोण थोड़ा बोझिल है - यह एक ही कक्षा में सभी प्रविष्टि बिंदुओं के लिए बहुत उपयोगी नहीं है :( क्या कोई अन्य नहीं है रास्ता? – Sam

+0

मेरा समाधान आपको विभिन्न वर्गों में अनुबंधों को तोड़ने की अनुमति देगा। आप अपने समाधान को ठंड के साथ जोड़ सकते हैं ताकि 5 कक्षाएं हों, प्रत्येक 2 अंत बिंदुओं के साथ। मैं बहुत उत्सुक हूं हालांकि आपको 50 अनुबंधों की आवश्यकता क्यों है। http://www.idesign.net/ पर 0 जुवाल के सर्वोत्तम प्रथाओं को देखें। –

+1

मैं क्रिस की दूसरी टिप्पणी करूंगा। ऐसा लगता है कि आपको अपने डिज़ाइन को सरल बनाना होगा। – chilltemp

6

मिर्च का जवाब काम करेंगे । यदि आप चाहते हैं उन्हें अलग किया जा करने के लिए इस प्रयास करें:

host1 = new ServiceHost(typeof(MyService1)); 
host2 = new ServiceHost(typeof(MyService2)); 

host1.Open(); 
host2.Open(); 

public class MyService1 : IMyService1 
{ 
    #region IMyService1 
    #endregion 
} 

public class MyService2 : IMyService2 
{ 
    #region IMyService2 
    #endregion 
} 

संपादित करें: के रूप में मैट पोस्ट, इसे एक से अधिक अंतिमबिंदुओं प्रत्येक सेवा/अनुबंध

+0

यह सही है। यह वही है जब मैं इस धागे को पढ़ना शुरू कर रहा था। शुरू में मैंने सोचा था कि यह असंभव रूप से इस धागे की गड़बड़ी से तय होगा, लेकिन यह ठीक काम करता है। –

10

इस उत्तर को स्वीकार कर लिया जवाब में टिप्पणी के लिए एक और प्रतिक्रिया है के लिए की आवश्यकता होगी chilltemp से।

सैम, आपको वास्तव में यह निर्धारित करना चाहिए कि आपको 10-50 अनुबंधों की आवश्यकता क्यों है और दूसरा समाधान खोजने का प्रयास करें। मैं युवल लोवी के WCF कोडिंग मानक (http://www.idesign.net/ पर होता है) के ऊपर देखा और निम्नलिखित संदर्भ मिले:

3 सेवा संविदा ... 4. एक सदस्य के साथ बचें अनुबंध। 5. सेवा अनुबंध प्रति तीन से पांच सदस्यों के लिए प्रयास करें। 6. प्रति सेवा अनुबंध के बीस से अधिक सदस्य नहीं हैं। बारह शायद व्यावहारिक सीमा है।

वह अनुबंध कार्यान्वयन (जो मुझे मिल सकता है) पर एक सीमा का उल्लेख नहीं करता है, लेकिन मैं कल्पना नहीं कर सकता कि वह सेवा पर 50 अनुबंधों को सर्वोत्तम अभ्यास जैसा दिखता है। एक समाधान मैंने पाया है कि समान कार्यों के लिए सदस्य साझाकरण का उपयोग करना अच्छी तरह से काम करता है।

उदाहरण के लिए, यदि आप दो मूल्यों पर गणित करने के लिए डब्ल्यूसीएफ सेवा का उपयोग कर रहे हैं तो आपके पास सेवा पक्ष पर 4 सदस्य हो सकते हैं: जोड़ें (एक्स, वाई), घटाएं (एक्स, वाई), गुणा (एक्स, वाई) , विभाजन (एक्स, वाई)। यदि आप इन्हें अधिक सामान्य सदस्य में जोड़ते हैं और आवश्यक डेटा को पास करने के लिए किसी ऑब्जेक्ट का उपयोग करते हैं तो आप आसानी से अपने सदस्य की गिनती को कम कर सकते हैं और स्केलेबिलिटी बढ़ा सकते हैं। उदाहरण: PeformCalculation (obj) जहां ओबीजे में एक्स, वाई, और एक्शन (जोड़, घटाएं, गुणा करें, विभाजित करें) गुण हैं।

उम्मीद है कि इससे मदद मिलती है।

+0

जुवाल अनुबंध पर 3-5 सदस्यों के बारे में बात कर रहा है। मैं एक सेवा के लिए 10-50 अनुबंधों के बारे में बात कर रहा हूं (प्रत्येक अनुबंध में 3-5 सदस्य हैं)। शायद भ्रम पैदा कर रहा है? – Sam

+1

यह भ्रम नहीं है, वह अनुबंधों पर एक सीमा का उल्लेख नहीं करता है लेकिन मैं सेवा पर 50 अनुबंध होने की सड़क पर नहीं जाना चाहता हूं। कुछ प्रकार का रिफैक्टरिंग होना चाहिए जो आपके अनुबंधों पर आकार/गिनती को कम करने के लिए किया जा सकता है। यह आपका ऐप है लेकिन मैं अन्य विकल्पों की तलाश करूंगा। –

17

मुझे वर्तमान में एक ही समस्या का सामना करना पड़ रहा है, और नीचे दिए गए कार्यान्वयन के साथ जाने का फैसला किया है।मुझे यकीन नहीं है कि क्या इस सेवा के अनुबंध के साथ कोई प्रदर्शन समस्या है, लेकिन मेरे अंतिम कार्यान्वयन में शायद मेरे पास लगभग 10-15 सेवा अनुबंध होंगे, इस प्रकार लगभग 10-15 सर्विसहोस्ट।

मैं एक ही विंडोज सेवा के अंदर अपनी सभी डब्ल्यूसीएफ सेवाओं की मेजबानी कर रहा हूं।

private void PublishWcfEndpoints() 
{ 
    var mappings = new Dictionary<Type, Type> 
    { 
     {typeof (IAuthenticationService), typeof (AuthenticationService)}, 
     {typeof(IUserService), typeof(UserService)}, 
     {typeof(IClientService), typeof(ClientService)} 
    }; 


    foreach (var type in mappings) 
    { 
     Type contractType = type.Key; 
     Type implementationType = type.Value; 

     ServiceHost serviceHost = new ServiceHost(implementationType); 
     ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(contractType, ServiceHelper.GetDefaultBinding(), 
                    Properties.Settings.Default.ServiceUrl + "/" + contractType.Name); 
     endpoint.Behaviors.Add(new ServerSessionBehavior()); 

     ServiceDebugBehavior serviceDebugBehaviour = 
      serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>(); 
     serviceDebugBehaviour.IncludeExceptionDetailInFaults = true; 

     log.DebugFormat("Published Service endpoint: {0}", Properties.Settings.Default.ServiceUrl); 

     serviceHost.Open(); 
     serviceHosts.Add(serviceHost); 
    } 

} 

इस प्रकार के सेट अप पर टिप्पणी करने के लिए स्वतंत्र महसूस करें, और यदि इसके साथ कोई समस्या है, खासकर प्रदर्शन से संबंधित।

+0

यहां जटिल है –

+0

यदि आप कार्यान्वयन को हल करने के लिए निर्भरता इंजेक्शन कंटेनर का उपयोग करते हैं तो बेहतर होगा =) – Th3B0Y

+0

सर्वोत्तम समाधान को अलग करने और व्यक्तिगत रूप से जिम्मेदार होने की अनुमति देने के लिए, – bvj

1

इसे आधार पते और इसके नीचे कई सेवाओं/अनुबंधों के साथ विभाजित करने के बारे में क्या है? मैं अभी एक developmachine पीछे नहीं हूँ, लेकिन कुछ की तरह:

http://myserver/myservices/serviceA
http://myserver/myservices/serviceB
http://myserver/myservices/serviceC

प्रत्येक सेवा के लिए अपने स्वयं ServiceContract को लागू करने।

आप
public class WcfEntryPoint : IMyService1, IMyService2

public partial class WcfEntryPoint : IMyService1

Example

8

को public partial class WcfEntryPoint : IMyService2 मैं एक RoutingService वर्ग का उपयोग करके इस समस्या के लिए करने के लिए एक और समाधान पाया बदल सकते हैं। प्रत्येक अनुबंध को अभी भी अपने ServiceHost में होस्ट किया जाना चाहिए, लेकिन उनमें से सभी के शीर्ष पर बैठे RoutingService हो सकते हैं - और उन्हें एक एकीकृत "एंडपॉइंट" पर प्रस्तुत किया जा सकता है। मैंने इसके बारे में codeproject article भी लिखा है। उदाहरण कोड Bitbucket पर भी उपलब्ध है।

1

कोई भी दस्तावेज एनपॉइंट्स नहीं है। Whe एक से अधिक प्रयोग किया जाता है (एक समूह, आम यूआरएल, उदाहरण के लिए http के लिए से के रूप में) एक ही बंधन उदाहरण (अधिक नहीं), यानी उपयोग करना चाहिए

आपका नमूना:

servicehost = new ServiceHost(typeof(MyService1)); 
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1"); 
servicehost.AddServiceEndpoint(typeof(IMyService2), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService2"); 
servicehost.Open(); 

केवल एक नए बाध्यकारी होना चाहिए(), मैंने http पर परीक्षण किया।

servicehost = new ServiceHost(typeof(MyService1)); 
BasicHttpBinding binding = new BasicHttpBinding(); 
servicehost.AddServiceEndpoint(typeof(IMyService1),binding , "http://127.0.0.1:800/MyApp/MyService1"); 
servicehost.AddServiceEndpoint(typeof(IMyService2), binding, "http://127.0.0.1:800/MyApp/MyService2"); 
servicehost.Open(); 

मैं कुछ फाइलों में कुछ अनुबंधों को लागू करने वाले आंशिक वर्ग के साथ पूरी तरह सहमत हूं।

0

क्या मुझे कुछ याद आया, या यहां सबसे सरल समाधान का उल्लेख नहीं किया गया है? सबसे सरल समाधान यह है: वेब सेवा के लिए एकाधिक इंटरफेस का उपयोग न करें।

लेकिन इसका मतलब यह नहीं है कि आप अभी भी अपने इंटरफेस को अलग कर सकते हैं। यही कारण है कि हमारे पास इंटरफेस विरासत है।

[ServiceContract] 
public interface IMetaSomeObjectService : ISomeObjectService1, ISomeObjectService2 
{ 
} 

मेटा इंटरफ़ेस अन्य सभी इंटरफेस से विरासत में आता है।

[ServiceContract] 
public interface ISomeOjectService1 
{ 
    [OperationContract] 
    List<SomeOject> GetSomeObjects(); 
} 

[ServiceContract] 
public interface ISomeOjectService2 
{ 
    [OperationContract] 
    void DoSomethingElse(); 
} 

तब सेवा में मेटा इंटरफ़ेस है।

public class SomeObjectService : IMetaSomeObjectService 
{ 
    public List<SomeOject> GetSomeObjects() 
    { 
     // code here 
    } 

    public void DoSomethingElse() 
    { 
     // code here 
    } 
} 
संबंधित मुद्दे