Created
December 6, 2015 03:12
-
-
Save jagt/e940218f5f4308867549 to your computer and use it in GitHub Desktop.
Castle Dynamic Proxy Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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