Skip to content

Instantly share code, notes, and snippets.

@jagt
Created December 6, 2015 03:12
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jagt/e940218f5f4308867549 to your computer and use it in GitHub Desktop.
Save jagt/e940218f5f4308867549 to your computer and use it in GitHub Desktop.
Castle Dynamic Proxy Example
using System;
using System.Collections.Generic;
using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy;
// http://kozmic.net/2008/12/16/castle-dynamicproxy-tutorial-part-i-introduction/
public interface IFreezable
{
bool IsFrozen { get; }
void Freeze();
}
public static class Freezable
{
public static readonly IDictionary<object, IFreezable> _freezables = new Dictionary<object, IFreezable>();
private static readonly ProxyGenerator _generator = new ProxyGenerator();
public static bool IsFreezable(object obj)
{
return obj != null && _freezables.ContainsKey(obj);
}
public static void Freeze(object freezable)
{
if (!IsFreezable(freezable))
{
throw new System.Exception("not freezable object: " + freezable.GetHashCode());
}
_freezables[freezable].Freeze();
}
public static bool IsFrozen(object freezable)
{
return IsFreezable(freezable) && _freezables[freezable].IsFrozen;
}
public static T MakeFreezable<T>() where T : class, new()
{
var interceptor = new FreezableInterceptor();
var proxy = _generator.CreateClassProxy<T>(new CallLoggingInterceptor(), interceptor);
_freezables.Add(proxy, interceptor);
return proxy;
}
}
public class CallLoggingInterceptor : IInterceptor
{
private int indentation;
public void Intercept(IInvocation invocation)
{
try
{
indentation++;
Console.WriteLine(string.Format("{0} ! {1}", new string(' ', indentation), invocation.Method.Name));
invocation.Proceed();
}
finally
{
indentation--;
}
}
}
public class FreezableInterceptor : IInterceptor, IFreezable
{
private bool _isFrozen;
public bool IsFrozen
{
get
{
return _isFrozen;
}
}
public void Freeze()
{
_isFrozen = true;
}
public void Intercept(IInvocation invocation)
{
if (_isFrozen && invocation.Method.Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
{
throw new Exception("Object Frozen");
}
invocation.Proceed();
}
}
public class Person
{
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public override string ToString()
{
return FirstName + " " + LastName;
}
}
class Program
{
static void Main(string[] args)
{
Person p = Freezable.MakeFreezable<Person>();
p.FirstName = "Foo";
p.LastName = "Bar";
Console.WriteLine(p);
Freezable.Freeze(p);
p.FirstName = "what";
Console.WriteLine(p);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment