Home > C#, Tips, Unity > [EN] #NET #Unity container and INotifyPropertyChanged and POCO

[EN] #NET #Unity container and INotifyPropertyChanged and POCO

One day I had a need to use POCO in my project, and later on I used POCOs in webservice communications as DTOs (some can complain about using POCOs as DTOs see this), and after that I’d like to present or to check if some property was changed by the user on client site, and when it was changed, then I had to do some action. What is more I’d like to use only Microsoft tools without any other non Microsoft frameworks (let’s say at this time). I achieved this using Unity Container with Interceptor, POCOs generated from entity framework database  and one INotifyPropertyChanged interface.

First of all, we will use an POCO objet generated from Entity Framework POCO template. The template generates virtual properties which later on are replaced dynamically for example by the Entity Framework, some example of our POCO (but not generated from template) is presented below:

public class MyPocoClass 
{ 
 public virtual int ID { get; set; } 
 public virtual string Name { get; set; } 
 public virtual DateTime? Date { get; set; } 
}

Next we will create a derived class MyViewModel:

public class MyViewModel: MyPocoClass, INotifyPropertyChanged 
{ 
 public virtual event 
 PropertyChangedEventHandler PropertyChanged; 
} 

Remember, that the PropertyChanged event should be also virtual. You can add Your own properties or methods. Now we have to create our NotifyPropertyChangedBehavior. 95% of the code is available on this MSDN web site, and we will use this code except some changes. The code on MSDN site works more like “inform that a property was set”, so first we will add a ShouldRaiseEvent method (see this post) except, that we will return true when there are no getMethod.

private bool ShouldRaiseEvent(IMethodInvocation input)
{
  string propertyName = input.MethodBase.Name.Substring(4);
  PropertyInfo property =
     input.MethodBase.ReflectedType.GetProperty(propertyName);
  MethodInfo getMethod = property.GetGetMethod();
  if (getMethod == null) return true;
  object oldValue = getMethod.Invoke(input.Target, null);
  object value = input.Arguments[0];
  return value == null
    ? value != oldValue
    : !value.Equals(oldValue);
}

next we will modify the procedure from MSDN code

private IMethodReturn InterceptPropertySet(
  IMethodInvocation input,
  GetNextInterceptionBehaviorDelegate getNext)
{
  var propertyName = input.MethodBase.Name.Substring(4);

  if (ShouldRaiseEvent(input))
  {
    var subscribers = propertyChanged;
    if (subscribers != null)
    {
      subscribers(input.Target,
        new PropertyChangedEventArgs(propertyName));
    }
  }
  var returnValue = getNext()(input, getNext);

  return returnValue;
}

After that, when We create an instance of our MyViewModel, then UnityContainer will handle any property change of any virtual property. This You can see in the result window below the code

using (IUnityContainer container = new UnityContainer())
{
  container
    .AddNewExtension()
    .RegisterType(
      new Interceptor(),
      new InterceptionBehavior(new NotifyPropertyChangedBehavior())
    );
  var viewModel = container.Resolve();
  viewModel.PropertyChanged += (a, b) => Console.WriteLine(b.PropertyName);
  viewModel.ID = 6;
  viewModel.ID = 6;

  viewModel.Date = DateTime.Now;
  viewModel.Date = DateTime.Now;

  viewModel.Name = "Some name";
  viewModel.Name = "Some name";
}


The date can be presented twice because we are using DateTime.Now everytime we set the property, and the result of DateTime.Now can differ.

#Fix – 3rd May 2011

There is one problem with the code above (with the InterceptPropertySet method). In that case, it’s not possible to get the new property value in event method – if You need the value in Your method then You have to update the method with the code below (the fix is not included in sample).

private IMethodReturn InterceptPropertySet(
IMethodInvocation input, 
GetNextInterceptionBehaviorDelegate getNext)
{
  var shouldRaise = ShouldRaiseEvent(input);
  var returnValue = getNext()(input, getNext);
  if (shouldRaise)
  {
    var subscribers = propertyChanged;
    if (subscribers != null)
    {
      var propertyName = input.MethodBase.Name.Substring(4);
      subscribers(input.Target, 
        new PropertyChangedEventArgs(propertyName));
    }
  }
  return returnValue;
}

Links

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: