通常,您可以像这样从OperationContextget the service instance

OperationContext.Current.InstanceContext.GetServiceInstance()


但是,当您使用IAuthorizationPolicy时,InstanceContext为null。托管在IIS中时,还有另一种获取服务实例的方法吗?

最佳答案

IAuthorizationPolicy.Evaluate()中,OperationContext.Current.InstanceContext并不总是为null。

Carlos Figueira’s WCF Extensibility test program开头,每次调用WCF扩展名时,该命令都会在命令行中显示一条消息。我添加了一个自定义的IAuthorizationPolicy。输出和程序如下。

输出显示


创建服务实例后调用IAuthorizationPolicy.Evaluate()
OperationContext.Current.InstanceContextIAuthorizationPolicy.Evaluate()中不为空


测试程序是使用BasicHttpBinding自托管的。在其他托管环境中,很有可能IAuthorizationPolicy.Evaluate()无法访问服务实例,但至少在理论上是可行的。

你为什么要这样做?

从体系结构的角度来看,IAuthorizationPolicy应该处理声明。该应用程序应该使用ClaimsPrinciple上的索赔。将IAuthorizationPolicy与特定服务紧密耦合会破坏Window Identity体系结构中非常有意的关注点分离。换句话说,我认为这是一个坏主意。

测试程序

这是一个Windows命令行程序,位于一个文件中。

using System;
using System.Globalization;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading;
using System.Collections.Generic;

