1

所以,我正在尝试编写路由服务。这个想法是,每次有人调用路由服务时,WCF 行为扩展都会随机选择端点。我使用了 MSDN 中名为DynamicReconfiguration的稍作修改的示例来实现这一点。我的 web.config 的一部分看起来像这样

<behaviors>
  <serviceBehaviors>
    <behavior>
     <behavior name="behaviorWithUpdate">
       <updateBehavior />
    </behavior>
  </serviceBehaviors>
</behaviors>
<extensions>
  <behaviorExtensions>
    <add name="updateBehavior" type="RouterService.UpdateBehavior, RouterService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </behaviorExtensions>
</extensions>
<services>

以及行为和行为扩展的实现

public class UpdateBehavior : BehaviorExtensionElement, IServiceBehavior
{
    void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }
    void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        var rulesUpdateExtension = new RulesUpdateExtension();
        serviceHostBase.Extensions.Add(rulesUpdateExtension);
    }
    void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
    class RulesUpdateExtension : IExtension<ServiceHostBase>
    {
        ServiceHostBase _owner;
        List<EndpointAddress> _endpoints = new List<EndpointAddress>
                                                       {
                                                           new EndpointAddress("http://localhost:19338/Service1.svc"),
                                                           new EndpointAddress("http://localhost:20464/Service2.svc")
                                                       };

        void IExtension<ServiceHostBase>.Attach(ServiceHostBase owner)
        {
            this._owner = owner;

            UpdateRules(DateTime.Now.Second % 2 == 0 ? _endpoints[0] : _endpoints[1]);
        }

        void IExtension<ServiceHostBase>.Detach(ServiceHostBase owner)
        {
        }

        void UpdateRules(EndpointAddress endpoint)
        {
            var rc = new RoutingConfiguration();

            var serviceEndpoint = new ServiceEndpoint(
                    ContractDescription.GetContract(typeof(IService1)),
                    new BasicHttpBinding(),
                    endpoint);
            rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { serviceEndpoint });

            this._owner.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc);
        }
    }

    public override Type BehaviorType
    {
        get { return typeof(UpdateBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new UpdateBehavior();
    }
}

问题是UpdateRules方法的最后一行抛出NullReferenceException。即使我在行为中附加它,它也找不到这个扩展。在来自 MSDN 的示例中,路由服务托管在控制台应用程序中,并且我尝试将其托管在 IIS 上。我在这里错过了一些东西......

4

1 回答 1

1

在示例 RoutingService 项目中,routing.cs 中的代码以编程方式将 RoutingExtension 注入 RoutingService。这通常在配置文件中使用 behavior>serviceBehaviors>behavior>routing 元素来设置要使用的过滤器表。但是,由于 WCF 服务只能通过配置文件分配单个服务行为,因此示例 RoutingService 项目在服务主机初始化中动态添加 RoutingExtension。

要在 IIS 中做同样的事情,您需要创建一个自定义服务宿主工厂来执行示例项目中的 routing.cs 代码的相同功能。查看这篇 MSDN 文章了解如何创建自定义主机。它还显示了如何使用 IIS 对其进行配置。

于 2011-04-22T13:40:18.627 回答