System.Runtime.Remoting.ServerIdentity.GetServerObjectChain C# (CSharp) Метод

GetServerObjectChain() приватный Метод

private GetServerObjectChain ( MarshalByRefObject &obj ) : IMessageSink
obj System.MarshalByRefObject
Результат IMessageSink
        internal IMessageSink GetServerObjectChain(out MarshalByRefObject obj)
        {
            obj = null;
            // NOTE: Lifetime relies on the Identity flags for 
            // SingleCall and Singleton being set by the time this getter 
            // is called.
                if (!this.IsSingleCall())
                {
                    // This is the common case 
                    if (_serverObjectChain == null) 
                    {
                        bool fLocked = false;
                        RuntimeHelpers.PrepareConstrainedRegions();
                        try
                        {
                            Monitor.ReliableEnter(this, ref fLocked);
                            if(_serverObjectChain == null)
                            {
                                MarshalByRefObject srvObj = 
                                    (MarshalByRefObject) 
                                        this.TPOrObject;

                                _serverObjectChain = 
                                    _srvCtx.CreateServerObjectChain(
                                        srvObj);
                                    
                            }
                        }   
                        finally
                        {
                            if (fLocked)
                            {
                                Monitor.Exit(this);
                            }
                        }
                    }
                    BCLDebug.Assert( null != _serverObjectChain, 
                        "null != _serverObjectChain");

                    return _serverObjectChain;                    
                }
                else 
                {
                    // ---------- SINGLE CALL WKO --------------
                    // In this case, we are expected to provide 
                    // a fresh server object for each dispatch.
                    // Since the server object chain is object 
                    // specific, we must create a fresh chain too.

                    // We must be in the correct context for this
                    // to succeed.


                    BCLDebug.Assert(Thread.CurrentContext==_srvCtx,
                                    "Bad context mismatch");

                    MarshalByRefObject srvObj = null;
                    IMessageSink objChain = null;
                    if (_tpOrObject != null && _firstCallDispatched == 0 && Interlocked.CompareExchange(ref _firstCallDispatched, 1, 0) == 0)
                    {
                        // use the instance of server object created to 
                        // set up the pipeline.
                        srvObj = (MarshalByRefObject) _tpOrObject;

                        objChain = _serverObjectChain;

                        if (objChain == null)
                        {
                            objChain = _srvCtx.CreateServerObjectChain(srvObj);
                        }
                    }
                    else
                    {
                        // For singleCall we create a fresh object & its chain
                        // on each dispatch!
                        srvObj = (MarshalByRefObject)
                                 Activator.CreateInstance((Type)_srvType, true);

                        // make sure that object didn't Marshal itself.
                        // (well known objects should live up to their promise
                        // of exporting themselves through exactly one url)
                        String tempUri = RemotingServices.GetObjectUri(srvObj);
                        if (tempUri != null)
                        {
                            throw new RemotingException(
                                String.Format(
                                              CultureInfo.CurrentCulture, Environment.GetResourceString(
                                "Remoting_WellKnown_CtorCantMarshal"),
                                              this.URI));
                        }

                        // Set the identity depending on whether we have the server
                        // or proxy
                        if(!RemotingServices.IsTransparentProxy(srvObj))
                        {

#if _DEBUG
                            Identity idObj = srvObj.__RaceSetServerIdentity(this);
#else
                            srvObj.__RaceSetServerIdentity(this);
#endif
#if _DEBUG
                            BCLDebug.Assert(idObj == this, "Bad ID state!" );             
                            BCLDebug.Assert(idObj == MarshalByRefObject.GetIdentity(srvObj), "Bad ID state!" );             
#endif
                        }
                        else
                        {
                            RealProxy rp = null;
                            rp = RemotingServices.GetRealProxy(srvObj);
                            BCLDebug.Assert(null != rp, "null != rp");
                            //  #if _DEBUG
                            //                      Identity idObj = (ServerIdentity) rp.SetIdentity(this);
                            // #else
                            rp.IdentityObject = this;
                            // #endif 
                        }
                        // Create the object chain and return it
                        objChain = _srvCtx.CreateServerObjectChain(srvObj);
                    }

                    // This is passed out to the caller so that for single-call
                    // case we can call Dispose when the incoming call is done
                    obj = srvObj;
                    return objChain;
                }
        }