*****[在重新测试和代码清理后重新添加了这个答案]这是我添加到我的基于 WCF 的通用服务开发框架中的实际代码,并且它已经过全面测试。*****
假设您一开始就启用了 MEXServiceHost
...
下面的解决方案被写入
的条款ServiceHost
子类
(WCFServiceHost<T>
)实现
一个特殊的接口(IWCFState
) 为了
存储 MEX 的实例EndpointDispatcher
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){}
}
现在让我们填写扩展方法...
停止 MEXServiceHost
在运行时
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();
在 a 上(再次)启动 MEXServiceHost
在运行时
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();
Summary
此设计允许您使用一些消息传递方法将命令发送到服务本身或托管服务的代码,并让它执行 MEX 的启用或禁用EndpointDispatcher
,为此有效地关闭 MEXServiceHost
.
注意:此设计假设代码在启动时支持 MEX,但随后它将使用配置设置来确定服务在调用后是否禁用 MEXOpen()
on the ServiceHost
。如果您尝试在之前调用任一扩展方法,则会抛出此代码ServiceHost
已被打开。
注意事项:我可能会创建一个特殊的服务实例,其管理操作在启动时不支持 MEX,并将其建立为服务控制通道。
资源
在解决这个问题时,我发现以下两个资源不可或缺:
.NET 反射器:类浏览器、分析器和反编译器,用于检查 System.ServiceModel.dll 等程序集: http://www.red-gate.com/products/reflector/ http://www.red-gate.com/products/reflector/
扩展调度程序 (MSDN):提供了 WCF 服务的类组成的精彩高级图表:http://msdn.microsoft.com/en-us/library/ms734665.aspx http://msdn.microsoft.com/en-us/library/ms734665.aspx