Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Friday, March 16, 2012

Extending the Value Injector beyond one level properties mapping between entities

For many enterprises application, we may have entities in different layer and we would be needing an easy way to map the properties between them. There are many options available but I used Value Injector.

But this has two problems :

  1. It will not work for nested properties. It just converts the one level properties which are basic types
  2. It will not work for IEnumerable types.

The good thing that l like about Value Injector is it is extendable. So this how I solved both the above problems.

Extend ConventionInjection to write logic for multiple inner level mappings. This code uses the power of reflection and recursion to go into multiple inner levels.

public class CloneInjection : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Value != null;
}

protected override object SetValue(ConventionInfo c)
{
//for value types and string just return the value as is
if (c.SourceProp.Type.IsValueType || c.SourceProp.Type == typeof(string))
{
return c.SourceProp.Value;
}

//handle arrays
if (c.SourceProp.Type.IsArray)
{
var arr = c.SourceProp.Value as Array;
var clone = arr.Clone() as Array;

for (int index = 0; index < arr.Length; index++)
{
var a = arr.GetValue(index);
if (a.GetType().IsValueType || a.GetType() == typeof(string)) continue;
clone.SetValue(Activator.CreateInstance(a.GetType()).InjectFrom<CloneInjection>(a), index);
}
return clone;
}


if (c.SourceProp.Type.IsGenericType)
{
//handle IEnumerable<> also ICollection<> IList<> List<>
if (c.SourceProp.Type.GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable)))
{
var t = c.SourceProp.Type.GetGenericArguments()[0];

if (t.IsValueType || t == typeof(string))
{
return c.SourceProp.Value;
}

t = c.TargetProp.Type.GetGenericArguments()[0];

var tlist = typeof(List<>).MakeGenericType(t);
var list = Activator.CreateInstance(tlist);

var addMethod = tlist.GetMethod("Add");
foreach (var o in c.SourceProp.Value as IEnumerable)
{
var e = Activator.CreateInstance(t).InjectFrom<CloneInjection>(o);
addMethod.Invoke(list, new[] { e }); // in 4.0 you can use dynamic and just do list.Add(e);
}
return list;
}

//unhandled generic type, you could also return null or throw
return c.SourceProp.Value;
}

//for simple object types create a new instance and apply the clone injection on it
return Activator.CreateInstance(c.TargetProp.Type)
.InjectFrom<CloneInjection>(c.SourceProp.Value);
}

Use this custom Injection class while mapping between two entities so that irrespective of multiple nested properties, you can easily clone to different type


Ex:


 

target.InjectFrom<CloneInjection>(source);

Write your own Extension method to consider mapping between two enumerable or any type entities. Again here also we check of generic types for two entities and if they are IEnumerable, construct the list items of target type using reflection and add it to target object

public static object InjectCompleteFrom(this object target, object source)
{
if (target.GetType().IsGenericType &&
target.GetType().GetGenericTypeDefinition() != null &&
target.GetType().GetGenericTypeDefinition().GetInterfaces() != null &&
target.GetType().GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable)) &&
source.GetType().IsGenericType &&
source.GetType().GetGenericTypeDefinition() != null &&
source.GetType().GetGenericTypeDefinition().GetInterfaces() != null &&
source.GetType().GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable)))
{
var t = target.GetType().GetGenericArguments()[0];

var tlist = typeof(List<>).MakeGenericType(t);
var addMethod = tlist.GetMethod("Add");

foreach (var sourceItem in source as IEnumerable)
{
var e = Activator.CreateInstance(t).InjectFrom<CloneInjection>(sourceItem);
addMethod.Invoke(target, new[] { e });
}

return target;
}
else
{
return target.InjectFrom<CloneInjection>(source);
}
}

This is how you will need to use it:

IEnumerable<Category> categoryList = categoryService.GetAll();
IList<CategoryViewModel> viewModelList = new List<CategoryViewModel>();
viewModelList.InjectCompleteFrom(categoryList);

I have answered question related to this at http://stackoverflow.com/questions/7872405/how-to-map-lists-with-valueinjector/9735614#9735614


I will plan to add this in my MVC tool kit project at http://mvctoolkit.codeplex.com/


To know more about this project, refer http://sureshballa.blogspot.in/2012/03/my-first-community-contribution-mvc.html

Saturday, March 3, 2012

My First Community Contribution - MVC Tool Kit Framework

 

