internal IMessage NotifyActivatorProperties(
IMessage msg, bool bServerSide)
{
BCLDebug.Assert( (msg is IConstructionCallMessage)
|| (msg is IConstructionReturnMessage),
"Bad activation msg type");
BCLDebug.Assert( !((msg is IConstructionCallMessage) &&
(msg is IConstructionReturnMessage)),
"Activation message cannot be both call & return type");
BCLDebug.Assert((_ctxFlags & CTX_FROZEN) == CTX_FROZEN,
"ServerContext not frozen during activation!");
// Any exception thrown by the notifications is caught and
// folded into a return message to return to the caller.
IMessage errMsg = null;
try
{
// Since the context is frozen the properties array is in
// effect read-only!
int iProp = _numCtxProps;
Object prop = null;
while (iProp-- != 0)
{
// see if this property is interested in Activation
prop = _ctxProps[iProp];
IContextPropertyActivator activator = prop as IContextPropertyActivator;
if (null != activator)
{
// yes, notify as appropriate
IConstructionCallMessage ccm = msg as IConstructionCallMessage;
if (null != ccm)
{
// IConsructionCallMessage on its way forward
if (!bServerSide)
{
// activation starting at client side
activator.CollectFromClientContext(ccm);
}
else
{
activator.DeliverClientContextToServerContext(ccm);
}
}
else
{
// IConstructionReturnMessage on its way back
if (bServerSide)
{
// activation returning from server side
activator.CollectFromServerContext((IConstructionReturnMessage)msg);
}
else
{
// activation back at client side
activator.DeliverServerContextToClientContext((IConstructionReturnMessage)msg);
}
}
}
}
}
catch (Exception e)
{
IMethodCallMessage mcm = null;
if (msg is IConstructionCallMessage)
{
mcm = (IMethodCallMessage) msg;
}
else
{
mcm = new ErrorMessage();
}
errMsg = new ReturnMessage(e, mcm);
if (msg != null)
{
((ReturnMessage)errMsg).SetLogicalCallContext(
(LogicalCallContext)
msg.Properties[Message.CallContextKey]);
}
}
return errMsg;
}