I'm trying to allow for user configuration of a WCF service, including the IP and port number that the service listens on. The user has a separate config application that allows for these values to be set, but the problem I am running into is that the app.config MUST have an endpoint defined in order to create a new ServiceHost entry...but my endpoint is being defined in a separate configuration file and must then be bound programatically at runtime.
If I do the following (based on How to programatically modify WCF app.config endpoint address setting?:
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 on BOTH the URI defined in the app.config, AND the URI defined in the configuration file. There is no way that I can find to remove the original endpoint or to create the service without an endpoint defined.
Writing to the app.config from the configuration application is not an option - I need to pull the configured value programatically from the separate XML config file....
any thoughts?
EDIT: the service runs as a Windows Service and exposes an HTTP endpoint, it is not running as a web service hosted in IIS - if that changes things at all
Justin,
Does this help you? This code will allow you to respond to any address that you list 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" %>
Well I don't have tremendous WCF background, but would 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();
By combining both gWiz and Dylan's answers I came up with a way to do this, though I haven't tested thoroughly enough to know if I have broken any other functionality 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 ServiceHost "ApplyConfiguration" call and (likely needlessly for now because if the config isn't 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 does cause the service to only listen on the externally configured endpoint and not the app.config configured endpoint
Thanks!
You don't have to have the configuration piece at all, I don't believe - i.e. you can do it all in code. If you leave the stuff in .config then it'll be used along with what you write in code.
If you want one or the other, I think you have to remove one or the other.
来源:https://stackoverflow.com/questions/2059485/how-to-programatically-set-a-single-endpoint-for-a-wcf-service