是否可以/如何在运行时停止和启动自托管 WCF 服务的 HTTP MEX 监听器而不影响主 WCF 服务?
(请不要问我为什么要这样做。这是一种绕过别人人为限制的黑客行为。)
最佳答案
*****[在重新测试和代码清理后重新添加了此答案]这是我添加到基于 WCF 的通用服务开发框架中的实际代码,并且经过了全面测试。*****
假设您开始时在 ServiceHost
上启用了 MEX ...
The following solution is written in terms of a
ServiceHost
subclass (WCFServiceHost<T>
) that implements a special interface (IWCFState
) for storing an instance of the MEXEndpointDispatcher
class.
首先,添加这些命名空间...
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
其次,定义IWCFState
界面...
public interface IWCFState
{
EndpointDispatcher MexEndpointDispatcher
{
get;
set;
}
}
第三,为某些ServiceHost
创建一个静态类扩展方法(我们将在下面填写)...
public static class WCFExtensions
{
public static void RemoveMexEndpointDispatcher(this ServiceHost host){}
public static void AddMexEndpointDispatcher(this ServiceHost host){}
}
现在让我们填写扩展方法...
在 ServiceHost
上停止 MEX在运行时
public static void RemoveMexEndpointDispatcher(this ServiceHost host)
{
// In the simple example, we only define one MEX endpoint for
// one transport protocol
var queryMexChannelDisps =
host.ChannelDispatchers.Where(
disp => (((ChannelDispatcher)disp).Endpoints[0].ContractName
== "IMetadataExchange"));
var channelDisp = (ChannelDispatcher)queryMexChannelDisps.First();
// Save the MEX EndpointDispatcher
((IWCFState)host).MexEndpointDispatcher = channelDisp.Endpoints[0];
channelDisp.Endpoints.Remove(channelDisp.Endpoints[0]);
}
然后这样调用它...
// WCFServiceHost<T> inherits from ServiceHost and T is the Service Type,
// with the new() condition for the generic type T. It encapsulates
// the creation of the Service Type that is passed into the base class
// constructor.
Uri baseAddress = new Uri("someValidURI");
WCFServiceHost<T> serviceImplementation = new WCFServiceHost<T>(baseAddress);
// We must open the ServiceHost first...
serviceImplementation.Open();
// Let's turn MEX off by default.
serviceImplementation.RemoveMexEndpointDispatcher();
在 ServiceHost
上(再次)启动 MEX在运行时
public static void AddMexEndpointDispatcher(this ServiceHost host)
{
var queryMexChannelDisps =
host.ChannelDispatchers.Where(
disp => (((ChannelDispatcher)disp).Endpoints.Count == 0));
var channelDisp = (ChannelDispatcher)queryMexChannelDisps.First();
// Add the MEX EndpointDispatcher
channelDisp.Endpoints.Add(((IWCFState)host).MexEndpointDispatcher);
}
然后这样调用它...
serviceImplementation.AddMexEndpointDispatcher();
摘要
此设计允许您使用一些消息传递方法将命令发送到服务本身或托管服务的代码,并让它执行 MEX EndpointDispatcher
的启用或禁用。 ,为此有效地关闭 MEX ServiceHost
.
注意:此设计假设代码在启动时支持 MEX,但随后它将使用配置设置来确定服务在调用 Open()
后是否禁用 MEX。关于ServiceHost
。如果您尝试在 ServiceHost
之前调用任一扩展方法,则会抛出此代码。已开通。
注意事项:我可能会创建一个特殊的服务实例,其管理操作在启动时不支持 MEX,并将其建立为服务控制 channel 。
资源
在解决这个问题时,我发现以下两个资源不可或缺:
.NET Reflector:用于检查 System.ServiceModel.dll 等程序集的类浏览器、分析器和反编译器:http://www.red-gate.com/products/reflector/
扩展调度程序 (MSDN):提供了 WCF 服务的类组成的精彩高级图表:http://msdn.microsoft.com/en-us/library/ms734665.aspx
关于c# - 在运行时停止/启动 WCF MEX 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/547287/