C# 4.0 New Features: Optional Parameters in Methods

Microsoft has provided several new features in .Net 4.0 and among them one which i found a very useful and handy is that now instead of making overloaded methods developer can just make a single method and make the parameters as optional.

Following OOPs people used to write overloaded methods for handling multiple parameters in different way. Lets suppose you have a method named Execute() and following are the overloaded methods.


void Execute(int a){}
void Execute(int a, int b){}
void Execute(int a, int b, int c){}

Using .Net framework 4.0 you dont need to create multiple overloaded methods and you just have to create one as follows.


void Execute(int a, int optionalB = 0, int optionalC = 0)
{

}

And it can be called as follows.


Execute(1);
Execute(1,2);
Execute(1,2,3);

We can also pass the parameters in different orders considering the same method as follows.


Execute(optionalB: 2, optionalC: 3, a:1);

You only need to denote the parameter name followed with a colon and the framework automatically sets the value to that order parameter have in the method signature.

Utilizing LINQ to SQL in Multi Tier Architecture

Normally LINQ to SQL seems to be designed for 2 -tier program, especially when we use Visual Studio to visually create entities and DataContexts. No doubt, this is a very rapid way of developing a data access layer and using its classes for data operations. But when developing an enterprise application which is divided into multiple layers i.e. Data Access Layer, Business Layer, Service Layer and Presentation layer, etc. then developer gets confused in separating the business objects with the data access layer and to make them loosely coupled.

However, in order to utilize the LINQ to SQL for enterprise architecture I did some R & D and came to know that there are some methods supported by LINQ to SQL which helps to design a data access layer that is independent with the business objects. This helps the developer to use the same business objects even they are data contracts (specifically when talking in terms of WCF framework) or any other common business types.

Below procedure shows the way you can utilize the LINQ to SQL in multi tier architecture.

1. Create a Data Types layer which contains all types of business objects.
2. Create an empty BaseEntity class by which all the business objects will be inherited from. You can also put common properties under BaseEntity class like CreatedOn, CreatedBy, UpdatedOn, UpdatedBy usually common in all business objects.

public class BaseEntity
{

}

3. Now create a business object in our example its “Condition” class. [Note the property name should be equal to the result set column names of the procedure being called].

public class Condition :BaseEntity
{
Int32 conditionId;
public Int32 ConditionId
{
get { return conditionId; }
set { conditionId = value; }
}

String conditionName;
public String ConditionName
{
get { return conditionName; }
set { conditionName = value; }
}

String conditionDescription;
public String ConditionDescription
{
get { return conditionDescription; }
set { conditionDescription = value; }
}
}

4. Now create a Data Access Layer. Create a class Library Project and add LinqToSql, you may notice that .dbml file will be added into the solution. This provides the datacontext classes available to perform data operations.

5. Next, create a PersistanceManager class and adds following method. Here I have developed a wrapper of LINQ to SQL ExecuteQuery which provides the automatic binding of the type T and returns the List of T.

public List ExecuteQuery(String queryName, params Object[] param) where T : DataTypes.BaseEntity
{
List lst = new List();
using (DDMSDataContext context = new DDMSDataContext())
{
var items = context.ExecuteQuery(typeof(T), queryName, param);
foreach (var item in items)
{
T t;
t = (T)item;
lst.Add(t);
}
}
return lst;
}

As shown above, this method executes the procedure with the parameters supplied and returns the business object List to user. Once this is done you can call this method from Business layer or any other layer as follows

public List GetAllMedicalConditionsByConditionType(Int32 TypeId)
{
List lstMedConditions = PersistanceManager.GetInstance().ExecuteQuery("Exec SelectAllActiveMedicalConditionsByConditionType {0}", TypeId);
return lstMedConditions;
}

Dynamic Binding of SharePoint Lists with .Net Business Objects

Dynamic Binding of SharePoint Lists with .Net Business Objects

This document highly detailing the binding of .Net business objects with SharePoint list and also provides a framework which provides dynamic support of CRUD operations, In which the developer only needs to define a business object and mapping with list and its fields, rest will be done by the framework itself.
First of all, develop two class Attributes namely ListAttribute and FieldAttribute