I like the fact that Microsoft started supporting open source java script frameworks like JQuery, JQuery Validations etc. And now Microsoft is also going to start supporting Knockout JS which is great framework for data bindings with MVVM pattern. Also now web is slowly moving towards HTML 5 leaving away all proprietary frameworks like flash and Silverlight. Considering all these, I always had a wish that reusable features/controls that leverages the power of HTML5, Knockout JS(client JS library based on MVVM pattern) and data annotations would be great value add to developer which abstracts all underlying technologies that I mentioned and gives the super powers. Out of this is what came out is “MVC Tool Kit Framework” Yes, I have started creating some reusable features and wanted to make available to public. 1st release is out and you can get it from http://mvctoolkit.codeplex.com/. Thanks to my organization Neudesic for supporting this activity.

 

So what does this framework have?

At high level these are the features that it provides:

  1. Basic Input Control that supports HTML 5, Knockout JS and custom attributes in Data Annotations
  2. Validation Framework and some common validation attributes
  3. Checkbox list control that doesn’t exists in ASP.NET MVC

So what's so great about this framework?

Use this framework for normal ASP.NET MVC post back or with Knockout JS framework. Additionally get the benefits of  custom data annotation attributes and validation attributes that are present in this framework.

Input Controls

Each of input controls have these parameters:

  1. Expression<Func<TModel, TProperty>> expression: This is the model property expression for which you want the control to bind.
  2. InputType inputType: This is to specify what type of input control you want. The frame work supports all HTML 5 input types - Text, Color, Date, Datetime, DatetimeLocal, Email, Month, Number, Range, Search,Tel, Time, Url, Week
  3. object htmlAttributes: This is for any html attributes that you would wanted to be generated.
  4. object dataAttributes: This is for generating html 5 data attributes (data-*)
  5. KOBinding<TModel>[] koBindAttributes: This is for generating Knockout data bind attributes. The specialty about this parameter is that you can bind Knockout bindings based on server model itself
  6. object koCustomBindAttributes: Use this parameter for Knockout data bind attributes to bind some properties to custom defined JS model properties or methods which will not be in server side model.

All of the above parameters (except the 1st one) are optional parameters.

Specific to HTML 5 attributes, these controls will generate the following additional attributes also:

  1. placeholder (based on data annotation meta attribute Html5PlaceholderAttribute)
  2. required (based on data annotation RequiredAttribute which is system attribute)
  3. patters (based on data annotation RegularExpressionAttribute which is system attribute)

Note: Html5PlaceholderAttribute is custom attribute defined in this framework, if you wish to use this attribute, please register the CustomModelMetadataProvider (defined as part of this framework) in your global.ascx file.

image

Usage

image

will generate

image

Validation Framework

The following attributes are defined which can be used for Model validation.

  • Comparer. Use this to have some comparison rule between model properties. Example:

imageimage                          This attribute supports following comparison attributes: EqualTo, NotEqualTo, GreaterThan, GreaterThanEqualTo, LessThan, LessThanEqualTo

  • RequiredIf: Required validation based on other property. Example: image

Also validation framework has utilities that can validate the model at any time (at presentation layer, business layer etc.) to ensure its following all the rules defined to it has validation attributes.

image

 

The code hosted at http://mvctoolkit.codeplex.com/ also has web sample that has usage of these framework features. So go ahead and start using it.

I wish to see some more ideas to extend this framework and comments on this. Please reach out to me at suresh.balla@neudesic.com for any questions/ suggestions. Contributions are welcome for this framework.

I plan to add more complex controls in future and extend this framework. Follow the project at codeplex for the updates. I will also post the updates here in my blog.

Saturday, October 15, 2011

Aspect Oriented Programming