namespace WcfRuntime
{
    class MyDispatchMessageInspector : IDispatchMessageInspector
    {
        public MyDispatchMessageInspector()
        {
        }

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
        }
    }

    class MyDispatchMessageFormatter : IDispatchMessageFormatter
    {
        IDispatchMessageFormatter inner;
        public MyDispatchMessageFormatter(IDispatchMessageFormatter inner)
        {
            this.inner = inner;
        }

        public void DeserializeRequest(Message message, object[] parameters)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            this.inner.DeserializeRequest(message, parameters);
        }

        public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.SerializeReply(messageVersion, parameters, result);
        }
    }

    class MyClientMessageInspector : IClientMessageInspector
    {
        public MyClientMessageInspector()
        {
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            ColorConsole.WriteLine(ConsoleColor.Yellow, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            ColorConsole.WriteLine(ConsoleColor.Yellow, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return null;
        }
    }

    class MyClientMessageFormatter : IClientMessageFormatter
    {
        IClientMessageFormatter inner;
        public MyClientMessageFormatter(IClientMessageFormatter inner)
        {
            this.inner = inner;
        }

        public object DeserializeReply(Message message, object[] parameters)
        {
            ColorConsole.WriteLine(ConsoleColor.Yellow, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.DeserializeReply(message, parameters);
        }

        public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
        {
            ColorConsole.WriteLine(ConsoleColor.Yellow, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.SerializeRequest(messageVersion, parameters);
        }
    }

    class MyDispatchOperationSelector : IDispatchOperationSelector
    {
        public string SelectOperation(ref Message message)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            string action = message.Headers.Action;
            string method = action.Substring(action.LastIndexOf('/') + 1);
            return method;
        }
    }

    class MyParameterInspector : IParameterInspector
    {
        ConsoleColor consoleColor;
        bool isServer;
        public MyParameterInspector(bool isServer)
        {
            this.isServer = isServer;
            this.consoleColor = isServer ? ConsoleColor.Cyan : ConsoleColor.Yellow;
        }

        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            ColorConsole.WriteLine(this.consoleColor, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
        }

        public object BeforeCall(string operationName, object[] inputs)
        {
            ColorConsole.WriteLine(this.consoleColor, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return null;
        }
    }

    class MyCallContextInitializer : ICallContextInitializer
    {
        public void AfterInvoke(object correlationState)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
        }

        public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return null;
        }
    }

    class MyOperationInvoker : IOperationInvoker
    {
        IOperationInvoker inner;
        public MyOperationInvoker(IOperationInvoker inner)
        {
            this.inner = inner;
        }

        public object[] AllocateInputs()
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.AllocateInputs();
        }

        public object Invoke(object instance, object[] inputs, out object[] outputs)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.Invoke(instance, inputs, out outputs);
        }

        public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.InvokeBegin(instance, inputs, callback, state);
        }

        public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.InvokeEnd(instance, out outputs, result);
        }

        public bool IsSynchronous
        {
            get
            {
                ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
                return this.inner.IsSynchronous;
            }
        }
    }

    class MyInstanceProvider : IInstanceProvider
    {
        Type serviceType;
        public MyInstanceProvider(Type serviceType)
        {
            this.serviceType = serviceType;
        }

        public object GetInstance(InstanceContext instanceContext, Message message)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return Activator.CreateInstance(this.serviceType);
        }

        public object GetInstance(InstanceContext instanceContext)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return Activator.CreateInstance(this.serviceType);
        }

        public void ReleaseInstance(InstanceContext instanceContext, object instance)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
        }
    }

    class MyInstanceContextProvider : IInstanceContextProvider
    {
        IInstanceContextProvider inner;
        public MyInstanceContextProvider(IInstanceContextProvider inner)
        {
            this.inner = inner;
        }

        public InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.GetExistingInstanceContext(message, channel);
        }

        public void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            this.inner.InitializeInstanceContext(instanceContext, message, channel);
        }

        public bool IsIdle(InstanceContext instanceContext)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return this.inner.IsIdle(instanceContext);
        }

        public void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            this.inner.NotifyIdle(callback, instanceContext);
        }
    }

    class MyInstanceContextInitializer : IInstanceContextInitializer
    {
        public void Initialize(InstanceContext instanceContext, Message message)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
        }
    }

    class MyChannelInitializer : IChannelInitializer
    {
        ConsoleColor consoleColor;
        public MyChannelInitializer(bool isServer)
        {
            this.consoleColor = isServer ? ConsoleColor.Cyan : ConsoleColor.Yellow;
        }
        public void Initialize(IClientChannel channel)
        {
            ColorConsole.WriteLine(this.consoleColor, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
        }
    }

    class MyClientOperationSelector : IClientOperationSelector
    {
        public bool AreParametersRequiredForSelection
        {
            get
            {
                ColorConsole.WriteLine(ConsoleColor.Yellow, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
                return false;
            }
        }

        public string SelectOperation(MethodBase method, object[] parameters)
        {
            ColorConsole.WriteLine(ConsoleColor.Yellow, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return method.Name;
        }
    }

    class MyInteractiveChannelInitializer : IInteractiveChannelInitializer
    {
        public IAsyncResult BeginDisplayInitializationUI(IClientChannel channel, AsyncCallback callback, object state)
        {
            ColorConsole.WriteLine(ConsoleColor.Yellow, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            Action act = new Action(this.DoNothing);
            return act.BeginInvoke(callback, state);
        }

        public void EndDisplayInitializationUI(IAsyncResult result)
        {
            ColorConsole.WriteLine(ConsoleColor.Yellow, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
        }

        private void DoNothing() { }
    }

    class MyErrorHandler : IErrorHandler
    {
        public bool HandleError(Exception error)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            return error is ArgumentException;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            ColorConsole.WriteLine(ConsoleColor.Cyan, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));
            MessageFault messageFault = MessageFault.CreateFault(new FaultCode("FaultCode"), new FaultReason(error.Message));
            fault = Message.CreateMessage(version, messageFault, "FaultAction");
        }
    }

    public class MyAuthorizationPolicy : IAuthorizationPolicy
    {
        string id;
        public MyAuthorizationPolicy()
        {
            id = Guid.NewGuid().ToString();
        }

        public bool Evaluate(EvaluationContext evaluationContext, ref object state)
        {
            ColorConsole.WriteLine(ConsoleColor.Green, "{0}.{1}", this.GetType().Name, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod()));

            if (OperationContext.Current.InstanceContext != null)
            {
                var instance = (Service)OperationContext.Current.InstanceContext.GetServiceInstance();
                ColorConsole.WriteLine(ConsoleColor.Green, "Got the service instance. Name={0}", instance.Name);
            }
            else
            {
                ColorConsole.WriteLine(ConsoleColor.Green, "OperationContext.Current.InstanceContext is null");
            }

            // Return true, indicating that this method does not need to be called again.
            return true;
        }

        public ClaimSet Issuer
        {
            get { return ClaimSet.System; }
        }

        public string Id
        {
            get { return id; }
        }
    }

    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        int Add(int x, int y);
        [OperationContract(IsOneWay = true)]
        void Process(string text);
    }

    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class Service : ITest
    {
        public Service() { ColorConsole.WriteLine(ConsoleColor.Green, "Created Service Instance"); }

        public string Name { get { return "MyService instance 1234"; } }

        public int Add(int x, int y)
        {
            ColorConsole.WriteLine(ConsoleColor.Green, "In service operation '{0}'", MethodBase.GetCurrentMethod().Name);

            if (x == 0 && y == 0)
            {
                throw new ArgumentException("This will cause IErrorHandler to be called");
            }
            else
            {
                return x + y;
            }
        }

        public void Process(string text)
        {
            ColorConsole.WriteLine(ConsoleColor.Green, "In service operation '{0}'", MethodBase.GetCurrentMethod().Name);
        }
    }

    class MyBehavior : IOperationBehavior, IContractBehavior
    {
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
            clientOperation.Formatter = new MyClientMessageFormatter(clientOperation.Formatter);
            clientOperation.ParameterInspectors.Add(new MyParameterInspector(false));
        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            dispatchOperation.CallContextInitializers.Add(new MyCallContextInitializer());
            dispatchOperation.Formatter = new MyDispatchMessageFormatter(dispatchOperation.Formatter);
            dispatchOperation.Invoker = new MyOperationInvoker(dispatchOperation.Invoker);
            dispatchOperation.ParameterInspectors.Add(new MyParameterInspector(true));
        }

        public void Validate(OperationDescription operationDescription)
        {
        }

        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ChannelInitializers.Add(new MyChannelInitializer(false));
            clientRuntime.InteractiveChannelInitializers.Add(new MyInteractiveChannelInitializer());
            clientRuntime.MessageInspectors.Add(new MyClientMessageInspector());
            clientRuntime.OperationSelector = new MyClientOperationSelector();
        }

        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
            dispatchRuntime.ChannelDispatcher.ChannelInitializers.Add(new MyChannelInitializer(true));
            dispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(new MyErrorHandler());
            dispatchRuntime.InstanceContextInitializers.Add(new MyInstanceContextInitializer());
            dispatchRuntime.InstanceContextProvider = new MyInstanceContextProvider(dispatchRuntime.InstanceContextProvider);
            dispatchRuntime.InstanceProvider = new MyInstanceProvider(dispatchRuntime.ChannelDispatcher.Host.Description.ServiceType);
            dispatchRuntime.MessageInspectors.Add(new MyDispatchMessageInspector());
            dispatchRuntime.OperationSelector = new MyDispatchOperationSelector();
        }

        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
        }
    }

    static class ColorConsole
    {
        static object syncRoot = new object();

        public static void WriteLine(ConsoleColor color, string text, params object[] args)
        {
            if (args != null && args.Length > 0)
            {
                text = string.Format(CultureInfo.InvariantCulture, text, args);
            }

            lock (syncRoot)
            {
                Console.ForegroundColor = color;
                Console.WriteLine("[{0}] {1}", DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture), text);
                Console.ResetColor();
            }

            Thread.Sleep(50);
        }

        public static void WriteLine(string text, params object[] args)
        {
            Console.WriteLine(text, args);
        }

        public static void WriteLine(object obj)
        {
            Console.WriteLine(obj);
        }
    }

    static class ReflectionUtil
    {
        public static string GetMethodSignature(MethodBase method)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(method.Name);
            sb.Append("(");
            ParameterInfo[] parameters = method.GetParameters();
            for (int i = 0; i < parameters.Length; i++)
            {
                if (i > 0) sb.Append(", ");
                sb.Append(parameters[i].ParameterType.Name);
            }
            sb.Append(")");
            return sb.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
            using (ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)))
            {
                ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
                endpoint.Contract.Behaviors.Add(new MyBehavior());
                foreach (OperationDescription operation in endpoint.Contract.Operations)
                {
                    operation.Behaviors.Add(new MyBehavior());
                }

                var polices = new List<IAuthorizationPolicy>();
                polices.Add(new MyAuthorizationPolicy());
                host.Authorization.ExternalAuthorizationPolicies = polices.AsReadOnly();

                host.Open();
                ColorConsole.WriteLine("Host opened");

                using (ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress)))
                {
                    factory.Endpoint.Contract.Behaviors.Add(new MyBehavior());
                    foreach (OperationDescription operation in factory.Endpoint.Contract.Operations)
                    {
                        operation.Behaviors.Add(new MyBehavior());
                    }

                    ITest proxy = factory.CreateChannel();
                    ColorConsole.WriteLine("Calling operation");
                    ColorConsole.WriteLine(proxy.Add(3, 4));

                    //ColorConsole.WriteLine("Called operation, calling it again, this time it the service will throw");
                    //try
                    //{
                    //    ColorConsole.WriteLine(proxy.Add(0, 0));
                    //}
                    //catch (Exception e)
                    //{
                    //    ColorConsole.WriteLine(ConsoleColor.Red, "{0}: {1}", e.GetType().Name, e.Message);
                    //}

                    //ColorConsole.WriteLine("Now calling an OneWay operation");
                    //proxy.Process("hello");

                    ((IClientChannel)proxy).Close();
                }
            }

            ColorConsole.WriteLine("Done");
        }
    }
}


