Home
Browse all 647 examples
Download all 647 examples
Download sample chapters
Reviews
Errata
Acknowledgments
Links on .NET
Paradoxal Press

Buy directly from Paradoxal Press at $33.99 (Save 43%)



Category: Programming
Level: Beginner to seasoned
900 pages
ISBN-10 097661322-0
ISBN-13 978-097661322-0
$59.99 USA
$79.99 CANADA


Listing 22-35 extracted from chapter .NET Remoting


Listing 22-34<     > Listing 22-36


This listing can be compiled with the command line:
csc.exe /target:exe Example_22_35.cs
Errors: 0 Warnings: 0


Example_22_35.cs
using System;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
using System.Threading;
using System.Collections;

//
// Instances of the context property class inject message sinks
// in all regions.
//
public class CustomDisplayContextProperty :
      IContextProperty,
      IContributeEnvoySink,
      IContributeObjectSink,
      IContributeServerContextSink,
      IContributeClientContextSink {
   public CustomDisplayContextPropertybool bDisplay ) {
      m_bDisplay = bDisplay;
   }
   bool m_bDisplay;
   public bool bDisplay { get return m_bDisplay; } }

   // IContextProperty
   public string Name { get return "PropDisplay"; } }
   public bool IsNewContextOK(Context ctx) { return true; }
   public void Freeze( Context ctx ) {
      Console.WriteLine( "   Freeze ContextID={0}", ctx.ContextID );
   }

   // Inject two message sinks in the 'client' region. 
   public IMessageSink GetClientContextSink( IMessageSink nextSink) {
      Console.WriteLine( "   GetClientContextSink()" );
      IMessageSink nextnextSink = new CustomDisplayMessageSink(
                                 nextSink, "Client region1  ", m_bDisplay);
      return new CustomDisplayMessageSink(
                             nextnextSink, "Client region2  ", m_bDisplay);
   }

   // Inject a message sink in the 'server' region. 
   public IMessageSink GetServerContextSink( IMessageSink nextSink) {
      Console.WriteLine( "   GetServerContextSink()" );
      return new CustomServerMessageSink( nextSink );
   }

   // Inject a message sink in the 'envoy' region. 
   // NOTE: You can use 'mbro' to obtain a reference on the object.
   public IMessageSink GetEnvoySink( MarshalByRefObject mbro,
                                     IMessageSink nextSink) {
      Console.WriteLine( "   GetEnvoySink()" );
      return new CustomEnvoyMessageSink( nextSink );
   }

   // Inject a message sink in the 'object' region. 
   public IMessageSink GetObjectSink( MarshalByRefObject mbro,
                                      IMessageSink nextSink ) {
      Console.WriteLine( "   GetObjectSink()" );
      return new CustomDisplayMessageSink(
                             nextSink, "Object region   ", m_bDisplay);
   }
}

//----------------------------------------------------------------------
//
// Context attribute class. It forces creating a context per object.
// It injects a CustomDisplayContextProperty in each created context.
//
[AttributeUsage(AttributeTargets.Class)]
public class CustomDisplayContextAttribute 
 : AttributeIContextAttribute {
   bool m_bDisplay;
   public CustomDisplayContextAttributebool bDisplay ) { 
     m_bDisplay = bDisplay; 
   }
   // Forces creating a context per object.
   public bool IsContextOK( Context currentCtx,
                            IConstructionCallMessage ctor) {
      return false;
   }

   // Injects a CustomDisplayContextProperty in each created context.
   public void GetPropertiesForNewContext( IConstructionCallMessage ctor ){
      IContextProperty prop = new CustomDisplayContextProperty(m_bDisplay);
      ctor.ContextProperties.Add( prop );
   }
}


//----------------------------------------------------------------------
//
// Instances of the CustomDisplayMessageSink class are message sinks 
// that display info on console.
//
[Serializable]
public class CustomDisplayMessageSink : IMessageSink {
   IMessageSink m_NextSink;
   // Message to display.
   string m_sDisplay;
   // Display only if 'm_bDisplay' is true.
   bool m_bDisplay;