After some years of programming in top down (C language) and object oriented (C++, Java and C#) approaches, recently in one my assignment I had to work on new type of programming approach. Yes, as the blog title suggest, the new approach is known/called as Aspect Oriented Programming or simply AOP. When I heard this for the first time, I thought new kind of programming approach but I realized this approach is basically adding meta data to MSIL and then altering the execution behavior accordingly. But why do we need to do this? Why cannot we achieve the same with normal programming? Like these, there were many questions popped up in my mind. To get answers to these questions, I dived deep into this area and learned how we can use this model for enterprise applications. (AOP in .NET is achieved via custom attributes in .NET)

The Technical Problem – Cross-Cutting Concerns

All good programming practice aims to organize software code according the principle of separation of concerns. Ideally, each software requirement is implemented in a separate source code artifact. In object-oriented programming (OOP), the basic unit of organization is the class. Code in classes is segmented internally by fields (discrete units of information), methods (discrete units of functionality), and events (discrete units of reaction). Common families of classes are themselves organized into namespaces.

The standard OOP approach has proven an excellent model for code architecture and organization. It falls short, however, when developers must implement cross-cutting concerns – behaviors that are used across a large number of business requirements, and cannot easily be isolated.

Some of the cross-cutting concerns are logging, security auditing, transactions, multithreading etc.

The Effect of Cross-Cutting Concerns

In a typical OOP approach, cross-cutting behaviors are factored into separate classes, which are then instantiated and called directly by business logic code. This forces business logic code to be intimately aware of these cross-cutting concerns and creates numerous problems for the architecture and code quality of an OOP application

  1. The number of lines of code increase
  2. An enormous amount of code is duplicated
  3. Business logic code becomes entangled with cross-cutting code
  4. Business logic code is tightly coupled to cross-cutting concerns

The end result of this approach to cross-cutting concerns is a code base that is hard to author, hard to maintain, and hard to debug.

A Framework for Cross-Cutting Behaviors

These shortcomings aren't an indictment of the object-oriented paradigm, which has proven highly successful as a model of code architecture. What's needed is an enhancement to this paradigm that enables the addition of cross-cutting behaviors. Ideally, such an enhancement or framework would enable:

  • adding cross-cutting concerns with little or no modification to existing business logic code;
  • applying these behaviors to multiple methods, classes, or even namespaces and assemblies with minimal additional code;
  • enhancing cross-cutting logic without the need to revise code in the business object;
  • eliminating redundant boilerplate code that must be copied from method to method.

Meta Programming - Aspect Oriented Programming comes to rescue

Meta programming, which has been made popular by dynamic languages, allows programs to change their behavior extensively at both runtime and build time.

AOP is a specific case of meta-programming. However, AOP operates at a higher level of abstraction.

Aspect Oriented Programming – Introduction

The sole purpose of aspect-oriented programming (AOP) is to provide a cleaner separation of concerns in complex applications, especially where cross-cutting behavior is concerned.

AOP Terminology

Aspect: a modularization of a concern that cuts across multiple classes.Join point: a point during the execution of a program, such as the execution of a method or the handling of an exception. Advice: action taken by an aspect at a particular join point. Different types of advice include "around," "before" and "after" advice. Weaving: linking aspects with other application types or objects to create an advised object. This can be done at compile time, load time, or at runtime.

PostSharp – .NET framework for Aspect Oriented Programming

PostSharp is a .NET framework for Aspect Oriented Programming from SharpCrafters. It has very simple attributes for instrumentation, security, user interface, multithreading and many more.

PostSharp is the leading AOP framework in the Microsoft ecosystem. Several Microsoft products, such as Windows Communication Framework and ASP.NET MVC, provide a subset of AOP features, but Microsoft has always been reluctant to use the term aspect-oriented programming, preferring the terms “filters” or “behaviors” instead. And these are noting but custom attributes in .NET.

It takes more effort and time and also difficult for me to explain everything in this blog post, so posting some of the screenshots for easy overview. 

 

image

 

Logging:

image

Exception Handling:

image

Authorization:

image

NotifyPropertyChanged support (User Interface):

image

Undo and Redo:

image

Multithreading:

image

Thread synchronization:

image

Note: Some of the content in this blog post is from different internet resources.

Tuesday, September 20, 2011

Is BackgroundWorker really thread safe component for WinForms?

 
Under certain circumstances the BackgroundWorker Component's ProgressChanged event and RunWorkerCompleted event will run on the wrong thread
Microsoft claims (for updating the UI controls based on work that us getting done by background thread):

“The preferred way to implement multithreading in your desktop based application is to use the BackgroundWorker component. The BackgroundWorker component uses an event-driven model for multithreading. The background thread runs your DoWork event handler, and the thread that creates your controls runs your ProgressChanged and RunWorkerCompleted event handlers. You can call your controls from your ProgressChanged and RunWorkerCompleted event handlers.”
Claim link: http://msdn.microsoft.com/en-us/library/ms171728.aspx
 
But intermittently I have experienced under certain circumstances the BackgroundWorker Component's ProgressChanged event and RunWorkerCompleted event will run on the wrong thread (probably by worker thread itself). I was surprised by this. When these event run under wrong thread, I get cross thread error. So to solve this I had check under which thread these events are running and perform actions under the thread that has created the UI control. For this we need to use InvokeRequired property and Invoke method as shown below:

(This approach is what we follow if we use our own thread and not this component)

 
if(control.InvokeRequired)
  control.Invoke(Action);
else
  Action()
 
InvokeRequired:
Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on.
Invoke():
Executes the specified delegate on the thread that owns the control's underlying window handle.