About Me

My photo
My Name is Ashish Mishra and MCA Post graduate from premier institute having more than 6 years of work exposure in the field of Software Development & Engineering services and over 6 years in total. Presently I am working as a Sr. Software Engineer for Sapient in Dot Net 3.5/4.0 Framework, BizTalk Server2009 and SQL Server 2008 (SSIS and SSRS). My role as an SSE requires me to work as a team that develops and tests software to fulfill business requirements of the clients. A large part of my time is spent in learning & enhancing technical and Business knowledge. I also have a prime role in preparing documents, coding and testing the application and troubleshooting. To espouse respect from the team, I have to work extra hard on learning new skills and abilities.

Saturday, 30 July 2011

Building Smart Objects for WPF Binding with Validation Support in .NET 4.0


Synopsis:
We would like to build an object which has in-built support to change notification support and different types of validation features including Required, Regular Expression and Custom validations without having to add INotifyPropertyChanged interface implementation in the component. Interesting? Read the following article.
Article:
Problem Statement:
As we know, WPF supports very good data binding features bound to CLR Objects / XML data source providers. In order to avail binding in an object, of course, we have to make sure that the object at-least supports the implementation of INotifyPropertyChanged interface if we can’t have Dependency Properties. So, when it comes to simple properties, we need to ensure that all properties setter implementation triggers an event to notify to update the values in the User Interface. If your component has more number of properties,  it suddenly becomes cluttered in the code. And over a period of time, it is very difficult to maintain the solution as well.
Solution:
Having said this, by taking advantages of .NET 4.0 Dynamic Programming capabilities, it becomes sort of a relief in creating such components very easily. Idea goes like this …
We would like to have our object as simple as possible, like the example given below.
public class Employee
{
[Required(ErrorMessage = "Id Required")]
public string EmployeeId { get; set; }
[Required(ErrorMessage = "Name Required")]
public string EmployeeName { get; set; }
[Range(2000, 50000, ErrorMessage = "Package Offered Not In Range")]
public int PackageOffered { get; set; }
[RegularExpression(@"\d{3,5}-\d{6,8}", ErrorMessage = @"Phone Not Valid")]
public string Phone { get; set; }
public override string ToString()
{
return string.Format(@”{0}, {1}, {2}, {3}”,
this.EmployeeId, this.EmployeeName, this.PackageOffered, this.Phone);
}
}
Note: No implementation of INotifyPropertyChanged interface has been provided in the Employee component.
Let’s now build a general purpose component which accepts a Generic Type, and inherits DynamicObject of .NET 4.0 to encapsulate such that all calls made toEmployee class get diverted to this component. And this class going to provide the implementation of INotifyPropertyChanged interface, and apply validation logic as well.
We would call this component as DynamicBaseEntity, and will have mainly two important method implementations such as TryGetMember and TrySetMember to perform dynamic setting and getting values and validations. And, in many cases we might need to convert the our Dynamic Object into original object ie., Employee. So, we could be able to pass entity objects into subsequent layers.
public class DynamicBaseEntity<T> : DynamicObject, INotifyPropertyChanged where T : new()
{
private Type tType = typeof(T);
private object instance = default(object);
public DynamicBaseEntity()
{
instance = new T();
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var isSuccess = default(bool);
var property = tType.GetProperty(binder.Name, BindingFlags.Public | BindingFlags.Instance);
result = default(object);
if (property == null)
return isSuccess;
result = property.GetValue(instance, null);
isSuccess = true;
return result != null && isSuccess;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var isSuccess = default(bool);
var property = tType.GetProperty(binder.Name, BindingFlags.Public | BindingFlags.Instance);
if (property == null)
return isSuccess;
value = Convert.ChangeType(value, property.PropertyType);
property.SetValue(instance, value, null);
var attributes = property.GetCustomAttributes(typeof(ValidationAttribute), true);
foreach (ValidationAttribute attribute in attributes)
Validator.ValidateProperty(value, new ValidationContext(instance, null, null)
{
MemberName = property.Name
});
Notify(binder.Name);
isSuccess = true;
return isSuccess;
}
private void Notify(string propertyName)
{
if (propertyName != null && PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public override bool TryConvert(ConvertBinder binder, out object result)
{
result = (T)instance;
return instance != null && result != null;
}
public event PropertyChangedEventHandler PropertyChanged;
}
Let me explain the above implementation.
a. In the constructor we create an instance of the type we intend to.
b. TryGetMember method implemented such that we retrieve value from the original object using Reflection.
c. TrySetMember method has been implemented such that we set the value to the original object using Reflection with appropriate validation execution logic. Along-with, we have also the implementation of change notification.
d. TryConvert method implemented for the sake of retrieving original object from Dynamic Object.
Now have a look at the usage of this DynamicBaseEntity component in a typical application:
public static class MainClass
{
public static void Main(string[] args)
{
dynamic dynamicObject = new DynamicBaseEntity<Employee>();
dynamicObject.PropertyChanged += new PropertyChangedEventHandler((objSender, objArgs) =>
{
Console.WriteLine(“Argument Value Changed : ” + objArgs.PropertyName);
});
try
{
dynamicObject.EmployeeId = “E10001″;
dynamicObject.EmployeeName = “Ramkumar JD”;
dynamicObject.Phone = “080-3984343″;
dynamicObject.PackageOffered = 12000;
}
catch (Exception exceptionObject)
{
Console.WriteLine(“Error : ” + exceptionObject.Message);
}
Employee eObject = (Employee)dynamicObject;
Console.WriteLine(eObject.ToString());
Console.ReadLine();
}
}
I’ve provided an implementation of WPF application which uses this feature.
NOTE: If you see the limitations of this solution, VS 2010 or XAML designer may not offer intellisense support to the type, as we resolve all properties of the object at runtime.
I’ve provided the implementation in the Dynamic Object such a way that it throws an exception when you try to set / get a property which is not found in the type we intend to dynamically work on.
Hope it benefits you and reduces our effort in building Entity objects that support Data Binding for WPF applications.
Looking for complete source code with a sample application?
Click here to continue downloading from SkyDrive.