Sunday, September 30, 2012

Windows Workflow Foundation

What is a workflow?

It is a framework that enables user to create system and process flow easily. Users can see controls that look like blocks and connectors in the UI design page, and you can simply drag and drop these blocks and connectors together to construct a flowchart, then a system will be created and functioning without the need to write lots of code. Finally, you can understand how the system work base on the flowchart.

Here is one sample that I had done while I was learning it.
I created a very simple workflow for leave application with the scenario of when I submit my leave application, it should automatically check for leave cannot be taken for more than 10 days, the application start date must be a future date, and the end date must be greater than start date.


Sample workflow


Things that we must know when we create workflow.

1. Variable - you can declare variables and use it in the workflow or inside a scope (block). It is useful for flagging purpose.

 
2. Arguments - you can determine the input or output parameters of a workflow


3. Imports - you can find the imported assembly namespaces here.



How to pass entity / object into workflow?

After you have created your own entity class, just simply add it as project reference to your workflow project. You actually pass and use your own object in workflow by setting the argument. But, there is another way to pass object into workflow, which is going through WCF via messaging way, but I have yet to discover how to do it. I will update and cover it in my next blog post.

So, go to the arguments of your workflow (as above screenshot), declare a name, set the direction, then set the argument type. While setting argument type, you are suppose to choose your entity object, but it will not be listed there. You just need to import it manually by selecting "Browse for Types...". Then select your entity project under <Referenced Assemblies>.



I have contructed my workflow, so how to test or debug?

Create a new unit test project. Then, add the workflow and entity project reference to your unit test project. Refer to following sample code to create an unit test.

        [TestMethod]
        public void ApplyLeave()
        {
            IDictionary input = new Dictionary();
            IDictionary output;

            Leave leave = new Leave();
            leave.Duration = 3;
            leave.StartDate = DateTime.Now.AddDays(1);
            leave.EndDate = DateTime.Now.AddDays(4);

            input.Add("LeaveApplication", leave);

            output = WorkflowInvoker.Invoke(new ApplyLeave(), input);

            Assert.AreEqual(((Leave)output["LeaveApplication"]).IsApproved, true);
        }

WorkflowInvoker is the class that you use to invoke your workflow. You can execute your workflow at any place such as ASP.net, WCF, windows form, console application, even unit test, and etc. The WorkflowInvoker accept and return Dictionary<string, object> type only. The dictionary key is the argument name, while the value is the argument value.

In my workflow design, I set my input argument type as my entity object type. Therefore, base on my above sample code, I actually construct my entity object, then keep it in my Dictionary<string, object> object instance, then pass it to the WorkflowInvoker. The passed in object will go through the workflow process and then return the final result back to WorkflowInvoker.

Summary

You should be able to notice that the idea of workflow actually is to make an object properties value change after one process end by another process. And, the value actually represent a status of a "thing".

By the way, you can create breakpoint in your workflow by right clicking at the block, then select Insert Breakpoint. So, you are able to identify the problem easily when you encounter any error or workflow does not work correctly while running the unit test.

You can find my sample code here: Download Here

 

Saturday, September 22, 2012

Layered Architecture Solution Guidance (LASG)

Ever think of how nice if there is a tool that able to generate code for you and shorten the application development time? Have you ever notice that when you create an application, there are a lot of code are repetitive in term of pattern (not design pattern) and the way it execute? For example pulling data and manipulating data from DB with ADO.net. Normally you would write the same style or pattern of code but what it actually does is getting the data from DB then store in different variables.

Here is the tool to generate the code for you: Layered Architecture Solution Guidance (LASG).
It is created by my mentor, Serena Yeoh (firedancer).
Download for Visual Studio 2010
Download for Visual Studio 2012

Note:
Some prerequisite components are needed to be installed first in order to install LASG.
1. Enterprise Library 5
2. Open GAX (for Visual Studio 2012)
3. GAX 2010 (for Visual Studio 2010)

Actually, the tool itself is not only meant for code automation, its main purpose is to guide developer to create application with proper and correct layering design. When you start using the tool and then create a new project with LASG template, you will see multiple projects will be created automatically and they are nicely structured into different folders which follow the layering design.
Logical Component Architecture
Physical Deployment Architecture


After installing the tool, how to use the tool?

Create a new project, then look for Guidance Packages installed template.

 

