MessageProcessingContext.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.ServiceModel;
  5. using System.ServiceModel.Channels;
  6. namespace System.ServiceModel.Dispatcher
  7. {
  8. internal class MessageProcessingContext
  9. {
  10. OperationContext operation_context;
  11. RequestContext request_context;
  12. Message incoming_message;
  13. Message reply_message;
  14. InstanceContext instance_context;
  15. Exception processingException;
  16. DispatchOperation operation;
  17. UserEventsHandler user_events_handler;
  18. public MessageProcessingContext (OperationContext opCtx)
  19. {
  20. operation_context = opCtx;
  21. request_context = opCtx.RequestContext;
  22. incoming_message = opCtx.IncomingMessage;
  23. user_events_handler = new UserEventsHandler (this);
  24. }
  25. public DispatchOperation Operation
  26. {
  27. get { return operation; }
  28. set { operation = value; }
  29. }
  30. public Exception ProcessingException
  31. {
  32. get { return processingException; }
  33. set { processingException = value; }
  34. }
  35. public Message ReplyMessage
  36. {
  37. get { return reply_message; }
  38. set { reply_message = value; }
  39. }
  40. public InstanceContext InstanceContext
  41. {
  42. get { return instance_context; }
  43. set { instance_context = value; }
  44. }
  45. public Message IncomingMessage
  46. {
  47. get { return incoming_message; }
  48. set { incoming_message = value; }
  49. }
  50. public RequestContext RequestContext
  51. {
  52. get { return request_context; }
  53. set { request_context = value; }
  54. }
  55. public OperationContext OperationContext
  56. {
  57. get { return operation_context; }
  58. set { operation_context = value; }
  59. }
  60. public UserEventsHandler EventsHandler
  61. {
  62. get { return user_events_handler; }
  63. set { user_events_handler = value; }
  64. }
  65. public void Reply (IDuplexChannel channel, bool useTimeout)
  66. {
  67. EventsHandler.BeforeSendReply ();
  68. if (useTimeout && Operation.Parent.ChannelDispatcher != null) // FIXME: this condition is a workaround for NRE, there might be better way to get timeout value.
  69. channel.Send (ReplyMessage, Operation.Parent.ChannelDispatcher.timeouts.SendTimeout);
  70. else
  71. channel.Send (ReplyMessage);
  72. }
  73. public void Reply (bool useTimeout)
  74. {
  75. EventsHandler.BeforeSendReply ();
  76. if (useTimeout && Operation.Parent.ChannelDispatcher != null) // FIXME: this condition is a workaround for NRE, there might be better way to get timeout value.
  77. RequestContext.Reply (ReplyMessage, Operation.Parent.ChannelDispatcher.timeouts.SendTimeout);
  78. else
  79. RequestContext.Reply (ReplyMessage);
  80. }
  81. }
  82. #region user events implementation
  83. internal class UserEventsHandler
  84. {
  85. MessageProcessingContext request_context;
  86. DispatchRuntime dispatch_runtime;
  87. IClientChannel channel;
  88. object [] msg_inspectors_states;
  89. object [] callcontext_initializers_states;
  90. public UserEventsHandler (MessageProcessingContext mrc)
  91. {
  92. request_context = mrc;
  93. dispatch_runtime = mrc.OperationContext.EndpointDispatcher.DispatchRuntime;
  94. msg_inspectors_states = new object [dispatch_runtime.MessageInspectors.Count];
  95. channel = request_context.OperationContext.Channel as IClientChannel;
  96. }
  97. public void AfterReceiveRequest ()
  98. {
  99. Message message = request_context.IncomingMessage;
  100. for (int i = 0; i < dispatch_runtime.MessageInspectors.Count; ++i)
  101. msg_inspectors_states [i] = dispatch_runtime.MessageInspectors [i].AfterReceiveRequest (
  102. ref message, channel, request_context.InstanceContext);
  103. request_context.IncomingMessage = message;
  104. }
  105. public void BeforeSendReply ()
  106. {
  107. Message toBeChanged = request_context.ReplyMessage;
  108. for (int i = 0; i < dispatch_runtime.MessageInspectors.Count; ++i)
  109. dispatch_runtime.MessageInspectors [i].BeforeSendReply (ref toBeChanged, msg_inspectors_states [i]);
  110. }
  111. public void BeforeInvoke (DispatchOperation operation)
  112. {
  113. callcontext_initializers_states = new object [operation.CallContextInitializers.Count];
  114. for (int i = 0; i < callcontext_initializers_states.Length; ++i)
  115. callcontext_initializers_states [i] = operation.CallContextInitializers [i].BeforeInvoke (
  116. request_context.InstanceContext, channel, request_context.IncomingMessage);
  117. }
  118. public void AfterInvoke (DispatchOperation operation)
  119. {
  120. for (int i = 0; i < callcontext_initializers_states.Length; ++i)
  121. operation.CallContextInitializers [i].AfterInvoke (callcontext_initializers_states [i]);
  122. }
  123. }
  124. #endregion
  125. }