Reputation: 9733
Consider this scenario:
What I did now is add a service reference to the same service and added an extra endpoint + client in the service configuration file. Working over net.tcp.
It works fine, but I read somewhere that you can use "in process" hosting to connect to a service without using a proxy. This way you can get rid of the configuration and have much cleaner code.
So instead of this with the accompying configuration settings:
DeliveryOwnClient.DeliveryClient deliveryObject = new DeliveryOwnClient.DeliveryClient("netTcpDeliveryService");
I want to use this without any configuration:
IDelivery deliveryObject = InProcessFactory.CreateInstance<DeliveryService.Delivery, IDelivery>();
But this throws an exception that "The ChannelDispatcher at http://localhost:8003/DeliveryService with contract "IMetadataExchange" can't open the IChannelListener. A registration already exists for Uri net.tcp://localhost:9003/DeliveryService"
The implementation for CreateInstance looks like this:
ServiceHost host = new ServiceHost(typeof(S));
string address = "net.pipe://" + Environment.MachineName + "/" + Guid.NewGuid();
host.AddServiceEndpoint(typeof(I), Binding, address);
host.Open();
So I'm adding a net.pipe baseaddress and it fails because there is something running over net.tcp already.
** edit **
Figured out at least why this is happening.
The service is configured in the app.config with two baseaddresses
<service name="DeliveryService.Delivery">
<endpoint binding="netTcpBinding" contract="DeliveryService.IDelivery"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8003/DeliveryService" />
<add baseAddress="net.tcp://localhost:9003/DeliveryService" />
</baseAddresses>
</host>
</service>
When the host is constructed
ServiceHost host = new ServiceHost(typeof(S));
It find that section in the config file and automatically adds net.tcp and http base addresses. I add net.pipe, but that doesnt matter. When the service is opened it finds that net.tcp is already running so it wont continue.
So I guess my question is changed into: Is it possible to construct a ServiceHost without having it read app.config?
Upvotes: 4
Views: 115
Reputation: 9733
Jay managed to figure it out! ServiceHost derives from ServiceHostBase and that class has a virtual function named ApplyConfiguration. So I made a class which derives from ServiceHost and overrides ApplyConfiguration...and leave it empty.
class ServiceHostNoConfig<S> : ServiceHost where S : class
{
public ServiceHostNoConfig(string address)
{
UriSchemeKeyedCollection c = new UriSchemeKeyedCollection(new Uri(address));
InitializeDescription(typeof(S), c);
}
public new void InitializeDescription(Type serviceType, UriSchemeKeyedCollection baseAddresses)
{
base.InitializeDescription(serviceType, baseAddresses);
}
protected override void ApplyConfiguration()
{
}
}
Use it like this:
ServiceHost host = new ServiceHostNoConfig<S>(address);
host.AddServiceEndpoint(typeof(I), Binding, address);
Upvotes: 1