IDispatchMessageInspectorインターフェイスのカスタム実装を作成しましたが、コードは99%正常に機能しています。
私の問題は、WCFサービスホストが強制終了されたとき、および/またはクラスのインスタンスを解放したときに、いくつかの管理対象オブジェクトを解放する必要があることです。IDisposableを解放するための私のオブジェクトは、破棄されていません。私はMSDNライブラリ(もっと混乱しています)とSOアーカイブを調べましたが、「WCFサービスホストがMessageInspectorsを破棄するのはいつ/どこですか?」という質問に対処するものは見つかりませんでした。
イベントをどこかにフックする必要がありますか?ServiceModel名前空間からさらに難解なものを実装する必要がありますか?
誰かが私に正しい方向へのポインタを与えることができますか?
編集1:説明
現在、自動Webサーバーを使用してIDEで実行しています。私は、本番環境で一度ホストを制御することはできません。有効なサーバーホストの選択肢のいずれかである可能性があります。
MyCore.MyオブジェクトとMyCore.MyPropertiesオブジェクトは、WCFサーバーホストが強制終了/バウンスされたときに破棄しようとしているオブジェクトです。
Webサーバープロセス(タスクバーにあるもの)を強制終了した場合でも、Dispose()が呼び出されることはありません。
編集2:コードスニペットが追加されました。
using /* snip */
using MyCore = Acme.My;
namespace My.SOAP
{
    public class MyMessageInspector : IDispatchMessageInspector
    {
        protected static MyCore.My _My;
        protected static MyCore.MyProperties _MyProps;
        protected static ConcurrentDictionary<string, MyCore.AnotherSecretThing> _anotherSecretThings = new ConcurrentDictionary<string, MyCore.AnotherSecretThing>();
        protected static void InitMy()
        {
            if (_My != null) return;
            _MyProps = new MyCore.MyProperties();
            MyCore.MySqlDatabaseLogger logger = new MyCore.MySqlDatabaseLogger(_MyProps);
            _My = new MyCore.My(logger);
        }
        public MyMessageInspector()
        {
            InitMy();
        }
        public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request,    System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
        {
            MyMessageHeader header = null;
            try
            {
                // find My header
                Int32 headerPosition = request.Headers.FindHeader(MyMessageHeaderKey.MyHeaderElementName, MyMessageHeaderKey.MyNamespace);
                // get reader
                XmlDictionaryReader reader = request.Headers.GetReaderAtHeader(headerPosition);
                // get My header object
                header = MyMessageHeader.ReadHeader(reader);
                // add to incoming messages properties dictionary
                OperationContext.Current.IncomingMessageProperties.Add(MyMessageHeaderKey.MyHeaderElementName, header);
            }
            catch (Exception ex)
            {
                // log via ExceptionHandlingBlock
            }
            MyCore.SecretThings SecretThings = CreateSecretThings(/* snip */);
            return SecretThings.Id;
        }
        public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object  correlationState)
        {
             MyCore.SecretThings req = _My.GetSecretThingsOnThread();
            // if we didn't find the SecretThings, there is nothing to stop() and no data to put in the MessageHeaders
            if (req == null) return;
            MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
            reply = buffer.CreateMessage();
            var MyHeader = new MyMessageHeader(/* snip */);
            reply.Headers.Add(MyHeader);
            req.Stop(MyCore.Status.SUCCESS);
        }
        protected MyCore.SecretThings CreateSecretThings(string key, Dictionary<string, string> ids)
        {
            /* snip */
            return _My.GetSecretThings(/* snip */);
        }
    }
}