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-36 extracted from chapter .NET Remoting


Listing 22-35<     > Listing 23-1


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


Example_22_36.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 CustomDisplayContextAttribute(bool 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) {
      DataContext dc = new DataContext(10);
      ctor.LogicalCallContext.SetData("TheDataID",dc);
      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 CustomDisplayMessageSink(IMessageSink 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.
// 
[CustomDisplayContextAttribute(true)]
public class Foo : ContextBoundObject {
   public Foo() {
      Console.WriteLine("   Foo ctor");
   }
   public int Ajout(int a, int b) {
      Console.WriteLine("   Add {0}+{1}", a, b);
      return a + b;
   }
   public int AjoutCross(Foo tmp, int a, int b) {
      Console.WriteLine("   Cross Add {0}+{1}", a, b);
      return tmp.Ajout(a, b);
   }
}

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


public class DataContext : ILogicalThreadAffinative {
   public int Data;
   public DataContext(int 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