无法使我的WCF扩展工作

时间:2011-11-29 00:54:49

标签: c# wcf dependency-injection

我有一个WCF解决方案,它包含以下类库:

  1. Exercise.Services:包含服务的实现类。
  2. Exercise.ServiceProxy:包含在客户端中实例化的类。
  3. Exercise.HttpHost:包含服务(* .svc文件)。
  4. 我从一个控制台应用程序调用该服务,“第一个版本”工作得非常好所以我采取了下一步,即创建一个自定义ServiceHostFactory,ServiceHost和InstanceProvider,以便我可以在我的服务中使用构造函数注入它在this article中解释。

    这些类在另一个类库中实现:
    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
            }
    }
    

    但这不是全部,我在web.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);
           }
       }
    }
    

1 个答案:

答案 0 :(得分:0)

查看StructureMapInstanceProvider的代码,看起来它缺少dispatchRuntime.InstanceProvider的设置。我从链接的网页复制了清单5。它是IContractBehavior接口的一部分。

public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
dispatchRuntime.InstanceProvider = this;
}