private static Object GetOrCreateProxy(
Identity idObj, Object proxy, bool fRefine)
{
Message.DebugOut("Entering GetOrCreateProxy for given proxy\n");
// If we are not supplied a proxy then we have to find an existing
// proxy or create one
if (null == proxy)
{
// Get the type of the server object
Type serverType;
ServerIdentity serverID = idObj as ServerIdentity;
if (null != serverID)
{
serverType = serverID.ServerType; // ServerObject.GetType();
}
else
{
BCLDebug.Assert(ObjRef.IsWellFormed(idObj.ObjectRef),
"ObjRef.IsWellFormed(idObj.ObjectRef)");
IRemotingTypeInfo serverTypeInfo = idObj.ObjectRef.TypeInfo;
// For system generated type info we create the proxy for
// object type. Later, when the proxy is cast to the appropriate
// type we will update its internal state to refer to the cast type
// This way we avoid loading the server type till cast time.
//
// For type info generated by others we have no choice but to
// load the type provided by the typeinfo. Sometimes, we
// use this second approach even if the typeinfo has been
// generated by us because this saves us an extra checkcast.
// A typical example of this usage will be when we are
// unmarshaling in parameters. We know that the unmarshal will
// be followed by a check cast to ensure that the parameter type
// matches the signature type, so we do both in one step.
serverType = null;
if (((serverTypeInfo is TypeInfo) && !fRefine) ||
(serverTypeInfo == null))
{
serverType = typeof(System.MarshalByRefObject);
}
else
{
String typeName = serverTypeInfo.TypeName;
if (typeName != null)
{
String typeNamespace = null;
String assemNamespace = null;
TypeInfo.ParseTypeAndAssembly(typeName, out typeNamespace, out assemNamespace);
Assembly assem = FormatterServices.LoadAssemblyFromStringNoThrow(assemNamespace);
if (assem != null)
{
serverType = assem.GetType(typeNamespace, false, false);
}
}
}
if (null == serverType)
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_BadType"),
serverTypeInfo.TypeName));
}
}
Message.DebugOut("Creating Proxy for type " + serverType.FullName + "\n");
proxy = SetOrCreateProxy(idObj, serverType, null);
}
else
{
// We have been supplied with a proxy. Set that proxy in
// the identity object
// Assert that this the activation case only as this code path is
// not thread safe otherwise! (We call Wrap to associate an object
// with its proxy during activation).
BCLDebug.Assert(
((RemotingProxy)GetRealProxy(proxy)).ConstructorMessage!=null,
"Only expect to be here during activation!");
proxy = SetOrCreateProxy(idObj, null, proxy);
}
// At this point we should have a non-null transparent proxy
if (proxy == null)
throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_UnexpectedNullTP")));
BCLDebug.Assert(IsTransparentProxy(proxy),"IsTransparentProxy(proxy)");
Message.DebugOut("Leaving GetOrCreateProxy for given proxy\n");
// Return the underlying transparent proxy
return proxy;
}