Then, enter your project namespace, then select the project type that you wish to create from the preset templates. Each template have different sets of projects to be created. The checkboxes indicate the projects that will be automatically created after you hit the OK button. Unfortunately, there has no icon or detail show in the UI saying what kind of project type is that. So, here are the details:
- When you see "Web" keyword mean ASP.net Web Forms
- "WinForm" of course is Windows Forms
- "Workflow" of course is Workflow
- "Database" of course is Database
- "Services" and "Contracts" mean WCF
- "Entities", "Process", "Data", "Framework" are Class Library
- "Test" is a Unit Test




After the projects are created, Follow the steps below:

I am not going to share the details on how to do it here. Instead, I will provide you the available link.

Step 1: Generate Business Entities
Step 2: Generate Data Access Components
Step 3: Generate Business Components
Step 4: Generate Services
Step 5: Generate Workflow Activities (optional if you do not have a workflow project)
Step 6: Generate UI Controllers

The steps without documentation require you to explore by yourself. It is not hard to use anyway.

The most interesting part to me is the auto generated code. You can do the code preview first before generate it into code file. And also, the tool automatically keep track which code had been generated before. If you go back to the tool and do some adding or removing, then regenerate the code, it actually give you an option to append or rewrite the code file.

There is one more new feature with this tool is if you happen to have your project namespace is similar to what LASG created, for example project name end with suffix "Data", "Business", "Entities", etc. You actually can enable the tool attach to your project without the need to recreate a new project with LASG template.

What you need to do is just go to the top menu, click at Tools then select Guidance Package Manager. Then, you will see the window as follow:



Then, click at the Enable / Disable Packages... button at the bottom left of the window.


Check the Layered Architecture Solution Guidance 2012 checkbox, then hit the OK button.

You will see the LASG tool menu appear after you right click at your project in the Solution Explorer.

For some reasons, you do not want LASG to attach to your project, you can do the same way, but uncheck the Layered Architecture Solution Guidance 2012 checkbox.


If you like this tool, feel free to like this facebook fan page, so if there is any new update about the tool, it will be shown in your facebook news feed.


Source and credits:
http://serena-yeoh.blogspot.com/
http://layersample.codeplex.com/
http://cloudsample.codeplex.com/
http://visualstudiogallery.msdn.microsoft.com/2dc87fb2-d6f2-4151-9dab-faad717eea41
http://visualstudiogallery.msdn.microsoft.com/c8c473b5-21a1-447a-8b24-33b43411ee7f
https://www.facebook.com/layersample#!/layersample

 

Saturday, September 15, 2012

Data Driven Unit Testing with XML

I had been stopped writing blog for the past 3 months, it is really tough for me to keep up the momentum in writing blog in a timely manner. Well, until recently I join a new company and I suppose I will encounter some unfamiliar issue and new experience to share here more oftenly.

Back to the topic, I would like to share how to write data driven unit test with XML.

Do you ever encounter a scenario that you wish to test one test case with multiple different set of test data?

I used to experience in writing data driven unit test with MbUnit. But, today I want to share about doing the same thing with Visual Studio unit test.
Here is one of the solution with XML.

        [DeploymentItem("\\TestData\\TimeOffTestData.xml"), TestMethod()]
        [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
            "|DataDirectory|\\TestData\\TimeOffTestData.xml", 
            "TimeOffTest_ApplyTimeOffTest", DataAccessMethod.Sequential)]
        public void ApplyTimeOffTest()
        {
            TimeOff timeOff = new TimeOff();
            timeOff.UserId = int.Parse(TestContext.DataRow["UserID"].ToString());
            timeOff.StartDate = DateTime.Parse(TestContext.DataRow["StartDate"].ToString());
            timeOff.EndDate = DateTime.Parse(TestContext.DataRow["EndDate"].ToString());

            TimeOffComponent component = new TimeOffComponent();

            try
            {
                component.Apply(timeOff);
            }
            catch (Exception ex)
            {
                if (!Convert.ToBoolean(TestContext.DataRow["ExpectException"]))
                {
                    throw ex;
                }
                else
                {
                    Assert.AreEqual(typeof(InvalidTimeOffException), ex.GetType(), 
                        "This exception type was unexpected.");
                }
            }
        }
Here is the content of my test data XML:
  
