Skip to content

Instantly share code, notes, and snippets.

@kkozmic
Created August 11, 2009 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkozmic/166110 to your computer and use it in GitHub Desktop.
Save kkozmic/166110 to your computer and use it in GitHub Desktop.
namespace INPC.Using.Dynamic.Proxy
{
using System;
using System.ComponentModel;
using System.Reflection;
using Castle.Core.Interceptor;
using Castle.DynamicProxy;
class Program
{
static void Main(string[] args)
{
var generator = new ProxyGenerator();
var options = new ProxyGenerationOptions(new SetterProxyHook());
options.Selector = new SetterInterceptorSelector();
options.AddMixinInstance(new NotifyPropertyChanged());
var proxy = generator.CreateClassProxy(typeof (SomeDto), options, new PropertyChangedInterceptor());
(proxy as INotifyPropertyChanged).PropertyChanged +=
((sender, e) => Console.WriteLine("Property " + e.PropertyName + " changed!"));
var dto = proxy as SomeDto;
dto.CreatedAt = DateTime.UtcNow;
Console.ReadKey();
}
}
public class SetterInterceptorSelector:IInterceptorSelector
{
public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
{
if (MethodHelper.IsNotifierMethod(method))
return new IInterceptor[0];
return interceptors;
}
}
public static class MethodHelper
{
public static bool IsNotifierMethod(MethodInfo info)
{
return info.DeclaringType.IsAssignableFrom(typeof(NotifyPropertyChanged));
}
}
public class SetterProxyHook:IProxyGenerationHook
{
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return IsSetter(methodInfo) || MethodHelper.IsNotifierMethod(methodInfo);
}
private bool IsSetter(MethodInfo info)
{
// this is very naive implementation
return info.Name.StartsWith("set_");
}
public void NonVirtualMemberNotification(Type type, MemberInfo memberInfo)
{
}
public void MethodsInspected()
{
}
}
public class PropertyChangedInterceptor:IInterceptor
{
public void Intercept(IInvocation invocation)
{
var notifier = invocation.Proxy as INotifier;
invocation.Proceed();
notifier.RaiseChanged(invocation.Proxy, invocation.Method.Name.Substring("set_".Length));
}
}
public class NotifyPropertyChanged:INotifier
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public void RaiseChanged(object target,string propertyName)
{
PropertyChanged(target, new PropertyChangedEventArgs(propertyName));
}
}
public interface INotifier:INotifyPropertyChanged
{
void RaiseChanged(object target, string propertyName);
}
public class SomeDto
{
public Guid Id { get; set; }
public virtual DateTime? LastUpdatedAt { get; set; }
public virtual DateTime? CreatedAt { get; set; }
// etc...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment