Skip to content

Instantly share code, notes, and snippets.

@runceel
Created April 20, 2012 08:21
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 runceel/2427098 to your computer and use it in GitHub Desktop.
Save runceel/2427098 to your computer and use it in GitHub Desktop.
INotifyPropertyChanged Implementation
using System;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using System.ComponentModel;
using Microsoft.Practices.Unity.InterceptionExtension;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Practices.Unity;
namespace ConsoleApplication4
{
public class Person : INotifyPropertyChanged
{
public virtual event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string name)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public virtual string Name { get; set; }
private int age;
public int Age
{
get { return age; }
set
{
this.age = value;
this.RaisePropertyChanged("Age");
this.RaisePropertyChanged("Name");
}
}
}
public class NotifyPropertyChangedBehavior : IInterceptionBehavior
{
private static readonly EventInfo PropertyChangedEventInfo = typeof(INotifyPropertyChanged).GetEvent("PropertyChanged");
private event PropertyChangedEventHandler handler;
public IEnumerable<Type> GetRequiredInterfaces()
{
yield return typeof(INotifyPropertyChanged);
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
if (input.MethodBase.Name == PropertyChangedEventInfo.GetAddMethod().Name)
{
var d = input.Arguments[0] as PropertyChangedEventHandler;
this.handler += d;
return getNext()(input, getNext);
}
if (input.MethodBase.Name == PropertyChangedEventInfo.GetRemoveMethod().Name)
{
var d = input.Arguments[0] as PropertyChangedEventHandler;
this.handler -= d;
return getNext()(input, getNext);
}
if (input.MethodBase.IsSpecialName && input.MethodBase.Name.StartsWith("set_"))
{
var result = getNext()(input, getNext);
var name = input.MethodBase.Name.Substring(4);
if (this.handler != null)
{
this.handler(input.Target, new PropertyChangedEventArgs(name));
}
return result;
}
return getNext()(input, getNext);
}
public bool WillExecute
{
get { return true; }
}
}
class Program
{
static void Main(string[] args)
{
var c = new UnityContainer();
c.AddNewExtension<Interception>();
c.RegisterType<Person>(
new Interceptor<VirtualMethodInterceptor>(),
new InterceptionBehavior<NotifyPropertyChangedBehavior>());
var p = c.Resolve<Person>();
p.PropertyChanged += (_, e) => Console.WriteLine(e.PropertyName);
p.Name = "a";
p.Name = "bbb";
p.Age = 10;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment