C# 在运行时动态更新WCF路由服务配置

C# 在运行时动态更新WCF路由服务配置,c#,wcf,iis,wcf-routing,C#,Wcf,Iis,Wcf Routing,我一直在关注MSDN上的WCF路由服务教程: (见下面的代码) 在尝试将控制台示例转换为IIS托管的原型时经历了很多痛苦,现在我有了一个WCF路由服务,它按照教程每5秒更新一次配置 我现在需要从网页触发此更新,而不是计时器每5秒自动更新一次,但找不到任何示例说明如何执行此操作。类似于管理屏幕,它处理数据库中存储的端点的CRUD操作。如果用户更改了配置,路由服务将需要动态更新其配置 显然,您可以通过UDP公告和发现服务执行类似的操作,但我不希望一个简单的端点触发从另一个应用程序调用的更新就足够了

我一直在关注MSDN上的WCF路由服务教程:


(见下面的代码)

在尝试将控制台示例转换为IIS托管的原型时经历了很多痛苦,现在我有了一个WCF路由服务,它按照教程每5秒更新一次配置

我现在需要从网页触发此更新,而不是计时器每5秒自动更新一次,但找不到任何示例说明如何执行此操作。类似于管理屏幕,它处理数据库中存储的端点的CRUD操作。如果用户更改了配置,路由服务将需要动态更新其配置

显然,您可以通过UDP公告和发现服务执行类似的操作,但我不希望一个简单的端点触发从另一个应用程序调用的更新就足够了

如何获取路由服务
UpdateBehavior
的引用,以便手动调用
UpdateRules
方法

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Routing;
using System.Threading;

namespace ErpRoutingService
{
    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)
        {
            RulesUpdateExtension rulesUpdateExtension = new RulesUpdateExtension();
            serviceHostBase.Extensions.Add(rulesUpdateExtension);
        }
        void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }

        class RulesUpdateExtension : IExtension<ServiceHostBase>, IDisposable
        {
            bool primary = false;
            ServiceHostBase owner;
            Timer timer;

            void IExtension<ServiceHostBase>.Attach(ServiceHostBase owner)
            {
                this.owner = owner;
                //Call immediately, then every 5 seconds after that.
                this.timer = new Timer(this.UpdateRules, this, TimeSpan.Zero, TimeSpan.FromSeconds(5));
            }

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

            public void Dispose()
            {
                if (this.timer != null)
                {
                    this.timer.Dispose();
                    this.timer = null;
                }
            }

            void UpdateRules(object state)
            {
                //Updating Routing Configuration
                RoutingConfiguration rc = new RoutingConfiguration();

                var inspector = new ErpMessageInspectorBehavior();

                if (this.primary)
                {
                    ServiceEndpoint endPoint101 = new ServiceEndpoint(
                    ContractDescription.GetContract(typeof(IRequestReplyRouter)),
                    new BasicHttpBinding(),
                    new EndpointAddress("http://meldev:62395/ErpIntegrationService.svc"));
                    endPoint101.EndpointBehaviors.Add(inspector);
                    rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { endPoint101 });                    
                }
                else
                {
                    ServiceEndpoint endPoint102 = new ServiceEndpoint(
                        ContractDescription.GetContract(typeof(IRequestReplyRouter)),
                        new BasicHttpBinding(),
                        new EndpointAddress("http://meldev:62396/ErpIntegrationService.svc"));
                    endPoint102.EndpointBehaviors.Add(inspector);
                    rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { endPoint102 });                    
                }

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


                this.primary = !this.primary;
            }
        }

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

        protected override object CreateBehavior()
        {
            return new UpdateBehavior();
        }
    }    
}
使用系统;
使用System.Collections.Generic;
使用System.ServiceModel;
使用System.ServiceModel.Channel;
使用System.ServiceModel.Configuration;
使用System.ServiceModel.Description;
使用System.ServiceModel.Dispatcher;
使用System.ServiceModel.Routing;
使用系统线程;
命名空间路由服务
{
公共类UpdateBehavior:BehaviorExtensionElement,IServiceBehavior
{
void IServiceBehavior.AddBindingParameters(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase,System.Collections.ObjectModel.Collection端点,BindingParameterCollection bindingParameters)
{
}
无效IServiceBehavior.ApplyDispatchBehavior(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
RulesUpdateExtension RulesUpdateExtension=新RulesUpdateExtension();
serviceHostBase.Extensions.Add(rulesUpdateExtension);
}
无效IServiceBehavior.Validate(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
}
类RulesUpdateExtension:IExtension,IDisposable
{
bool primary=false;
服务主机库所有者;
定时器;
void IExtension.Attach(ServiceHostBase所有者)
{
this.owner=所有者;
//立即打电话,然后每隔5秒打一次。
this.timer=new timer(this.UpdateRules,this,TimeSpan.Zero,TimeSpan.FromSeconds(5));
}
void IExtension.Detach(ServiceHostBase所有者)
{
这个。Dispose();
}
公共空间处置()
{
如果(this.timer!=null)
{
this.timer.Dispose();
this.timer=null;
}
}
void UpdateRules(对象状态)
{
//更新路由配置
RoutingConfiguration rc=新的RoutingConfiguration();
var inspector=new-ErpMessageInspectorBehavior();
如果(此.primary)
{
ServiceEndpoint101=新的ServiceEndpoint(
合同说明.GetContract(类型为(IRequestReplyRouter)),
新的BasicHttpBinding(),
新端点地址(“http://meldev:62395/ErpIntegrationService.svc"));
endPoint101.EndpointBehaviors.Add(检查器);
添加(新的MatchAllMessageFilter(),新列表{endPoint101});
}
其他的
{
ServiceEndpoint102=新的ServiceEndpoint(
合同说明.GetContract(类型为(IRequestReplyRouter)),
新的BasicHttpBinding(),
新端点地址(“http://meldev:62396/ErpIntegrationService.svc"));
endPoint102.EndpointBehaviors.Add(检查器);
添加(新的MatchAllMessageFilter(),新列表{endPoint102});
}
this.owner.Extensions.Find().ApplyConfiguration(rc);
this.primary=!this.primary;
}
}
公共重写类型BehaviorType
{
获取{return typeof(UpdateBehavior);}
}
受保护的重写对象CreateBehavior()
{
返回新的UpdateBehavior();
}
}    
}

从您的
ServiceHost
实例开始,它非常简单:

var updateBahvaior = serviceHost.Description.Behaviors.Find<UpdateBehavior>();
var updateBahvaior=serviceHost.Description.Behaviors.Find();

然后,如果您公开了一个从内部私有类调用
UpdateRules
方法的方法,则可以调用它。

您可能必须在自定义类中使用公共静态变量…

联机找到了此文档。

路由扩展应用程序配置在这里会有所帮助

附加代码段。