How to programmatically establish a single endpoint for a WCF service

I am trying to enable customization of a WCF service, including the IP number and port number that the service is listening on. The user has a separate configuration application that allows you to set these values, but the problem I am facing is that app.config MUST have an endpoint defined to create a new ServiceHost entry ... but my endpoint is defined in a separate configuration file and then must be bound programmatically at run time.

If I do the following (based on How to programmatically change the WCF endpoint address setting app.config?:

m_SvcHost = new ServiceHost(this); if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty) { m_SvcHost.AddServiceEndpoint(typeof(IMyService), new BasicHttpBinding(), Config.ServiceEndpoint); } m_SvcHost.Open(); 

the service will listen for the BOTH URI defined in app.config and the URI defined in the configuration file. I cannot find to remove the source endpoint or create a service without a specific endpoint.

Writing to app.config from a configuration application is not an option - I need to programmatically output the configured value from a separate XML configuration file ....

any thoughts?

EDIT: The service works as a Windows service and provides an HTTP endpoint, it does not work as a web service hosted in IIS - if that changes anything at all.

+4
source share
4 answers

By combining the answers of gWiz and Dylan, I came up with a way to do this, although I did not check it carefully enough to see if I had violated any other functions with these changes.

Basically, I added this class:

 public class MobileMonitoringSvcHost : ServiceHost { protected override void ApplyConfiguration() { // skip this line to not apply default config - unsure of other ramifications of doing this yet... base.ApplyConfiguration(); base.Description.Endpoints.Clear(); } public MobileMonitoringSvcHost(object singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses) { } } 

This skips the call to ServiceHost "ApplyConfiguration" and (probably now is not necessary, because if the configuration is not loaded, there should be no endpoints) clears the endpoints. Then I do the following:

 m_SvcHost = new MySvcHost(this); if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty) { //m_SvcHost.Description.Endpoints.Clear(); m_SvcHost.AddServiceEndpoint(typeof(IMobileMonitoringSvc), new BasicHttpBinding(), Config.ServiceEndpoint); } // open the svchost and allow incoming connections m_SvcHost.Open(); 

This causes the service to only listen on the external custom endpoint, not the app.config custom endpoint

Thanks!

+1
source

Justin

Does this help you? This code will allow you to respond to any address that you specify in the CreateServiceHost () method.

 public class CRSyncServiceHost : ServiceHost { public CRSyncServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { } protected override void ApplyConfiguration() { base.ApplyConfiguration(); } } public class CRSyncServiceFactory : ServiceHostFactory { protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { Uri newServiceAddress = new Uri("http://someaddress.com/CRSyncService.svc"); CRSyncServiceHost newHost = new CRSyncServiceHost(serviceType, newServiceAddress); return newHost; } } <%@ ServiceHost Language="C#" Debug="true" Service="CRSyncService" Factory="CRSyncServiceFactory" CodeBehind="CRSyncService.svc.cs" %> 
+2
source

Well, I don't have a terrific WCF background, but will this work?

 m_SvcHost = new ServiceHost(this); m_SvcHost.Description.Endpoints.Clear(); // <-- added if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty) { m_SvcHost.AddServiceEndpoint(typeof(IMyService), new BasicHttpBinding(), Config.ServiceEndpoint); } m_SvcHost.Open(); 
+2
source

You do not need to have a configuration part at all, I do not believe, i.e. you can do it all in code. If you leave the material in .config, it will be used along with what you write in the code.

If you want one or the other, I think you need to delete one or the other.

0
source

All Articles