A while back, Nick posted how you can use the Spring .NET Framework to have Design by Contract with AOP.  I’ve been talking to him about you can do the same thing using a .NET remoting proxy to your object and intercept the calls to your objects.  To do this, I needed three classes: An attribute to initialize the attaching at class level for wiring the AOP guts, a class that wires up the AOP guts and a sink that performs the interception.  This is a modified version of Nick’s code:

using System;
using 
System.Reflection;
using 
System.Runtime.Remoting.Activation;
using 
System.Runtime.Remoting.Contexts;
using 
System.Runtime.Remoting.Messaging;

namespace 
Lozanotek
{    
    
public interface IEvaluator
    {
        
bool Evaluate(object arg);
    
}

    [AttributeUsage(AttributeTargets.Method, AllowMultiple 
= true, Inherited = true)]
    
public class PrologAttribute : Attribute
    {
        
private int index;
        public 
IEvaluator evaluator;

        public 
PrologAttribute() { }

        
public PrologAttribute(int index, Type evalType, params object[] args)
        {
            
this.Index index;
            
Object obj Activator.CreateInstance(evalType, args);

            if 
(obj != null)
                
this.evaluator obj as IEvaluator;
        
}

        
public IEvaluator Evaluator
        {
            
get return evaluator}
            
set { evaluator = value; }
        }

        
public int Index
        {
            
get return index}
            
set { index = value; }
        }

        
public bool Evaluate(object arg) { return evaluator.Evaluate(arg)}
    }

    
public class StringLengthEvaluator : IEvaluator
    {
        
private int min 0;
        private int 
max 0;

        public 
StringLengthEvaluator(int min, int max)
        {
            
this.min min;
            this
.max max;
        
}

        
public bool Evaluate(object arg)
        {
            
int len arg.ToString().Length;
            return 
(len <max) && (len >min);
        
}
    }

    [AttributeUsage(AttributeTargets.Class)]
    
public class AOPClassAttribute : Attribute, IContextAttribute
    {
        
public void GetPropertiesForNewContext(IConstructionCallMessage msg)
        {
            msg.ContextProperties.Add(
new AOPProperty());
        
}

        
public bool IsContextOK(Context ctx, IConstructionCallMessage msg) { return false; }
    }

    
internal class AOPProperty : IContextProperty, IContributeServerContextSink
    {
        
public AOPProperty() { }

        
public void Freeze(Context newContext) { }

        
public bool IsNewContextOK(Context newCtx) { return true; }

        
public string Name 
        {
            
get return "AOPProperty"
        }

        
public IMessageSink GetServerContextSink(IMessageSink nextSink) 
        { 
            
return new AOPMessageSink(nextSink)
        
}
    }

    
internal class AOPMessageSink : IMessageSink
    {
        
private IMessageSink next;

        public 
AOPMessageSink(IMessageSink next) { this.next next}

        
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) { return null; }

        
public IMessageSink NextSink 
        { 
            
get return next
        }

        
public IMessage SyncProcessMessage(IMessage msg)
        {
            
bool proceed = true;

            if 
(msg is IMethodMessage)
            {
                proceed 
Invoke(msg as IMethodMessage);
            
}

            
return (proceed) ? NextSink.SyncProcessMessage(msg) :
                
new ReturnMessage(nullnull0null, (IMethodCallMessage) msg);
        
}

        
private bool Invoke(IMethodMessage msg)
        {
            
bool results = true;
            
MethodBase method msg.MethodBase;
            
Type attrType = typeof(PrologAttribute);
            
PrologAttribute[] prologs method.GetCustomAttributes(attrType, trueas PrologAttribute[];

            if 
(prologs != null)
            {
                
foreach (PrologAttribute pl in prologs)
                {
                    
if (pl != null)
                    {
                        IEvaluator eval 
pl.Evaluator as IEvaluator;

                        if 
(eval != null)
                        {
                            
object[] args msg.Args;
                            
results eval.Evaluate(args[pl.Index]);

                            if 
(!results) { break; }
                        }
                    }
                }
            }

            
return results;
        
}
    }

    [AOPClass]
    
public class Person : ContextBoundObject
    {
        [Prolog(
0typeof(StringLengthEvaluator), 05)]
        
public void SayHello(string name)
        {
            Console.WriteLine(
"Hello {0}", name);
        
}
    }

    
class Program
    {
        [STAThread]
        
static void Main(string[] args)
        {
            Person p 
= new Person();

            
p.SayHello("Javier");
            
p.SayHello("Jav");
            
            
Console.ReadLine();
        
}
    }
}

If you have any questions or comments, let me know.