У меня есть небольшой хостинг WCF, который я пишу, который будет динамически создавать ServiceHosts на основе файла .config. Общая идея состоит в том, чтобы позволить нам удалять существующие сервисы, а также добавлять новые сервисы во время выполнения без необходимости переводить все наши сервисы в автономный режим.
Я столкнулся с проблемой модульного тестирования, которое показывает, что это может быть не так просто, как кажется. Кажется, что только одна ServiceHost может существовать для любой данной конечной точки (даже если в одной ServiceHost может существовать несколько разных конечных точек для службы). Обычно это не проблема, однако, когда требуется переконфигурировать службу, сбой исходного ServiceHost фактически не уничтожает регистрацию для этого адреса конечной точки. Попытка создать другой ServiceHost для той же службы (что означает, что используются те же конечные точки) завершается неудачей со следующим исключением:
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/'.
Я действительно столкнулся с ошибкой во время модульного тестирования. В тестах будет задействован один модуль, который полностью закрывает ServiceHosts и хост-движок настолько, насколько это возможно. Затем создает другой экземпляр хост-движка, который пытается заново создать тот же ServiceHosts для другого теста. Второй тест встречает ошибку выше. Я предполагаю, что хотя ServiceHost.Close () был вызван, это на самом деле не разрушает хост службы ... так что он все еще находится в памяти. Я не могу сказать, очищает ли GC старые сервисные хосты или нет ... проблема сохраняется, не исчезая после того, как она первоначально произошла (насколько я смог определить ... я ждал около 30 минут) )
Мой файл конфигурации для system.serviceModel выглядит следующим образом:
<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>