Created
August 11, 2009 20:51
-
-
Save kkozmic/166110 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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