Running WCF ServiceHost with multiple contracts

Running ServiceHost with one contract works like this:

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

Now I would like to add a second (third, fourth, ...) contract. My first assumption was to simply add more endpoints, for example:

 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(); 

But of course, this will not work, since when creating the ServiceHost I can either pass MyService1 as a parameter or MyService2 - so I can add many endpoints to my service, but everyone should use the same contract, since I only can provide one implementation?
I feel like I'm missing the point. Of course, there must be some way to ensure implementation for each final contract, the contract that I add, or not?

+48
wcf self-hosting
Dec 02 '08 at 16:04
source share
8 answers

You need to implement both services (interfaces) in one class.

 servicehost = new ServiceHost(typeof(WcfEntryPoint)); servicehost.Open(); public class WcfEntryPoint : IMyService1, IMyService2 { #region IMyService1 #endregion #region IMyService2 #endregion } 



FYI: I often use partial classes to make it easier to read host class code:

 // WcfEntryPoint.IMyService1.cs public partial class WcfEntryPoint : IMyService1 { // IMyService1 methods } // WcfEntryPoint.IMyService2.cs public partial class WcfEntryPoint : IMyService2 { // IMyService2 methods } 
+55
Dec 02 '08 at 16:22
source share

I am currently facing the same problem and decided to move on to the implementation below. I'm not sure if there are any performance issues with this large number of service contracts, but in my last implementation I will probably have about 10-15 service contracts, thus about 10-15 ServiceHosts.

I host all my WCF services inside a single Windows service.

 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); } } 

Do not forget to comment on this type of tuning and, if there are any problems with it, especially related to performance.

+17
Aug 17 '09 at 16:39
source share

This answer is an additional response to the comment in the accepted answer from chilltemp.

Sam, you really need to determine why you need 10-50 contracts and try to find another solution. I looked at the WCW Juval Lowy coding standards (found at http://www.idesign.net/ ) and found the following links:

3 Service Contracts ... 4. Avoid Single Member Contracts. 5. Strive to have three to five members per service contract. 6. You have no more than twenty members per service contract. Probably twelve is a practical limit.

He does not mention the restrictions on the implementation of contracts (which I can find), but I cannot imagine that he considers 50 service contracts as something similar to best practice. One solution that I found that works well is to use membership access for similar features.

For example, if you use the WCF service to do the math with 2 values, you can have 4 members on the service side: Add (x, y), Subtract (x, y), Multiply (x, y), Divide (x, y ) If you combine them into a more general member and use the object to transfer the necessary data, you can easily reduce the number of members and increase scalability. Example: PeformCalculation (obj), where obj has properties x, y and action (addition, subtraction, multiplication, division).

Hope this helps.

+10
Dec 03 '08 at 17:37
source share

I found another solution for this problem using the RoutingService class. Each contract should be placed on it by ServiceHost , but maybe a RoutingService sits on top of all of them - and represents them at a single "endpoint". I also wrote an article on a code project about this. Sample code is also available on Bitbucket .

+8
Feb 29 2018-12-29T00:
source share

The answer to chili will work if you agree to the contracts shared by the service. If you want them separated, try the following:

 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 } 

Edit: as Matt sent, this will require multiple endpoints for each service / contract

+6
Dec 02 '08 at 16:44
source share

How about splitting it with a base address and several services / contracts below? I am not currently developing a machine, but something like:

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

Each service implements its own ServiceContract.

You can change the public class WcfEntryPoint : IMyService1, IMyService2
for image public partial class WcfEntryPoint : IMyService1
public partial class WcfEntryPoint : IMyService2

Example

+1
Aug 19 '09 at 9:49
source share

No one has registered enpoints. You used more than one (as a group, from a common URL, such as http), you must use the same instance of the binding (no more), i.e.

Your sample:

 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(); 

there should be only one new Binding () that I tested on 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(); 

I completely agree with the partial class that implements several contracts in several files.

+1
Sep 19 '15 at 8:05
source share

Am I missing something or is this the easiest solution not mentioned here? The simplest solution is this: do not use multiple interfaces for the web service.

But this does not mean that you can still share your interfaces. That is why we have interface inheritance.

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

The Meta interface inherits all other interfaces.

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

Then the service has only the Meta interface.

 public class SomeObjectService : IMetaSomeObjectService { public List<SomeOject> GetSomeObjects() { // code here } public void DoSomethingElse() { // code here } } 
0
Jun 15 '16 at 16:38
source share



All Articles