<?xml version="1.0" encoding="utf-8" ?>
<TestData>
  <TimeOffTest_ApplyTimeOffTest>
    <UserID>1</UserID>
    <StartDate>2012-09-10</StartDate>
    <EndDate>2012-09-13</EndDate>
    <ExpectException>true</ExpectException>
  </TimeOffTest_ApplyTimeOffTest>
  <TimeOffTest_ApplyTimeOffTest>
    <UserID>1</UserID>
    <StartDate>2012-11-13</StartDate>
    <EndDate>2012-11-10</EndDate>
    <ExpectException>true</ExpectException>
  </TimeOffTest_ApplyTimeOffTest>
  <TimeOffTest_ApplyTimeOffTest>
    <UserID>1</UserID>
    <StartDate>2012-11-12</StartDate>
    <EndDate>2012-11-13</EndDate>
    <ExpectException>true</ExpectException>
  </TimeOffTest_ApplyTimeOffTest>
  <TimeOffTest_ApplyTimeOffTest>
    <UserID>1</UserID>
    <StartDate>2012-11-15</StartDate>
    <EndDate>2012-11-20</EndDate>
    <ExpectException>true</ExpectException>
  </TimeOffTest_ApplyTimeOffTest>
</TestData>

What's does Microsoft.VisualStudio.TestTools.DataSource.XML do at the background is above XML will be parsed into a table, hence <TimeOffTest_ApplyTimeOffTest> is a table name then its child elements are columns name then the element content are the row data. Therefore above XML describe 4 set of test data and the differences of the test data.

When you perform test run, it will perform 4 runs with different set of test data accordingly to the defined XML above.

Here is how the test result look like:



Common Problem

After you have finished coding, and you could not get the same result like above screenshot. Following are the common issues that you may encounter and here is the solution:

Known Issue: The unit test adapter failed to connect to the data source or read the data.


Resolution:

Go to your Solution Explorer, add new item to your solution, then select "Test Settings" from the left menu, then add a new test setting.


In the "Test Settings" window, select "Deployment" from the left menu, then check the "Enable Deployment" checkbox.



If problem still persist, go to Solution Explorer, locate your test data XML file and then open the file properties. Make sure the "Copy to Output Directory" property is NOT set to "Do not copy", make it either "Copy always" or "Copy if newer".



If problem still persist and you are using Visual Studio 2012, move your XML file to your project root directory. The problem is the |Data Directory| is not returning correct path. I notice some odd behavior between Visual Studio 2010 and 2012.

I have a folder call "TestData" that keep all my XML files in my test project well organized.

With Visual Studio 2010, no issue in detecting my XML file in the folder.
With Visual Studio 2012, I will get the error. However, there is a workaround for it, which is not to use |Data Directory| when specifying your test data file location. Instead, use real physical path. For example:

        [DeploymentItem("\\TestData\\TimeOffTestData.xml"), TestMethod()]
        [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
            "D:\\Projects\\DataDrivenUnitTest\\DataDrivenUnitTest.Test\\TestData\\TimeOffTestData.xml", 
            "TimeOffTest_ApplyTimeOffTest", DataAccessMethod.Sequential)]
        public void ApplyTimeOffTest()


There is one more workaround for solving the problem with |DataDirectory| in Visual Studio 2012. You can set Copy to Output Directory value to "Do not copy" for the XML file. Then, open the unit test project properties, then set the post-build event command line: copy "$(ProjectDir)TestData" "$(ProjectDir)$(OutDir)"



So that, every time you build your unit test project, the command line above copy all the files in the TestData folder to your output directory without the TestData folder automatically.



You may download my unit test project to play around: Download Here


Tuesday, June 26, 2012

SqlCeException: The specified table does not exist [xxxxx]

Today I spent almost 2 hours just to find out what is the cause of the issue about keep getting SqlCeException: The specified table does not exist [xxxxx]
Here is story.

I intended to create a local database for my phone application, hence I am following the MSDN guide. http://msdn.microsoft.com/en-us/library/hh202876(v=vs.92).aspx#BKMK_CreatingtheDatabase

I was reading the guide while writing my own application with some modification until everything are ready for testing.

Then, when the code run until:
var watchListInDB = WatchDB.WatchTable.Select(x => x);
Watches = new ObservableCollection<Watch>(watchListInDB);

Note: WatchDB is my Database Context.

The error hit at the LINQ Select extension method. I re-read the whole guide again and again just to make sure nothing is missed out. So, here are the things you need to take care of if you are running into the same problem too.

