File: MessageProcessingContext.cs

package info (click to toggle)
mono 6.12.0.199%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,296,836 kB
  • sloc: cs: 11,181,803; xml: 2,850,076; ansic: 699,709; cpp: 123,344; perl: 59,361; javascript: 30,841; asm: 21,853; makefile: 20,405; sh: 15,009; python: 4,839; pascal: 925; sql: 859; sed: 16; php: 1
file content (156 lines) | stat: -rw-r--r-- 4,568 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace System.ServiceModel.Dispatcher 
{
	internal class MessageProcessingContext 
	{
		OperationContext operation_context;
		RequestContext request_context;
		Message incoming_message;

		Message reply_message;		
		InstanceContext instance_context;		
		Exception processingException;
		DispatchOperation operation;
		UserEventsHandler user_events_handler;		
		IChannel reply_or_input;

		public MessageProcessingContext (OperationContext opCtx, IChannel replyOrInput)
		{
			operation_context = opCtx;
			request_context = opCtx.RequestContext;
			incoming_message = opCtx.IncomingMessage;
			user_events_handler = new UserEventsHandler (this);
			reply_or_input = replyOrInput;
		}

		public IChannel Channel {
			get { return reply_or_input; }
		}

		public DispatchOperation Operation
		{
			get { return operation; }
			set { operation = value; }
		}

		public Exception ProcessingException
		{
			get { return processingException; }
			set { processingException = value; }
		}
		
		public Message ReplyMessage
		{
			get { return reply_message; }
			set { reply_message = value; }
		}

		public InstanceContext InstanceContext
		{
			get { return instance_context; }
			set { instance_context = value; }
		}

		public Message IncomingMessage
		{
			get { return incoming_message; }
			set { incoming_message = value; }
		}

		public RequestContext RequestContext
		{
			get { return request_context; }
			set { request_context = value; }
		}

		public OperationContext OperationContext
		{
			get { return operation_context; }
			set { operation_context = value; }
		}

		public UserEventsHandler EventsHandler
		{
			get { return user_events_handler; }
			set { user_events_handler = value; }
		}

		public void Reply (IDuplexChannel channel, bool useTimeout)
		{
			EventsHandler.BeforeSendReply ();
			if (useTimeout && Operation.Parent.ChannelDispatcher != null) // FIXME: this condition is a workaround for NRE, there might be better way to get timeout value.
				channel.Send (ReplyMessage, Operation.Parent.ChannelDispatcher.timeouts.SendTimeout);
			else
				channel.Send (ReplyMessage);
		}

		public void Reply (bool useTimeout)
		{
			EventsHandler.BeforeSendReply ();
			if (useTimeout && Operation.Parent.ChannelDispatcher != null) // FIXME: this condition is a workaround for NRE, there might be better way to get timeout value.
				RequestContext.Reply (ReplyMessage, Operation.Parent.ChannelDispatcher.timeouts.SendTimeout);
			else
				RequestContext.Reply (ReplyMessage);
		}
	}

	#region user events implementation

	internal class UserEventsHandler
	{
		MessageProcessingContext request_context;
		DispatchRuntime dispatch_runtime;
		IClientChannel channel;
		object [] msg_inspectors_states;
		object [] callcontext_initializers_states;

		public UserEventsHandler (MessageProcessingContext mrc)
		{
			request_context = mrc;
			dispatch_runtime = mrc.OperationContext.EndpointDispatcher.DispatchRuntime;
			msg_inspectors_states = new object [dispatch_runtime.MessageInspectors.Count];
			channel = request_context.OperationContext.Channel as IClientChannel;
		}

		public void AfterReceiveRequest ()
		{
			Message message = request_context.IncomingMessage;

			for (int i = 0; i < dispatch_runtime.MessageInspectors.Count; ++i)
				msg_inspectors_states [i] = dispatch_runtime.MessageInspectors [i].AfterReceiveRequest (
					   ref message, channel, request_context.InstanceContext);
			request_context.IncomingMessage = message;

		}

		public void BeforeSendReply ()
		{
			Message toBeChanged = request_context.ReplyMessage;
			for (int i = 0; i < dispatch_runtime.MessageInspectors.Count; ++i)
				dispatch_runtime.MessageInspectors [i].BeforeSendReply (ref toBeChanged, msg_inspectors_states [i]);
			request_context.ReplyMessage = toBeChanged;
		}

		public void BeforeInvoke (DispatchOperation operation)
		{
			callcontext_initializers_states = new object [operation.CallContextInitializers.Count];
			for (int i = 0; i < callcontext_initializers_states.Length; ++i)
				callcontext_initializers_states [i] = operation.CallContextInitializers [i].BeforeInvoke (
					request_context.InstanceContext, channel, request_context.IncomingMessage);

		}

		public void AfterInvoke (DispatchOperation operation)
		{
			for (int i = 0; i < callcontext_initializers_states.Length; ++i)
				operation.CallContextInitializers [i].AfterInvoke (callcontext_initializers_states [i]);
		}
	}

	#endregion
}