У меня есть решение WCF, которое состоит из следующих библиотек классов:
- Exercise.Services: Содержит классы реализации для служб.
- Exercise.ServiceProxy: Содержит классы, которые создаются в клиенте.
- Exercise.HttpHost: содержит службы (* .svc файлы).
Я вызываю службу из консольного приложения, и «первая версия» работает очень хорошо, поэтому ясделал следующий шаг - создать пользовательские ServiceHostFactory, ServiceHost и InstanceProvider, чтобы я мог использовать инжекцию конструктора в своих сервисах, как описано в этой статье .
Эти классы реализованы веще одна библиотека классов:
4. Exercise.StructureMapWcfExtension
Теперь, хотя я изменил свой сервис так:
<%@ ServiceHost Language="C#" Debug="true" Factory="Exercise.StructureMapWcfExtension.StructureMapServiceHostFactory" Service="Exercise.Services.PurchaseOrderService" %>
Я всегда получаю следующее исключение:
System.ServiceModel.CommunicationException Согласование безопасности не удалось, поскольку удаленная сторона не отправила ответ своевременно.Это может быть связано с тем, что основное транспортное соединение было прервано.
В этой строке кода происходит сбой:
public class PurchaseOrderProxy : ClientBase<IPurchaseOrderService>, IPurchaseOrderService
{
public PurchaseOrderResponse CreatePurchaseOrder(PurchaseOrderRequest purchaseOrderRequest)
{
return base.Channel.CreatePurchaseOrder(purchaseOrderRequest); //Fails here
}
}
Но это еще не все, я добавил след в сетьФайл .config, и это ошибка, которая появляется в файле журнала:
System.InvalidOperationException Предоставленный тип службы не может быть загружен как служба, поскольку он не имеет значения по умолчанию (без параметров)конструктор.Чтобы решить эту проблему, добавьте конструктор по умолчанию к типу или передайте экземпляр типа на хост.
Так что это означает, что мой ServiceHostFactory никогда не срабатывает, я даже установил точку останова ви его конструктор, и метод, и они никогда не получат попадание.
Я добавил ссылку на библиотеку StructureMapWcfExtension ко всем остальным (даже консольному клиенту), один за другим, но безрезультатно.
Я также попытался использовать опцию в файле web.config хоста для настройки фабрики следующим образом:
<serviceHostingEnvironment>
<serviceActivations>
<add service="Exercise.Services.PurchaseOrderService" relativeAddress="PurchaseOrderService.svc" factory="Exercise.StructureMapWcfExtension.StructureMapServiceHostFactory"/>
</serviceActivations>
</serviceHostingEnvironment>
Это тоже не сработало.
ПожалуйстаМне нужна помощь, чтобы заставить это работать, чтобы я мог включить его в наш проект.
Спасибо.
ОБНОВЛЕНИЕ : Вот код фабрики хоста службы:
namespace Exercise.StructureMapWcfExtension
{
public class StructureMapServiceHostFactory : ServiceHostFactory
{
private readonly Container Container;
public StructureMapServiceHostFactory()
{
Container = new Container();
new ContainerConfigurer().Configure(Container);
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new StructureMapServiceHost(Container, serviceType, baseAddresses);
}
}
public class ContainerConfigurer
{
public void Configure(Container container)
{
container.Configure(r => r.For<IPurchaseOrderFacade>().Use<PurchaseOrderFacade>());
}
}
public class StructureMapServiceHost : ServiceHost
{
public StructureMapServiceHost(Container container, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if (container == null) throw new ArgumentNullException("container");
var contracts = ImplementedContracts.Values;
foreach (var c in contracts)
{
var instanceProvider = new StructureMapInstanceProvider(container, serviceType);
c.Behaviors.Add(instanceProvider);
}
}
}
public class StructureMapInstanceProvider : IInstanceProvider, IContractBehavior
{
private readonly Container Container;
private readonly Type ServiceType;
public StructureMapInstanceProvider(Container container, Type serviceType)
{
if (container == null) throw new ArgumentNullException("container");
if (serviceType == null) throw new ArgumentNullException("serviceType");
Container = container;
ServiceType = serviceType;
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return Container.GetInstance(ServiceType);
}
}
}