Pages

Saturday, February 23, 2013

Passing Parameters to Events - C#

All right , again one post away from my favorite SharePoint world but this is kind of generic which can be used anywhere in C#.

Today we will see how we can pass some custom parameters to any event in C#.

Consider a scenario where you are calling some method asynchronously and execution is happening in loops.
In General, we register an event with the method which gets called after method call is completed. but as the asynchronous execution is happening in the loop , so in the on completed event you never know which for which call the execution has been completed.

Check out this sample scenario where I have a simple windows forms application with two buttons and label, both buttons are registered to a same on click event. Now say, on click of each button I want to perform some independent actions and also want to pass some parameters to the on click event. I know there can be many approaches to do this but I have just taken this example to prove the actual point of this blog post.


public Form1()
{
   InitializeComponent();

   button1.Click += new EventHandler(button_Click);
   button2.Click += new EventHandler(button_Click);
}

void button_Click(object sender, EventArgs e)
{
   label1.Text = "Hi ";
}

Now on both button clicks - the text of a label is printed as 'Hi' as the event is common between both buttons.

Now what I want is to pass some extra information to the on click event from both buttons , you can pass on any number and type of  objects as you want. for the example I will send a string and Enum to click events.

I will also need to modify the button click event , as I am going to send some parameters to event so I need to catch those in the event.

public Form1()
{
  InitializeComponent();

  button1.Click += delegate(object sender, EventArgs e) { button_Click(sender, e, "This is   From Button1", MessageType.B1); };

  button2.Click += delegate(object sender, EventArgs e) { button_Click(sender, e, "This is From Button2", MessageType.B2); };

}

void button_Click(object sender, EventArgs e, string message, MessageType type)
{
   if (type.Equals(MessageType.B1))
   {
      label1.Text = message;
   }
   else if (type.Equals(MessageType.B2))
   {
      label1.Text = message;
   }
}

enum MessageType
{
   B1,
   B2
}


Friday, February 22, 2013

Creating Custom Workflow Activity - Windows Workflow Foundation 4.0


It’s been long since I written new blog post , but today got some time to write one on which I was working recently.
This time it’s little away from SharePoint world, just to stroll Windows Workflow Foundation 4.0. The time I am writing this post, Bollywood music is running over my ears so I am really in mood of writing J

Workflow Foundation

Microsoft has provided us a very strong foundation since release of .NET Framework 3.5 known as Windows Workflow Foundation (WF), and it is getting much better with every release. The latest one is WF 4.0 and is really useful in mapping your business processes to workflows. The basic idea behind any workflow creation is to automate the business processes and do it more declarative way.

Need of Custom Activities

Though the framework provides you lots of inbuilt activities so that you can grab them and directly use in your workflow application as it is, but again in most of the cases business scenarios are complex and requirement cannot be solved directly using out of the box activities. So in such cases what needs to be done? Nothing worry, similar to SharePoint workflows – windows workflow foundation also supports creating custom activities. (Awkward to say but WF seems much much stronger when compared to SharePoint workflow engine). You can also provide input parameters to your activity and activity can return you output which can be later used in the workflow.

Example

Ok enough of theory and let’s get in to the action.
Intentionally I have taken very simple example for demo, it simply uses a custom activity and workflow simply adds a new product in the products database and finishes. Nothing much but just to understand the creation and execution of custom activity.
I will start by creating a project in Visual Studio 2012
Open up visual studio and click on create new project. From left side of new project window – click on workflow category and select Workflow Console Application project.
You will see a Workflow.xaml opened up in the editor. This is basically playground for you where you can start designing you workflow.
If you take a look at left side of the window , you will see something familiar as Toolbox (remember ASP.NET web applications? ) and here is the place where you will find all out of the box activities provided by WF 4.0
I have designed a very simple workflow which prints a line to the windows when workflow starts and do some execution of activities and then again prints line to window when workflow finishes.



Now wait a minute, did you observe something called as AddProduct there in the editor as well as in the toolbox? From where on the earth that came?
Nothing suspicious going on here so don’t worry, this is the custom activity which I created which simply adds a new product in the products inventory. I won’t go in much details of the how I have created the database and used it using the entity framework but we will concentrate more on creating that custom activity and passing parameters to it.

Implementation

Custom activities in the windows workflow foundation are nothing but the class which is derived from a class known as ‘CodeActivity’.
Once you create your own class and derive it from CodeActivity , you will need to override the execute method of the parent class. This method gives you the workflow execution context so that you can play around input and output parameters.
Following code is just for understanding purpose on how we can create custom activity, you can add any complex logic in the execute method.
So here is the AddProduct activity code



public class AddProduct : CodeActivity
{
  public InArgument<int> ProductId { get; set; }
  public InArgument<string> ProductName { get; set; }
  public InArgument<string> ProductDescription { get; set; }
  public InArgument<int> ProductPrice { get; set; }
  public InArgument<int> ProductDiscount { get; set; }
  public OutArgument<string> Result { get; set; }

  protected override void Execute(CodeActivityContext context)
  {
    try
    {
      using (var productEntities = new ProductsEntities())
      {
        productEntities.ProductInfoes.Add(new ProductInfo
        {
           ProductId = ProductId.Get(context),
           ProductName = ProductName.Get(context),
           ProductDescription = ProductDescription.Get(context),
           ProductPrice = ProductPrice.Get(context),
           ProductDiscount = ProductDiscount.Get(context)
         });
         productEntities.SaveChanges();
        }
              
    context.SetValue(Result, "Product with Id : " + context.GetValue(ProductId) + " Added Successfully!!");
     }
     catch (Exception ex)
     {
       context.SetValue(Result, "Error While Adding Product : " + ex.Message);
     }

   }
  }

As you can see that this activity is having 5 input parameters and one output parameter which is later consumed by workflow write line activity (at end of workflow) to display the message to users.
Once you are creating the class and done with implementation of execute method, then just rebuild your solution and observe the toolbox. Framework automatically adds the custom activity for you in the toolbox.
Now question is how to pass parameters to the activity?
Once the activity is available in the toolbox, simply drag and drop to the workflow. Right click on activity and go to the properties window.
Here you will need to provide the input parameters and also if you are returning something from your custom activity then you will need to catch that output to some workflow variable.



I am passing some hardcoded values as parameters to the activity but this can be made dynamic by passing in workflow arguments.
Result is nothing but the output message which our activity is producing from execute method. I have simply assigned that result to the workflow variable called as varResult , so that I will be able to use it in workflow context.
That’s all guys, I hope now you know how to create custom activities in Windows Workflow Foundation and use them to make your life easier. Hope this helps someone.