a. ListAttribute maps the SharePoint List Name.
b. FieldAttribute maps the column of SharePoint list.

Code Snippet for ListAttribute

[AttributeUsage(AttributeTargets.Class)]
public class ListAttribute
{
string listName;

public ListAttribute(String _listName)
{
this.listName = _listName;
}

public string ListName
{
get { return this.listName; }
}
}

Code snippet for FieldAttribute

[AttributeUsage(AttributeTargets.Property)]
public class FieldAttribute : Attribute
{

public FieldAttribute(String listItemName)
{
this.listItemName = listItemName;
}
string listItemName;

public string ListItemName
{
set { this.listItemName = value; }
get { return this.listItemName; }
}
}

Now let’s develop the custom list named Demo in SharePoint and specify Title, Description, Date columns.

Develop the business object for Demo list. Below code snippet shows the class details. Business Object class is derived from the parent class BaseEntity. Reason of binding is that the framework supports generic methods for all types of CRUD operations, this benefits the business objects that are derived from the BaseEntity to be passed as a parameter.

[ListAttribute("Demo")]
public class TripLogList: BaseEntity
{
string title;
[FieldAttribute("Title")]
public string Title {
set { this.title = value; }
get { return this.title; }
}

string description;
[FieldAttribute("Description")]
public string Description
{
set { this.description = value; }
get { return this.description; }
}

DateTime dateTime;
[FieldAttribute("Date")]
public DateTime DateTime
{
set { this.dateTime = value; }
get { return this.dateTime; }
}

Int32 id;
[FieldAttribute("ID")]
public Int32 Id
{
set { this.id = value; }
get { return this.id; }
}
}

Develop windows form through which we can manipulate SharePoint list items and can perform Insert, update, delete and load operations.

Below screen shows all the items stored in the Demo list

Framework provides the PersistanceManager object through which the developer can directly call Insert, Update, Delete and LoadAll methods and these operations will be performed by the PersistanceManager itself. Developer does not need to manually bind the SharePoint list items with business objects and depending on the fieldname specified, automatic binding will be done on loading, insertion, updation and deletion of list.

To Insert,

Demo demoObj = new Demo();
demoObj.Title = txtitle.Text;
demoObj.Description = txtDescription.Text;
demoObj.DateTime = dtPicker.Value;
PersistanceManager.GetInstance().Insert(demoObj);

To update,

Demo demoObj = new Demo();
demoObj.Id = Convert.ToInt32(row.Cells["id"].Value.ToString());
demoObj.Title= row.Cells["Title"].Value.ToString();
demoObj.Description=row.Cells["Description"].Value.ToString();
demoObj.DateTime = Convert.ToDateTime(row.Cells["DateTime"].Value);
PersistanceManager.GetInstance().Update(demoObj);

To delete,

Demo demoObj = new Demo();
demoObj.Id = Convert.ToInt32(row.Cells["id"].Value.ToString());
PersistanceManager.GetInstance().Delete(demoObj);

To LoadAll,

ArrayList lst=PersistanceManager.GetInstance().LoadAll(typeof(Demo));

grdView.DataSource=lst; // Binding datasoure with datagridview object.

Framework Classes/Interfaces

IDataManager

An interface which contains generic methods. When defining new Persistance Manager for any data source this interface should be derived with it.

interface IDataManager
{
void Insert(BaseEntity baseEntity);
void Update(BaseEntity baseEntity);
void Delete(BaseEntity baseEntity);
ArrayList LoadAll(Type type);
}

SPPersistanceManager

Persistance Manager class for SharePoint. This class implements the Insert, Update, Delete and LoadAll operations. For e.g if you have SQL Server datasource you need to develop a new class named SQLPersistanceManager and defines implements IDataManager methods.