节目输出

寻找---->。

[12:33:04.218] MyOperationInvoker.get_IsSynchronous()
[12:33:04.269] MyOperationInvoker.get_IsSynchronous()
Host opened
[12:33:04.322] MyChannelInitializer.Initialize(IClientChannel)
Calling operation
[12:33:04.373] MyClientOperationSelector.get_AreParametersRequiredForSelection()
[12:33:04.424] MyClientOperationSelector.SelectOperation(MethodBase, Object[])
[12:33:04.474] MyParameterInspector.BeforeCall(String, Object[])
[12:33:04.524] MyClientMessageFormatter.SerializeRequest(MessageVersion, Object[])
[12:33:04.574] MyClientMessageInspector.BeforeSendRequest(Message&, IClientChannel)
[12:33:04.632] MyInteractiveChannelInitializer.BeginDisplayInitializationUI(IClientChannel, AsyncCallback, Object)
[12:33:04.684] MyInteractiveChannelInitializer.EndDisplayInitializationUI(IAsyncResult)
[12:33:04.788] MyChannelInitializer.Initialize(IClientChannel)
[12:33:04.838] MyInstanceContextProvider.GetExistingInstanceContext(Message, IContextChannel)
[12:33:04.888] MyDispatchOperationSelector.SelectOperation(Message&)
[12:33:04.939] MyInstanceContextProvider.InitializeInstanceContext(InstanceContext, Message, IContextChannel)
[12:33:04.990] MyInstanceContextInitializer.Initialize(InstanceContext, Message)
[12:33:05.040] MyDispatchMessageInspector.AfterReceiveRequest(Message&, IClientChannel, InstanceContext)
[12:33:05.091] MyInstanceProvider.GetInstance(InstanceContext, Message)
[12:33:05.142] Created Service Instance
[12:33:05.192] MyCallContextInitializer.BeforeInvoke(InstanceContext, IClientChannel, Message)
[12:33:05.242] MyOperationInvoker.AllocateInputs()
[12:33:05.293] MyDispatchMessageFormatter.DeserializeRequest(Message, Object[])
[12:33:05.344] MyParameterInspector.BeforeCall(String, Object[])
[12:33:05.394] MyAuthorizationPolicy.Evaluate(EvaluationContext, Object&)
---->[12:33:05.445] Got the service instance. Name=MyService instance 1234
[12:33:05.495] MyOperationInvoker.Invoke(Object, Object[], Object[]&)
[12:33:05.547] In service operation 'Add'
[12:33:05.597] MyParameterInspector.AfterCall(String, Object[], Object, Object)
[12:33:05.648] MyDispatchMessageFormatter.SerializeReply(MessageVersion, Object[], Object)
[12:33:05.698] MyCallContextInitializer.AfterInvoke(Object)
[12:33:05.748] MyDispatchMessageInspector.BeforeSendReply(Message&, Object)
[12:33:05.803] MyInstanceContextProvider.IsIdle(InstanceContext)
[12:33:05.804] MyClientMessageInspector.AfterReceiveReply(Message&, Object)
[12:33:05.854] MyInstanceProvider.ReleaseInstance(InstanceContext, Object)
[12:33:05.855] MyClientMessageFormatter.DeserializeReply(Message, Object[])
[12:33:05.905] MyParameterInspector.AfterCall(String, Object[], Object, Object)

10-08 18:43