1. Database context had been created in App.xaml.
using (WatchListDataContext db = new WatchListDataContext(WatchListDataContext.DBConnectionString))
{
  
if (db.DatabaseExists() == false)
   {
     db.CreateDatabase();
   }
}
2.  In your database  context, you have your table property declared.
public class WatchListDataContext : DataContext
{

   public static string DBConnectionString = "Data Source=isostore:/Database.sdf";

   public WatchListDataContext(string connectionString) : base(connectionString)
   { }

   public Table<Watch> WatchTable;

}
3.  In your entity object, do not use unsupported data type in the class property as table column. This is my actual root cause of problem. My WatchList property/table column is a List<int> type which is not a valid data type. The SqlCeException message saying the specified table does not exist is not related to incorrect declared data type for my table column here!!! For the list of supported data type, refer to this: More Detail

Wrong example. generic list is not supported data type:
[Table]
public class Watch : INotifyPropertyChanged, INotifyPropertyChanging
{
  private List<int> _watchList;
  [Column]
  public List<int> WatchList
  {
    get
    {
      return _watchList;
    }
    set
    {
      if (_watchList != value)
      {
        NotifyPropertyChanging(
"WatchList");
        _watchList = value;
        NotifyPropertyChanged("WatchList");
      }

    }
  }
}

4.  Final thing, clean your project and then rebuild! It makes a difference!!!

Monday, June 18, 2012

Windows Phone with Windows Azure - Part 1



Normally, when we are creating a sophisticated phone app, we need to have our phone app communicate with some servers to perform some logic and data keeping. Hence, we need to host the services somewhere that allow the phone app to be able to communicate with. So, the main challenge is the service must be running and available in 24/7 and accessible from anywhere.


Therefore, what I need are:
1. WCF to provide web services for my phone app
2. Windows Azure to host my WCF service for 24/7 availability and accessible at anywhere.
3. SQL Azure to keep my data.

Windows Azure
It is a cloud computing service which is provided by Microsoft. Currently, Microsoft provides 3 months free trial for Windows Azure. We can take the advantage now to learn how to host a WCF service in Windows Azure which let your phone app to consume. More Detail

SQL Azure
It is a SQL server database service that host in cloud. SQL Azure come with the 3 months free trial Windows Azure, therefore, we can create our database there. But, mind you, there are some differences in  SQL Azure and MSSQL, especially some data types and features are not available in SQL Azure but MSSQL.

Warning: The service pricing is base on the number of hosted instances, instance size, database size, bandwidth, etc. Something like these need to be taken care of when the free trial period has ended, just to ensure your money is not burning a hole in your pocket. More Detail

Next, how to host WCF in Windows Azure? Will post it up in Part 2.

Windows Phone Development

Recently, I have been very interested in Windows Phone application development and keep doing research about it everyday after my daily job.We all know that in the current mobile industry, the phone operating systems available in the market now have iOS, Android, etc but why pick Windows Phone?

Reasons:
1. I am C# literate and I love C#.
I have been using C# since the beginning of my career. I would want to focus mastering it instead of learning all the other programming languages but not able to master all of them. In the end, I am expert in one thing instead of beginner of everything.

2. Windows Phone SDK provides all the libraries we need to develop an apps very quickly.
For those who experience in Microsoft .net framework knows that we can write code or develop application very quickly because one simple line of code can produce multiple results. The only drawback is we do not know what's happening behind the framework. :) Well, if you are a result oriented person, you would not care about it unless it hits some performance issue, then you will rage and curse Microsoft.

The advantage of speedy development in Windows Phone actually helps to tell the idea of your application can be success or fail. When the required development time is low, it means cost is low and risk is low too. Imagine you can create multiple applications with different business idea quickly to give it a trial and error way to test the market response at lower cost.

Get Started
Alright, let's get back to code. What do we need to get started?
1. Of course, Visual Studio.
2. Download and install the Windows Phone SDK 7.1. (Some may confuse with the SDK version. if you plan to create an app for Windows Phone 7.5, and this is the correct and latest SDK unless Windows Phone 8 SDK has released)
3. Download and install the Windows Phone SDK 7.1.1 Update.


Let's start having fun and play around with Hello World!


Send Transactional SMS with API

This post cover how to send transactional SMS using the Alibaba Cloud Short Message Service API. Transactional SMS usually come with One Tim...