Я нашел еще один вопрос об использовании custom ServiceHostFactory
для выполнения начальной загрузки , которая настраивается с помощью файла *.svc
. Файлы *.svc
являются частью приложения-службы WCF и не могут напрямую использоваться службой WCF Библиотека . Я хочу использовать библиотеку сервисов для некоторой гибкости с моей реализацией сервисов и возможным производственным хостингом, но использование сервисного приложения WCF позволило бы выполнить работу способом, подходящим для разработки (и, вероятно, было бы достаточно просто отбросить в IIS для производственного хостинга с альтернативным набором конфигурации). Поэтому я решил, что мне просто нужно создать приложение службы WCF, которое выступает в качестве хоста для служб в библиотеке служб и выполняет требуемую инициализацию.
Сначала я создал новое приложение службы WCF, удалил файлы службы по умолчанию, созданные VS, и добавил ссылку на существующую библиотеку служб и другие зависимости.
В файле Web.Config
приложения-службы в разделе <configSections>..</configSections>
(который должен быть первым узлом после тега <configuration>
) я добавил раздел <system.serviceModel>
для библиотеки служб (это может быть извлечено из файла App.config
в служебной библиотеке и отредактировано в соответствии с требованиями).
Например:
<system.serviceModel>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="BelfryImages.QueryService.Implementation.HelloWorld">
<endpoint address="HelloWorld" binding="wsHttpBinding" name="HelloWorld" contract="BelfryImages.QueryService.Contracts.IHelloWorld" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
</bindings>
</system.serviceModel>
Обратите внимание, что BelfryImages.QueryService.Implementation.HelloWorld
является FQN реализации службы (класс реализации) контракта на обслуживание (интерфейса) BelfryImages.QueryService.Contracts.IHelloWorld
. У меня фактически есть это в двух отдельных сборках; BelfryImages.QueryService.Contracts.dll
- Сервисная библиотека WCF.
Я добавил новый пустой файл .svc
в приложение-службу, названный в соответствии с конечной точкой, например HelloWorld.svc
. Обычно добавление службы WCF к приложению службы WCF приводит к созданию файла .svc
и файла кодовой привязки .cs
, в котором содержится реализация службы. Я вручную добавил только файл .svc
без кода и указал его на реализацию библиотеки служб:
<%@ ServiceHost Language="C#" Debug="true" Service="BelfryImages.QueryService.Implementation.HelloWorld" %>
В нынешнем виде это можно было использовать в качестве замены для служебной библиотеки, размещенной на VS, после первого изменения URL-адреса службы клиента с http://localhost:XXXXX/QueryService/HelloWorld
на http://localhost:XXXXX/HelloWorld.svc/HelloWorld
.
Затем я создал ServiceHostFactory
для выполнения инициализации службы. Я нашел статью MSDN ( Хостинг и использование служб WCF ), в которой объясняется, как это сделать (листинги 5-6 и 5-7) - для своих целей я просто добавил более простое, общего назначения CustomHostFactory
класс:
public class CustomHostFactory
: ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
// perform initialisation:
...
var serviceHost = base.CreateServiceHost(serviceType, baseAddresses);
return serviceHost;
}
}
Затем он привязывается к службе в файле .svc
путем добавления атрибута Factory
:
<%@ ServiceHost Language="C#" Debug="true" Service="BelfryImages.QueryService.Implementation.HelloWorld" Factory="BelfryImages.WcfService.CustomHostFactory" %>
Инициализация в верхней части переопределения CreateServiceHost()
выполняется до того, как служба создается как обычно. Кажется, что это происходит только один раз для каждой службы, а не один раз для каждого вызова службы, но для нескольких служб будут накладные расходы. Это, вероятно, можно сделать одноразовым, используя статический флаг или подобное. На данный момент все работает нормально.