I have a small WCF hosting engine that I am writing that will dynamically create ServiceHosts based on the .config file. The general idea is to allow us to remove existing services, as well as add new services, at runtime without having to bring all of our services offline.
I ran into a problem unit testing that indicates this may not be as easy as it sounds. It seems that only one ServiceHost may exist for any given endpoint (even though multiple different endpoints for a service may exist in a single ServiceHost). This is not a problem normally, however when a service needs to be reconfigured, bringing down the original ServiceHost does not actually kill the registration for that endpoint address. Trying to create another ServiceHost, for the same service (which means the same endpoints are used) fails with the following exception:
System.InvalidOperationException: The ChannelDispatcher at 'net.pipe://localhost/' with contract(s) '"ITestService"' is unable to open its IChannelListener. --->
System.InvalidOperationException: A registration already exists for URI 'net.pipe://localhost/'.
I am actually encountering the error during unit testing. The tests will exercise one unit, which fully closes down the ServiceHosts and hosting engine as much as is humanly possible. Then creates another instance of the hosting engine, which tries to recreate the same ServiceHosts again for a different test. The second test encounters the error above. I am guessing that while ServiceHost.Close() was called, that does not actually destroy the service host...so it is still hanging around in memory. I can not tell whether the GC is cleaning up the old service hosts or not...the problem persists without going away after it initially occurs (as best I have been able to determine...I have waited about 30 minutes so far.)
My configuration file for system.serviceModel is as follows:
<system.serviceModel>
<services>
<service name="Campus.Core.ServiceModel.TestServiceStub">
<endpoint
address="net.pipe://localhost"
binding="netNamedPipeBinding"
contract="Campus.Core.ServiceModel.ITestService"
/>
</service>
</services>
</system.serviceModel>