Stop/start WCF MEX service at runtime

后端 未结 1 1343
我寻月下人不归
我寻月下人不归 2021-01-21 17:57

Is it possible/how do I stop and start the HTTP MEX listener of a self hosted WCF service at runtime without affecting the primary WCF service?

(Please don\'t ask why I

相关标签:
1条回答
  • 2021-01-21 18:21

    *****[Re-added this answer after re-test and code cleanup] This is actual code that I have added to my generic WCF-based service development framework and it is fully tested.*****

    Assuming that you start with MEX enabled on the ServiceHost...

    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 MEX EndpointDispatcher class.

    First, add these namespaces...

    using System.ServiceModel;
    using System.ServiceModel.Dispatcher;
    

    Secondly, define the IWCFState interface...

    public interface IWCFState
    {
        EndpointDispatcher MexEndpointDispatcher
        {
            get;
            set;
        }
    }
    

    Thirdly, create a static class for some ServiceHost extension methods (we'll fill them in below)...

    public static class WCFExtensions
    {
        public static void RemoveMexEndpointDispatcher(this ServiceHost host){}
    
        public static void AddMexEndpointDispatcher(this ServiceHost host){}
    }
    

    Now let's fill in the extension methods...

    Stopping MEX on a ServiceHost at Runtime

    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]);
    }
    

    Then call it like this...

    // 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();
    

    Starting MEX (again) on a ServiceHost at Runtime

    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);
    }
    

    Then call it like this...

    serviceImplementation.AddMexEndpointDispatcher();
    

    Summary

    This design allows you to use some messaging methods to send a command to the service itself or to code that is hosting the service and have it carry out the enabling or disabling of a MEX EndpointDispatcher, effectively turning off MEX for that ServiceHost.

    Note: This design assumes that the code will support MEX at startup, but then it will use a config setting to determine if the service will disable MEX after calling Open() on the ServiceHost. This code will throw if you attempt to call either extension method before the ServiceHost has been opened.

    Considerations: I would probably create a special service instance with management operations that did not support MEX at startup and establish that as service control channel.

    Resources

    I found the following two resources indispensable while figuring this out:

    • .NET Reflector: class browser, analyzer & decompiler for inspecting assemblies like System.ServiceModel.dll: http://www.red-gate.com/products/reflector/

    • Extending Dispatchers (MSDN): provides a fantastic high-level diagram of the class composition of a WCF service: http://msdn.microsoft.com/en-us/library/ms734665.aspx

    0 讨论(0)
提交回复
热议问题