   public IMessageSink NextSink { get return m_NextSink; } }
   public CustomDisplayMessageSinkIMessageSink nextSink,
                                    string sDisplay,
                                    bool bDisplay ) {
      m_NextSink = nextSink;
      m_sDisplay = sDisplay;
      m_bDisplay = bDisplay;
   }
   public IMessage SyncProcessMessage( IMessage msg ) {
      if ( m_bDisplay )
         Console.WriteLine( "   Begin MsgSink:{0} ContextID={1}",
                            m_sDisplay, Thread.CurrentContext.ContextID);
      // Contact next message sink in the chain...
      IMessage retMsg = m_NextSink.SyncProcessMessage( msg );
      if (m_bDisplay)
         Console.WriteLine( "   End   MsgSink:{0} ContextID={1}",
                            m_sDisplay, Thread.CurrentContext.ContextID);
      return retMsg;
   }
   public IMessageCtrl AsyncProcessMessage( IMessage msg,
                                            IMessageSink replySink) {
      return m_NextSink.AsyncProcessMessage( msg, replySink );
   }
}


//----------------------------------------------------------------------
//
// The Foo class that supports the CustomDisplayContextAttribute 
// context attribute. The parameter 'true' means that message sinks
// must display info on console.
// 
[CustomDisplayContextAttributetrue )]
public class Foo : ContextBoundObject {
   public Foo() {
      Console.WriteLine( "   Foo ctor" );
   }
   public int Add( int a, int b ) {
      Console.WriteLine( "   Add {0}+{1}", a, b );
      return a + b;
   }
   public int AddCross( Foo tmp, int a, int b ) {
      Console.WriteLine( "   Cross Add {0}+{1}", a, b );
      return tmp.Add( a, b );
   }
}

//----------------------------------------------------------------------
//
public class Program
{
   static void Main() {
      Console.WriteLine( "Before constructing obj1." );
      Foo obj1 = new Foo();
      Console.WriteLine("Before using obj1.");
      obj1.Add(4,5);
      Console.WriteLine("After using obj1.");
   }
}


public class DataContext : ILogicalThreadAffinative {
   public int Data;
   public DataContextint i ){ Data=i; }
}

[Serializable]
public class CustomEnvoyMessageSink : IMessageSink {
   public IMessage SyncProcessMessage( IMessage msg ){
       DataContext dc = new DataContext691 );
      // Include the data in 'msg'.
      ((IMethodMessage)msg).LogicalCallContext.SetData( "TheDataID" , dc );
      return m_NextSink.SyncProcessMessage( msg );
   }
   IMessageSink   m_NextSink;
   public IMessageSink NextSink { get{  return m_NextSink; } }
   public CustomEnvoyMessageSink(   IMessageSink   NextSink ) {
      m_NextSink =  NextSink;
   }
   public IMessageCtrl AsyncProcessMessage(
      IMessage msg, IMessageSink replySink) {
      return m_NextSink.AsyncProcessMessage( msg, replySink );
   }
}

[Serializable]
public class CustomServerMessageSink : IMessageSink{    
   public IMessage SyncProcessMessage( IMessage msg ){
      // Get the data from 'msg'.
      DataContext dc = DataContext )
        ((IMethodCallMessage)msg).LogicalCallContext.GetData("TheDataID" );
      if( dc != null )
         Console.WriteLine( "   DataContext:" + dc.Data );
      IMessage retMsg = m_NextSink.SyncProcessMessage( msg );
      return retMsg;
   }
   IMessageSink   m_NextSink;
   public IMessageSink NextSink { get{  return m_NextSink;}}
   public CustomServerMessageSink(   IMessageSink   NextSink ) {
      m_NextSink   =   NextSink;
   }
   public IMessageCtrl AsyncProcessMessage(
         IMessage msg, IMessageSink replySink) {
      return m_NextSink.AsyncProcessMessage(msg, replySink);
   }
}	
Copyright Patrick Smacchia 2006 2007