public class SPPersistanceManager : IDataManager
{

String siteURL = System.Configuration.ConfigurationSettings.AppSettings.Get("SharePointSite");

//Load All Items

public ArrayList LoadAll(Type type)
{

ArrayList objlist = new ArrayList();

using (SPSite site = new SPSite(siteURL))
{
using (SPWeb web = site.OpenWeb())
{
String listName=FrameworkFacade.GetInstance().GetListName(type);
ArrayList fieldList = (ArrayList)FrameworkFacade.GetInstance().GetFields(type);
SPList list=web.Lists[listName];
foreach (SPListItem item in list.Items)
{
Demo tripLogObject = new Demo();

foreach (String fieldName in fieldList)
{

FrameworkFacade.GetInstance().SetFieldValue(tripLogObject, fieldName, item[fieldName]);

}
objlist.Add(tripLogObject);
}
}
}
return objlist;
}

//Insert Implementation

public void Insert(BaseEntity obj)
{
ArrayList fieldList = (ArrayList)FrameworkFacade.GetInstance().GetFields(obj.GetType());
using (SPSite site = new SPSite(siteURL))
{
using (SPWeb web = site.OpenWeb())
{
SPList myList = web.Lists[FrameworkFacade.GetInstance().GetListName(obj.GetType())];
SPListItem myListItem = myList.Items.Add();

foreach (String fieldName in fieldList)
{
if (!fieldName.Equals("ID"))
{
myListItem[fieldName] = FrameworkFacade.GetInstance().GetFieldValue(obj, fieldName);
}

}
web.AllowUnsafeUpdates = true;
myListItem.Update();
web.AllowUnsafeUpdates = false;
}
}
}

//Update Implementation

public void Update(BaseEntity obj)
{

using (SPSite site = new SPSite(siteURL))
{
using (SPWeb web = site.OpenWeb())
{
SPList myList = web.Lists[FrameworkFacade.GetInstance().GetListName(obj.GetType())];
SPListItem item = myList.GetItemById(Convert.ToInt32(FrameworkFacade.GetInstance().GetFieldValue(obj, "ID")));
ArrayList arrFields = FrameworkFacade.GetInstance().GetFields(obj.GetType());
foreach (String fieldName in arrFields)
{
if(fieldName!="ID")
item[fieldName] = FrameworkFacade.GetInstance().GetFieldValue(obj, fieldName);

}

item.Update();
}
}

}

//Delete Implementation

public void Delete(BaseEntity obj)
{

using (SPSite site = new SPSite(siteURL))
{
using (SPWeb web = site.OpenWeb())
{
SPList myList = web.Lists[FrameworkFacade.GetInstance().GetListName(obj.GetType())];
Int32 value = Convert.ToInt32(FrameworkFacade.GetInstance().GetFieldValue(obj, "ID").ToString());
myList.Items.DeleteItemById(value);
}
}

}

}

FrameworkFacade

FrameworkFacade is a core class which traverses object metadata through reflection and helps to retrieve properties, custom attributes and setting or getting property values, invoking methods etc.

public class FrameworkFacade
{
static Object _lock = new Object();
static FrameworkFacade instance = null;
private FrameworkFacade() { }
public static FrameworkFacade GetInstance() {
lock (_lock)
{
return (instance == null) ? new FrameworkFacade() : instance;
}

}

//Get Field value
public Object GetFieldValue(Object obj, String propertyAttributeName)
{
object fieldValue = null;
Type type = obj.GetType();
var props = type.GetProperties();
foreach (System.Reflection.PropertyInfo propInfo in props)
{
Object[] propertyAttribute = propInfo.GetCustomAttributes(typeof(FieldAttribute), true);
if (((FieldAttribute)propertyAttribute[0]).ListItemName == propertyAttributeName)
{
System.Reflection.MethodInfo methodInfo =
propInfo.GetGetMethod();
fieldValue = methodInfo.Invoke(obj, null);
break;
}

}

return fieldValue.ToString();
}

//Set Field Value

public void SetFieldValue(Object obj, String propertyAttributeName, Object value)
{

Type type = obj.GetType();
var props = type.GetProperties();
foreach (System.Reflection.PropertyInfo propInfo in props)
{
Object[] propertyAttribute = propInfo.GetCustomAttributes(typeof(FieldAttribute), true);
if (((FieldAttribute)propertyAttribute[0]).ListItemName == propertyAttributeName)
{

if (propInfo.CanWrite)
{
propInfo.SetValue(obj, value, null);
}

break;
}
}
}

//Get ListAttribute value from type

public String GetListName(Type type)
{
String name = type.Assembly.FullName;
object[] obj = type.GetCustomAttributes(typeof(ListAttribute), true);
ListAttribute listAttribute = (ListAttribute)obj[0];
return listAttribute.ListName;

}

//Get All Fields from Type.

public System.Collections.ArrayList GetFields(Type type)
{
System.Collections.ArrayList fieldProperties = new System.Collections.ArrayList();
string name = type.Assembly.FullName;
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(type.Assembly.Location);
System.Reflection.PropertyInfo[] propInfo = type.GetProperties();
foreach (System.Reflection.PropertyInfo property in propInfo)
{
object[] propAttributes = property.GetCustomAttributes(typeof(FieldAttribute), true);
foreach (object obj in propAttributes)
{
String fieldValue = ((FieldAttribute)obj).ListItemName;
fieldProperties.Add(fieldValue);
}
}
return fieldProperties;
}
#endregion
}

Offline Document Uploader in SharePoint 2010

A week ago i was just exploring Sharepoint 2010 Client Object model and have developed a utility which transfers all the documents from the windows folder to the Sharepoint document library. 

Following are the steps to develop Offline Document uploader in SharePoint 2010 using Client Object Model.

1. Create a menu item which opens files uploader utility from windows folder’s context menu.

                                        

In order to create custom menu item in windows, we have to place an entry into registry. 

I have first defined the two constant string variables as shown below that contains path to create a menu in the registry. You might have noticed that i have mentioned “Folder” at starting in both the values. This means that i want to create a context menu item at folder level. Otherwise if i place ” * ” it will be created at files, folder etc.

private const string MenuName = "Folder\\shell\\CMenuOption";
private const string Command= "Folder\\shell\\CMenuOption\Command";

Following is a code snippet that creates menu item at folder level. You can place it on any event. I have created two textboxes on a windows form i.e. txtMenuName and txtExecutablePath. In the txtMenuName textbox, i’ve  specified menu item name and in the txtExecutablePath i’ve specified the .exe path of an application which transfers file to sharepoint library.

Here is the complete code which creates a menu item into the registry.
           
RegistryKey regmenu = null;
            RegistryKey regcmd = null;
            try
            {
                regmenu = Registry.ClassesRoot.CreateSubKey(MenuName);
                if (regmenu != null)
                    regmenu.SetValue("", this.txtMenuName.Text);
                regcmd = Registry.ClassesRoot.CreateSubKey(Command);
                if (regcmd != null)
                    regcmd.SetValue("", this.txtExecutablePath.Text+ " \"%1\"");
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.ToString());
            }
            finally
            {
                if (regmenu != null)
                    regmenu.Close();
                if (regcmd != null)
                    regcmd.Close();
            }

Now there is a separate console application which sends the files from the folder path to the SharePoint document library. Following is the code snippet.

 
static void Main(string[] args)
        {

            String filepath =  args[0].ToString();
            Console.WriteLine(filepath);
            Console.WriteLine("Processing Documents");
            String[] files = Directory.GetFiles(filepath);

            String docLibrary= System.Configuration.ConfigurationSettings.AppSettings.Get("DocLibrary").ToString();
            String SPSiteURL= System.Configuration.ConfigurationSettings.AppSettings.Get("SPSiteURL").ToString();

            ClientContext context = new ClientContext(SPSiteURL);
            foreach (String fileName in files)
            {
                using(FileStream fileStream= new FileStream(fileName,FileMode.Open))
                {
                    Console.WriteLine("Uploading file = " + fileName);
                    Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, "/"+ docLibrary + "/" + Path.GetFileName(fileName), fileStream, true);
                    Console.WriteLine("Uploaded");
                }
            }
 }

Finally, When the user clicks on “Upload files to SP” a console application runs and uploads all the documents in the Sharepoint document library.

                                                 

Figure shows the Console Application uploading documents into SP doc library.

                                                 

                                                           Figure shows the documents uploaded in the SP doc library.