Archive for the ‘Development’ Category.

Sorting by Reversals in C#

I am getting a masters and I was studying this and wanted to implement it to understand it fully. Efficiency could be improved for sure but the goal of this is not efficiency, just to implement the algorithm so when I question comes up on the final, I can answer it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reversals
{
    class Program
    {
        static void Main(string[] args)
        {
            // SolveByReversals1
            int[] array1 = new int[] { 0, 1, 2, 3, 7, 6, 5, 4, 9, 8, 10 };
            Console.WriteLine("Before: " + string.Join(", ", array1));
            SolveByReversals1(array1);
            Console.WriteLine(" After: " + string.Join(", ", array1));

            Console.WriteLine();

            // SolveByReversals2
            int[] array2 = new int[] { 0, 1, 2, 3, 7, 6, 5, 4, 9, 8, 10 };
            Console.WriteLine("Before: " + string.Join(", ", array2));
            SolveByReversals1(array2);
            Console.WriteLine(" After: " + string.Join(", ", array2));

            int[] array3 = new int[] { 0, 10, 20, 30, 70, 60, 50, 40, 90, 80, 100 };
            Console.WriteLine("Before: " + string.Join(", ", array3));
            SolveByReversals2(array3);
            Console.WriteLine(" After: " + string.Join(", ", array3));

            Console.WriteLine();

            // SolveByReversals3
            int[] array4 = new int[] { 0, 1, 2, 3, 7, 6, 5, 4, 9, 8, 10 };
            Console.WriteLine("Before: " + string.Join(", ", array4));
            SolveByReversals3(array4);
            Console.WriteLine(" After: " + string.Join(", ", array4));

            int[] array5 = new int[] { 0, 10, 20, 30, 70, 60, 50, 40, 90, 80, 100 };
            Console.WriteLine("Before: " + string.Join(", ", array5));
            SolveByReversals3(array5);
            Console.WriteLine(" After: " + string.Join(", ", array5));

            int[] array6 = new int[] { 0, 0, 1, 4, 3, 3, 1, 2, 2, 4 };
            Console.WriteLine("Before: " + string.Join(", ", array6));
            SolveByReversals3(array6);
            Console.WriteLine(" After: " + string.Join(", ", array6));
        }

        /// <summary>
        /// Works only for perfect sequences starting at zero 
        /// and incrementing by one {0,1,2,3,...,10,...}
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static int[] SolveByReversals1(int[] array)
        {
            for (int i = 0; i < array.Length; i++)
            {
                int j = Array.IndexOf<int>(array, i);
                Array.Reverse(array, i, j - i + 1);
            }
            return null;
        }

        /// <summary>
        /// Works with sequences of unique integers.
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static int[] SolveByReversals2(int[] array)
        {
            int pos = 0;
            for (int i = 0; i < array.Max() - 1; i++)
            {
                int j = Array.IndexOf<int>(array, i, pos);
                if (j == -1)
                    continue;
                Array.Reverse(array, pos, j - pos + 1);
                pos++;
            }
            return null;
        }

        /// <summary>
        /// Works for numbers of any sequence.
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static int[] SolveByReversals3(int[] array)
        {
            int pos = 0;
            int highLoop = array.Max();
            if (array.Length > highLoop)
                highLoop = array.Length;
            for (int i = 0; i < array.Max() - 1; i++)
            {
                int j = 0;
                while ((j = Array.IndexOf<int>(array, i, pos)) != -1)
                {
                    Array.Reverse(array, pos, j - pos + 1);
                    pos++;
                }
            }
            return null;
        }
    }
}

So it was nice to implement this to understand some of the difficulties and solve this issue. I may never have arrived at the third method just from class discussion.

C# – Creating a Service to Monitor a Directory

Let’s say you wanted to watch a directory and perform an action each time a file is added, deleted, changed, or renamed.

  • Microsoft has a Visual C# Windows Service project template in Visual Studio.
  • Microsoft also has a nice class already created to help with this: FileSystemWatcher

Example Project

Here is an example project you can download: DirectoryMonitoring.zip

Step 1 – Create a Visual C# Windows Service project in Visual Studio

  1. Select File | New Project.
  2. Select Templates | VIsual C# | Windows | Windows Service.
  3. Provide a name: DirectoryMonitoring
  4. Click OK.

Step 2 – Create an object that inherits from FileSystemWatcher

  1. Right-click on Project and choose Add | Class.
  2. Name it MyFileSystemWatcher.cs.
using System;
using System.IO;

namespace DirectoryMonitoring
{
    public class MyFileSystemWatcher : FileSystemWatcher
    {
        public MyFileSystemWatcher()
        {
            Init();
        }

        public MyFileSystemWatcher(String inDirectoryPath)
            : base(inDirectoryPath)
        {
            Init();
        }

        public MyFileSystemWatcher(String inDirectoryPath, string inFilter)
            : base(inDirectoryPath, inFilter)
        {
            Init();
        }

        private void Init()
        {
            IncludeSubdirectories = true;
            // Eliminate duplicates when timestamp doesn't change
            NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size; // The default also has NotifyFilters.LastWrite
            EnableRaisingEvents = true;
            Created += Watcher_Created;
            Changed += Watcher_Changed;
            Deleted += Watcher_Deleted;
            Renamed += Watcher_Renamed;
        }

        public void Watcher_Created(object source, FileSystemEventArgs inArgs)
        {
            Log.WriteLine(&quot;File created or added: &quot; + inArgs.FullPath);
        }

        public void Watcher_Changed(object sender, FileSystemEventArgs inArgs)
        {
            Log.WriteLine(&quot;File changed: &quot; + inArgs.FullPath);
        }

        public void Watcher_Deleted(object sender, FileSystemEventArgs inArgs)
        {
            Log.WriteLine(&quot;File deleted: &quot; + inArgs.FullPath);
        }

        public void Watcher_Renamed(object sender, RenamedEventArgs inArgs)
        {
            Log.WriteLine(&quot;File renamed: &quot; + inArgs.OldFullPath + &quot;, New name: &quot; + inArgs.FullPath);
        }
    }
}

Notice that each method is logging. We will implement this log next.

Step 3 – Add logging

  1. Add the class from a previous post: A simple Log singleton in C#
  2. Make sure to change the namespace to match.

Step 4 – Implement the Service

  1. Right-click on the Service1.cs file and choose View Code.
  2. Change both the Name and the ServiceName to DirectoryMonitoringService. You can right-click on the file to rename. If that doesn’t rename the class, you can open the file, right-click on the class name and choose Refactor | Rename.
  3. Go to the code of the DirectoryMonitoringService.cs file (which was Service1.cs just a couple steps ago) in Visual Studio.
  4. Implement the constructor as follows:
using System.IO;
using System.ServiceProcess;

namespace DirectoryMonitoring
{
    public partial class DirectoryMonitoringService: ServiceBase
    {
        protected FileSystemWatcher Watcher;

        // Directory must already exist unless you want to add your own code to create it.
        string PathToFolder = @&quot;C:\Directoy\To\Monitor&quot;;

        public DirectoryMonitoringService()
        {
            Log.Instance.LogPath = @&quot;C:\ProgramData\DirectoryMonitoring&quot;;
            Log.Instance.LogFileName = &quot;DirectoryMonitoring&quot;;
            Watcher = new MyFileSystemWatcher(PathToFolder);
        }

        protected override void OnStart(string[] args)
        {
        }

        protected override void OnStop()
        {
        }
    }
}

Step 5 – Create a Service Installer

  1. Right-click on DirectoryMonitoringService.cs and choose View Designer.
  2. Right-click anywhere in the designer window and choose Add Installer. This adds a ProjectInstaller.cs file.
  3. Right-click on ProjectInstaller.cs and choose View Designer.
  4. In the designer, right-click on serviceProcessInstaller1 and choose Properties.
  5. In the properties, set Account to LocalSystem.
  6. Back in the designer, right-click on serviceInstaller1 and choose Properties.
  7. Set StartType to Automatic.
  8. Add a descriptions if you want.

Step 6 – Install the Service

  1. Open the Developer Command Prompt by right-clicking and choosing Run as Administrator.
    Note: If you don’t have the Developer Command Prompt, you can open a normal command prompt as administration and get installUtil.exe from this path:

    c:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe
  2. In the command prompt, change to the bin\debug folder in your project directory.
  3. Run this command to install the service:

    installutil.exe DirectoryMonitoring.exe

  4. Start the service with this command.

    net start DirectoryMonitoringService

Step 7 – Debug the Service

  1. Make sure the service is started and running.
  2. In Visual Studio with the DirectoryMonitoring project open, click Debug | Attach to Process.
  3. Select the DirectoryMonitoring.exe file.
  4. Put a break point at each event in the MyFileSystemWatcher object.
  5. Test all four events:
    1. Add a file.
    2. Rename a file.
    3. Open and save a file.
    4. Delete a file.

You have now created a service to monitor a directory and you have seen how to debug it.

Why your story estimation was off!

Estimations are often very far off because those doing the estimations forget what is involved in completing a story. Often the estimation is done based on how long it takes to code it up. As you can see below, coding it up is just one of the tasks per story.

Even just doubling the code time is inaccurate. Why does a team that doubles the code time estimates still fall behind?

  • Because they didn’t understand what is involved in the story.
  • Because they don’t understand coding time versus work time

Reason #1 – You didn’t consider all the development tasks

There are many more tasks than just development. You need to know what these tasks are and understand them. You need to understand the risks each brings to meeting your goals.

Tasks to consider when estimating story time

Applicable
(yes/no)
Tasks/Sub-Stories Hours
Research
Code Design and Architecture
User Experience
– Mock up
– Present to customer
Write Code
– Code
– Unit Tests
– Code Review (by Peer)
Writing Automated Tests
– Acceptance Tests
– Performance Tests
Build and compile
Install / Publish
– Add to installer/publisher
– Use separate installer
Localization
– Make code Localizable
– Localize (per language)
Documentation
Security

First determine which tasks apply to a story. Then estimate each task individually. Then simply add up the hours. Your estimations will probably be more accurate and upper management will become aware of what tasks are slowing a story up.

Using this list can also help with getting tasks done at the same time as opposed to using the waterfall method. For example, if you are creating a new file, you can create an empty project, check it in and build and install can get working on their tasks while developer is still coding.

Let’s give an example:

Applicable
(yes/no)
Tasks/Sub-Stories Hours
 yes Research  6 hours
 no Code Design and Architecture
 no User Experience
 no – Mock up
 no – Present to customer
 yes Write Code
 yes – Code  8 hours
 yes – Unit Tests  8 hours
 yes Writing Automated Tests
 yes – Acceptance Tests  4 hours
 no – Performance Tests
 no Build and compile
 no Install / Publish
 no – Add to installer/publisher
 no – Use separate installer
 yes Localization
 yes – Make code Localizable  2 hours
 no – Localize (per language)  story
 yes Documentation  8 hours
 no Security
Total  36 hours

So if you estimate based on coding, which is just 8 hours, you can see you aren’t even close. It will take four and a half times as long as you thought. If you estimate based on code and unit tests, 16 hours, you are still more than twice as long as you thought.

Note: I am not saying that these all have to be tasks on one story. You could break them up into separate stories. However, you will find that if Unit Tests and Automated Tests and these other tasks are separate stories, then the person in charge of prioritization of stories is now able to drop them in favor of other work and then your code will blow up one day and the developers will take some of the blame even if they shouldn’t. It is best if a story and all its tasks are 100% complete so you don’t ship half finished or a half tested product.

Reason #2 – You think developers code eight hours a day

Ok, so let’s talk about an eight hour day.

Most states have laws about two fifteen minute breaks (one ever four hours) so really, any employee is only going to work 7:30 hours a day. Ok, now add in the fact that it  usually takes five to fifteen minutes to focus back on work once back from a break. With lunch and two breaks that is 15-45 minutes. So now we are down to 6:45 minutes to 7:15 minutes. Ok, how long will be spent on email? 30 minutes to an hour. So now you are down to 5:35 to 6:45 hours of coding a day. Now factor in Stand up. 5-15 minutes, plus 5 to 15 minutes to get focus back and we are down to 5:05 to 6:35 minutes.

So on the best days a developer will likely code between five hours and 6 hours and 35 minutes.

Add a meeting or two in a day plus the refocus time after the meeting and development time is decreased further to 3 hours to 4 hours on meeting days.

So if you are assuming that your developers are going to coding 8 hours a day, you are in for a shock.

  • Best Day: 5 hours to 6-1/2 hours
  • Meeting Days: 3 hours to 4 hours

So add in scrum and sprint planning, story costing, and sprint retrospective, in which some meetings are longer than two hours and you lose a full day of development every sprint. So with a two week sprint, plan on 9 days of development at an average of 5 hours a day and you get 45 hours of development time.

  • Average development time per sprint per developer: 45 hours

Now if you have a team of three developers. An inexperienced team might estimate with 45 * 3, or 135 hours. Unfortunately that probably won’t be accurate. Estimators will find that inevitably one of the team members has time off during a sprint. Remove 5 hours per day off (not eight). There also might be a holiday during the sprint. Well, a holiday means that 5 development hours per developer are not available, so that 135 hours becomes 120.

So lets put this into perspective. If you think that you have 8 hours a day for 10 days in a two week sprint for 3 employees and so you plan 8 * 10 * 3 and get 240 hours, and then you plan 240 hours of stories, you are only going to get half way done. This calculation is almost twice what in reality your team can do. If you plan this way, you will always be behind, and fail to meet goals and deadlines while working your developers to death.

Can you make up the hours by working the developers longer? Not really. The developers may end up putting an extra two hours a day in for 9 of the 10 days, but they will probably take one more 15 minute break on those days. Which only gets you about 1 hour and 30 minutes more per day times 3 developers times 9 days. This is 45 hours. 120 hours plus 45 hours only gets you to 165 hours. You are still 75 hours short of 240 hours.

So estimate accurately by starting with 50 developer hours per two week sprint (10 * 5 = 50) for each developer and subtract days off. Then estimate the work that can be done.

Developer Days Hours
Mike Sourcington 8 days 40 hours
Krista Coderson 10 days 50 hours
Devon Li 9 days 45 hours
Total 130 hours

To make this easier for you, I have created A Spreadsheet for Sprint Planning that you can use.

Conclusion

If you fail to understand the number of development hours and fail to understand all the work for each development story, you will never be accurate, and you will always be behind and always be asking your developers to work longer hours, which will create a horrible work environment.

Understanding both of the above reasons above and estimating accordingly will provide accurate estimates. This will benefit the whole company. Upper management will see the true velocity. The quality of the code will be higher because the developers won’t be overwhelmed and stressed, which will result in lower bugs, maintenance, and support costs. Marketing will have realistic ideas of what is coming and what isn’t and won’t waste money getting ready for features that drop off a month before ship.

WPFSharp: A WPF Searchable TextBlock Control with Highlighting

So I needed a TextBlock that was searchable and from searching online, it seems a lot of people need one too. So I decided to inherit TextBlock and write a SearchableTextBox. It is really easy to use. I wrote the blog post over on my other site:

A WPF Searchable TextBlock Control with Highlighting

3 Column Table Layout verses 3 Column HTML5 Layout

Has HTML5 and CSS3 solved the layout problem? Or are tables layouts with CSS still a better solution.

You decide. Please post comments about other pros and cons you find. We all become experts when we all contribute.

Note: With both a table layout and an HTML5 layout, CSS is used, so this is not a CSS versus anything article. No matter which you use, lets agree that CSS should be used for style. However, CSS3 does add to the layout with the HTML5 solution.

3 Column HTML Table Layout with CSS Style

Click this link to see this layout: 3 Column HTML Table Layout with CSS Style

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML Table Layout with CSS Style - 3 Column</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
 
html, body 
{
  height: 100%;
}
 
body 
{
    margin:0
}
 
table.layout 
{
  height:100%;
  width: 100%;
  border-collapse:collapse;
}
 
td.header 
{
  padding: 15px;
  height: 120px;
  color: white;
  background: black
}
 
td.nav-bar 
{
  padding: 15px;
  height:20px;
  background:DarkGrey;
}
 
td.leftcol 
{
  padding: 15px;
  width: 170px;
  min-width: 170px;
  background-color:Navy;
  color: white;
}

td.midcol 
{
  padding: 15px;
  min-width: 625px; /* Make 425px for min res of 800x600 */
}
 
td.rightcol 
{
  padding: 15px;
  width: 205px;
  min-width: 205px;
  background-color:Navy;
  color: white;
}
 
td.footer 
{
  height: 120px;
  background: DarkGrey;
  text-align: center;
}

</style>
</head>
<body>
<table class="layout">
	<tr>
		<td class="header" colspan="3">Header</td>
	</tr>
	<tr>
		<td class="nav-bar" colspan="3">Nav bar</td>
	</tr>
	<tr>
		<td class="leftcol">Aside left</td>
		<td class="midcol">Article</td>
		<td class="rightcol">Aside right</td>
	</tr>
	<tr>
		<td class="footer" colspan="3">
			<a href="http://validator.w3.org/check?uri=referer">
				<img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" height="31" width="88" />
			</a>
		</td>
	</tr>
</table>
</body>
</html>

HTML Table Layout Pros

  • Validated with W3C
  • Only 95 lines of code with everything on its own line
  • Works with every browser according to BrowserShots.org
  • Very easy to use.
  • Making the table be 100% height is easy
  • Changing the width or height of any part of the page is easy

HTML Table Layout Cons

  • Layout is coupled to the HTML, layout would be best decoupled – Solved by using scripting languages like PHP and ASP.NET
  • Left column is found in HTML before the article body – No current solution

3 Column Layout HTML5 with CSS Layout/Style

Click this link to see this layout: 3 Column Layout HTML5 with CSS Layout/Style

<!DOCTYPE html>
<head>
<title>Layout HTML5 with CSS Layout/Style - 3 Column</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
 
html, body 
{
  height: 100%;
}

body 
{
    margin:0
}

header 
{
  padding: 15px;
  min-height: 150px;
  color: white;
  background: black
}
 
nav
{
  padding: 15px;
  min-height:20px;
  background:DarkGrey;
}

#main 
{ 
  /* height:100%; */ /* Broken with it, broken without it */               
  display: -moz-box;				/* Firefox */
  display: -webkit-box;				/* Safari and Chrome */	
  display: box; 					/* Future standard */
}

#main-aside-left
{
  padding: 15px;
  width: 170px;
  min-width: 170px;
  -moz-box-ordinal-group: 3; 		/* Firefox */
  -webkit-box-ordinal-group: 3; 	/* Safari and Chrome */
  box-ordinal-group: 3; 			/* Future standard */
  background-color:Navy;
  color: white;
}

article 
{ 
  padding: 15px;
  min-width: 625px;					/* Make 425px for min res of 800x600 */
  -moz-box-flex: 2; 				/* Firefox */
  -webkit-box-flex: 2; 				/* Safari and Chrome */
  box-flex: 2; 						/* Future standard */
  -moz-box-ordinal-group: 2; 		/* Firefox */
  -webkit-box-ordinal-group: 2; 	/* Safari and Chrome */
  box-ordinal-group: 2; 			/* Future standard */
}

#main-aside-right
{
  padding: 15px;
  width: 205px;
  min-width: 205px;
  -moz-box-ordinal-group: 1; 		/* Firefox */
  -webkit-box-ordinal-group: 1; 	/* Safari and Chrome */
  box-ordinal-group: 1; 			/* Future standard */
  background-color:Navy;
  color: white;
}

footer 
{
  height: 120px;
  height: 120px;
  background: DarkGrey;
  text-align: center;
}

</style>
</head>
<header>Header</header>
<nav>Nav bar</nav>
<div id="main">
   <article>Article</article>
   <aside id="main-aside-left">Aside left</aside>
   <aside id="main-aside-right">Aside right</aside>
</div>
<footer>
  <a href="http://validator.w3.org/check?uri=referer">
    <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" height="31" width="88" />
  </a>
</footer>

HTML5 Layout Pros

  • W3C validated (experimental)
  • Article data comes before the data in the asides – This is a huge SEO bonus
  • Only 97 lines of code both CSS and HTML code, with everything on its own line
  • Very easy to use.
  • Making the table be 100% height is easy
  • Changing the width or height of any part of the page is easy

HTML5 Layout Cons

  • It doesn’t work on IE 9 or below and fails in many other browsers according to Browsershots.org. – No current solution.
  • Much of the CSS has to be duplicated – No current solution but when it is fixed, the code will be another 10 lines smaller
  • If the content does not fill the screen, there is no way to make the screen exactly 100% – No current solution but as long as the content is larger than the screen this doesn’t matter
  • Layout is coupled to CSS,  a styling tool, layout should be decoupled – Solved by having a separate CSS file just for layout

Conclusion

Use Table layouts for now if your browser support is high priority.

Use HTML5 layouts if you can enforce uses to use HTML5 capable browsers.

Reasons to use MonoTouch and MonoDroid

MonoTouch and MonoDroid allow us to write our apps in C# and this is the right solution for our mobile apps and here are the reasons why.

Note: These reasons were ones I provided to a C# shop so some may not be valid for places where the majority of developers are not C# developers.

  1. MonoTouch is native. See monotouch is both a wrapper for the native code and the ability to access C# libraries. It is not like flash or html 5, where it is completely different technology. It is just the ability to use native code from C# with an added C# framework.
  2. MonoTouch uses the native UI (and MonoDroid does too). So UX’s desire to have a native UI is met by MonoTouch.
  3. Many companies already use MonoTouch and MonoDroid: Microsoft, 3M, VMWare, Novartis, Target, Acenture, Cisco, AT&T, AOL, Monster, Cornell University, Raytheon, Intuit, HP, and many more companies.
  4. The number of C# language experts we have: All of us
    The number of Objective-C language experts we have: Zero
    With C# everybody can work on the code, not just one or two Objective C engineers.
  5. If we use Objective C, we will have a huge ramp up expense and this expense will occur over and over, because every time someone quits, it is more likely that we will have to incur the cost of training a C# developer to become an Objective C developer than it is likely we will hire. As you know, hiring a replacement may or may not happen.
  6. Shared C# code. A large portion of our code the code write for SharePoint, iOS, Windows, and Android can be used and unit tested in one place. I have personally experienced this re-use of code at my previous company. We starting an Android app and our project was finished more than three weeks early by using MonoDroid, because we were able to use all the C# code we had already written.
  7. C# is a more developed language and is far easer to write code in. For example, to connect to a web service using windows integrated security is just a few lines of code in C# but requires extra libraries and a massive amount of effort in Java or Objective C.
  8. Shared Unit Test libraries. Since much of the code is shared, separate unit tests are not needed. Also, the C# unit testing frameworks we are already familiar with can be used and there is no need to ramp up on and implement a new unit testing technology. This is just another cost saving.

I recommended MonoDroid and MonoTouch at LANDesk and I will do the same here. The cost of using Ojbective C is far greater and the time to market is far longer. The SDLC of Objective C will have a greater cost. Choosing it will be a costly.

Since this isn’t my team and since it isn’t my decision, this is the last I am going to say about it.

Creating a drill down chart with ASP.NET and MSChart

In my first post, A basic reporting chart in ASP.NET, I went over the basics of creating a report using MSChart and ASP.NET and this was quit easy. However, in today’s world where the importance of business intelligence is ever increasing, the ability to drill down on a report has become the de facto standard. MSChart, ASP.NET, and HTML make it easy to create a drill-down report.

Note: Microsoft has a drill-down report in their ChartSamples example, but it was bundled as part of the same project with two-hundred other reports and was not a minimal example. It requires the use of an Access database (and I had nothing to read Access with), it has a bunch of javascript code that is for a tooltip preview of the drill down report, and the charts are in two objects. All of this made it more difficult for me to break this down.  In this example, the report will be its own ASP.NET project and will be a minimal example, however the use case and the sample data is taken directly from Microsoft’s example.

Report Example Use Case

Imagine you have a list of sales reps, their regions, and their sales results. You want a report to look at total sales per region. Then you want to click on a region to the see the sales by sales rep.

Download the project here: SampleChart.zip

Step 1 – Create the Visual Studio project

  1. In Visual Studio, click on File | New | Project.
  2. Select Visual C# | Web from the Installed Templates.
  3. Locate and select ASP.NET Empty Web Application.
    Note: I like to demonstrate using an Empty project you nothing is done for you, and you have to learn everything you actually need to do.
  4. Give the project a name.
    I named mine DrillDownChart because that is my example’s purpose.
  5. Click OK.
  6. Right-click on the newly created project and click Add | Reference.
  7. Select the .NET tab.
  8. Locate System.Web.DataVisualization and highlight it.
  9. Click OK.

Step 2 – Add a web form for your chart

  1. Right-click on the Project and choose Add |  New Item.
  2. Select Web Form.
  3. Give the file a name.
    I named my file  Report.aspx.
  4. Click OK.

Step 3 – Create a data object for the report

Because data is often coming from a database, this example is going to use a DataSet. I am not going to connect to a database, but just use a statically build DataSet.

  1. Right-click on the Project and choose Add |  Class.
  2. Give the file a name.
    I named my file  SalesDataSet.cs.
  3. Make the class inherit from DataSet.
  4. Click OK.

Step 4 – Add example data to the data object for the report

While in a real world scenario, you would get the data from a database or somewhere, lets first just create some sample data. We are going to create two simple tables. One is a Region table, that has the region name and ID. One is a RepSales table that has sales per rep and the rep’s region id.

  1. Create a property with only a getter that creates a region DataTable called RegionTable.
  2. Add the columns needed: RegionID and RegionName.
  3. Add the appropriate rows.
  4. Create a property with only a getter that creates a reps sales DataTable called RepsSalesTable.
  5. Add the columns needed: ID, Name, RegionID, and Sales.
  6. Add the appropriate rows.
  7. Now in your constructor, add those to the list of Tables in your object.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data;
    
    namespace DrillDownChart
    {
        public class SalesDataSet : DataSet
        {
            public SalesDataSet()
            {
                Tables.Add(RegionTable);
                Tables.Add(RepsSalesTable);
    
            }
    
            public DataTable RegionTable
            {
                get
                {
                    if (_RegionTable == null)
                    {
                        List<String> Regions = new List<string>() { "East", "West", "Central", "International", "South" };
    
                        _RegionTable = new DataTable("Region");
                        _RegionTable.Columns.Add("RegionID", typeof(int));
                        _RegionTable.Columns.Add("RegionName", typeof(string));
    
                        int i = 0;
                        foreach (var region in Regions)
                        {
                            DataRow row = _RegionTable.NewRow();
                            row["RegionID"] = ++i;
                            row["RegionName"] = region;
                            _RegionTable.Rows.Add(row);
                        }
    
                    }
                    return _RegionTable;
                }
            } private DataTable _RegionTable;
    
            public DataTable RepsSalesTable
            {
                get
                {
                    if (_RepsSalesTable == null)
                    {
                        List<String> reps = new List<string>() {
                            "Aaron", "Larry", "Andrew", "Mary", "Sally", "Nguyen", "Francis",
                            "Jerry", "Danny", "Jim", "Sarah", "Hannah", "Kim", "Gerry", "Bob" };
                        int[] regions = { 1, 2, 3, 1, 4, 2, 4, 3, 1, 2, 2, 3, 5, 5, 5 };
                        int[] sales = { 10440, 17772, 23880, 7663, 21773, 32294, 11983, 14991,
                                        17946, 8551, 19443, 27887, 30332, 16668, 21225 };
    
                        _RepsSalesTable = new DataTable("RepsSales");
                        _RepsSalesTable.Columns.Add("ID", typeof(int));
                        _RepsSalesTable.Columns.Add("Name", typeof(string));
                        _RepsSalesTable.Columns.Add("RegionID", typeof(int));
                        _RepsSalesTable.Columns.Add("Sales", typeof(int));
    
                        for (int i = 0; i < reps.Count; i++)
                        {
                            DataRow row = _RepsSalesTable.NewRow();
                            row["ID"] = i + 1;
                            row["Name"] = reps[i];
                            row["RegionID"] = regions[i];
                            row["Sales"] = sales[i];
    
                            _RepsSalesTable.Rows.Add(row);
                        }
    
                    }
                    return _RepsSalesTable;
                }
            } private DataTable _RepsSalesTable;
        }
    }
    

That is it, your fake example data is prepared.

Step 5 – Add a Chart to the Report.aspx file

  1. Open the Report.aspx file.
  2. Add a Register to the System.Web.DataVisualization assembly.
  3. Locate the div inside the body.
  4. Inside the div, add a Chart that includes a ChartArea.
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Report.aspx.cs" Inherits="CompareYearsByQuarter.Report" %>
    
    <%@ Register Assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Chart ID="SalesReport" runat="server">
                <chartareas>
                    <asp:ChartArea Name="ChartArea1">
                    </asp:ChartArea>
                </chartareas>
            </asp:Chart>
        </div>
        </form>
    </body>
    </html>
    

Step 6 – Add code the Report.aspx.cs file

We are going to use the same object for both the original report and the drill down report. We will just a little code that switches which data the chart is populated with.

  1. Open the Report.aspx.cs file.
  2. Create an instance of the SalesDataSet object that has our sample data.
  3. Add code in the Page_Load method to configure the Chart.
    Note 1: The steps for this code is in the code and comments itself. I created a method for each step and then populated the methods as  needed.
    Note 2: Notice that the AddDataToSeries() method uses and if statement to determine whether to add the original data or the drill down data.
    Note 3: Because we used a DataTable we query the example data using LINQ. It is likely that in your production reports you are using a real database and you will probably use queries directly to your database.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Data;
    using System.Web.UI.DataVisualization.Charting;
    
    namespace DrillDownChart
    {
        public partial class RegionReport : System.Web.UI.Page
        {
            // Step 1 - Create Example Data
            SalesDataSet ExampleData = new SalesDataSet();
    
            protected void Page_Load(object sender, EventArgs e)
            {
                // Step 2 - Populate chart drop down
                PopulateChartTypeDropDown();
    
                // Step 3 - Create Series
                Series series = CreateSeries();
    
                // Step 4 - Set the chart type
                SetChartType(series);
    
                // Step 5 - Add data (and if needed drilldown links to series)
                AddDataToSeries(series);
    
                // Step 6 - Add series into the chart's series collection
                SalesReport.Series.Add(series);
            }
    
            private void PopulateChartTypeDropDown()
            {
                List<String> chartTypes = new List<String>(Enum.GetNames(typeof(SeriesChartType)));
                chartTypes.Insert(0, "");
    
                foreach (var item in chartTypes)
                {
                    DropDownListChartType.Items.Add(item);
                }
            }
    
            private Series CreateSeries()
            {
                Series series = new Series("Sales");
                series.BorderWidth = 3;
                series.ShadowOffset = 2;
                return series;
            }
    
            private void SetChartType(Series inSeries)
            {
                if (Page.Request["ChartType"] != null)
                    DropDownListChartType.SelectedValue = Page.Request["ChartType"];
    
                if (DropDownListChartType.SelectedValue.ToString() == "")
                    DropDownListChartType.SelectedValue = SeriesChartType.Column.ToString();
    
                inSeries.ChartType = (SeriesChartType)System.Enum.Parse(typeof(SeriesChartType), DropDownListChartType.SelectedValue.ToString());
            }
    
            private void AddDataToSeries(Series series)
            {
                if (Page.Request["ChartType"] == null)
                    AddAllRegionData(series);
                else
                    AddSpecificRegionData(series);
            }
    
            private void AddAllRegionData(Series series)
            {
                DataTable sales = ExampleData.Tables["RepsSales"];
                DataTable regions = ExampleData.Tables["Region"];
    
                var query = from reps in sales.AsEnumerable()
                            join region in regions.AsEnumerable()
                            on reps.Field<int>("RegionID") equals region.Field<int>("RegionID")
                            group reps by region.Field<string>("RegionName") into regionGroup
                            select new { Region = regionGroup.Key, Sales = regionGroup.Sum(total => total.Field<int>("Sales")) };
    
                // Populate new series with data
                foreach (var value in query)
                {
                    series.Points.AddXY(value.Region, value.Sales);
                }
    
                // Step 7 - Make this series drillable
                for (int i = 0; i < series.Points.Count; i++)
                {
                    series.Points[i].Url = string.Format("RegionReport.aspx?region={0}&ChartType={1}", series.Points[i].AxisLabel, DropDownListChartType.SelectedValue);
                }
            }
    
            private void AddSpecificRegionData(Series series)
            {
                var query = from reps in ExampleData.RepsSalesTable.AsEnumerable()
                            join region in ExampleData.RegionTable.AsEnumerable()
                            on reps.Field<int>("RegionID") equals region.Field<int>("RegionID")
                            where region.Field<string>("RegionName") == (Page.Request["Region"] ?? "East")
                            select new { RepName = reps.Field<string>("Name"), Sales = reps.Field<int>("Sales") };
    
                // Populate new series with data
                foreach (var value in query)
                {
                    series.Points.AddXY(value.RepName, value.Sales);
                }
    
                // Step 7 - Make this series drillable
                for (int i = 0; i < series.Points.Count; i++)
                //{
                //    // Add drill down code to drill to a third chart
                //}
            }
    
            private void AddDrillDown(Series series)
            {
                for (int i = 0; i < series.Points.Count; i++)
                {
                    series.Points[i].Url = string.Format("RegionReport.aspx?region={0}&ChartType={1}", series.Points[i].AxisLabel, DropDownListChartType.SelectedValue);
                }
            }
        }
    }
    

Step 7 – Add an http handler to the Web.Config for the Chart

  1. Open the Web.Config file.
  2. Add an http handler for the chart.
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpHandlers>
      <add path="ChartImg.axd" verb="GET,HEAD,POST" validate="false"
           type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </httpHandlers>
  </system.web>
</configuration>

Your project is now complete.

You now have a report that shows you the total sales per region.

Click on the report and you have the sales per region broken out by sales rep.

And your done.

Download the project here: SampleChart.zip

A basic reporting chart in ASP.NET

It is time to learn to write some charts. By charts I mean graphic views for reporting on data.

Obtaining MSChart

For .NET 4, MSChart is included in the .NET Framework, so if you have installed .NET 4, you have already obtained MSChart.

For .NET 3.5, the MSChart project which was an add-on. If you are using .NET 3.5, you need to download and install the add-on.

Note: I am using .NET 4 and it was installed with Visual Studio 2010, so I have no need to install the add-on.

Also, we are going to the very minimal steps manually. Many of these steps may be done for you (for example, the Visual Studio Designer will populate the Web.Config for you, but it is always good to know how do things yourself.

Report Example Use Case

Imagine you have sales trending for four years, 2009-2012, and you want to visualize this trend. You want a chart that should all four years, with the quarter results next to each other.

Download the project here: SampleChart.zip

Step 1 – Create the Visual Studio project

  1. In Visual Studio, click on File | New | Project.
  2. Select Visual C# | Web from the Installed Templates.
  3. Locate and select ASP.NET Empty Web Application.
    Note: I like to demonstrate using an Empty project you nothing is done for you, and you have to learn everything you actually need to do.
  4. Give the project a name.
  5. Click OK.
  6. Right-click on the newly created project and click Add | Reference.
  7. Select the .NET tab.
  8. Locate System.Web.DataVisualization and highlight it.
  9. Click OK.

Step 2 – Add a web form for your chart

  1. Right-click on the Project and choose Add |  New Item.
  2. Select Web Form.
  3. Give the file a name.
    I named my file  Report.aspx.
  4. Click OK.

Step 3 – Create a data object for the report

  1. Right-click on the Project and choose Add |  Class.
  2. Give the file a name.
    I named my file  Data.cs.
  3. Click OK.

Step 4 – Add example data to the data object for the report

While in a real world scenario, you would get the data from a database or somewhere, lets first just create some sample data.

  1. Create a few lists of numbers, one for each year as shown.
    namespace CompareYearsByQuarter
    {
        public class Data
        {
            public int[] Sales2009 = new int[] { 47, 48, 49, 47 };
            public int[] Sales2010 = new int[] { 47, 50, 51, 48 };
            public int[] Sales2011 = new int[] { 50, 52, 53, 46 };
            public int[] Sales2012 = new int[] { 53, 54, 55, 49 };
        }
    }
    

That is it, your fake example data is prepared.

Step 5 – Add a Chart to the Report.aspx file

  1. Open the Report.aspx file.
  2. Add a Register to the System.Web.DataVisualization assembly.
  3. Locate the div inside the body.
  4. Inside the div, add a Chart that includes a ChartArea.
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Report.aspx.cs" Inherits="CompareYearsByQuarter.Report" %>
    
    <%@ Register Assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Chart ID="SalesReport" runat="server">
                <chartareas>
                    <asp:ChartArea Name="ChartArea1">
                    </asp:ChartArea>
                </chartareas>
            </asp:Chart>
        </div>
        </form>
    </body>
    </html>
    

Step 6 – Add code the Report.aspx.cs file

  1. Open the Report.aspx.cs file.
  2. Create an instance of the Data object that has our sample data.
  3. Add code in the Page_Load method to configure the Chart a separate series of data for each year.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.DataVisualization.Charting;
    
    namespace CompareYearsByQuarter
    {
        public partial class Report : System.Web.UI.Page
        {
            Data data = new Data();
    
            protected void Page_Load(object sender, EventArgs e)
            {
                Series year2009 = new Series("Sales 2009");
                // Populate new series with data
                foreach (var value in data.Sales2009)
                {
                    year2009.Points.AddY(value);
                }
                SalesReport.Series.Add(year2009);
    
                Series year2010 = new Series("Sales 2010");
                // Populate new series with data
                foreach (var value in data.Sales2010)
                {
                    year2010.Points.AddY(value);
                }
                SalesReport.Series.Add(year2010);
    
                Series year2011 = new Series("Sales 2011");
                // Populate new series with data
                foreach (var value in data.Sales2011)
                {
                    year2011.Points.AddY(value);
                }
                SalesReport.Series.Add(year2011);
    
                Series year2012 = new Series("Sales 2012");
                // Populate new series with data
                foreach (var value in data.Sales2012)
                {
                    year2012.Points.AddY(value);
                }
                SalesReport.Series.Add(year2012);
            }
        }
    }
    

Step 7 – Add an http handler to the Web.Config for the Chart

  1. Open the Web.Config file.
  2. Add an http handler for the chart.
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpHandlers>
      <add path="ChartImg.axd" verb="GET,HEAD,POST" validate="false"
           type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </httpHandlers>
  </system.web>
</configuration>

You are done. Build and look at your report.

You now have a simple report that should show you the sales trend for quarters 1,2,3,4 over four years. Your chart should look like this.

Download the project here: SampleChart.zip

I demand a simpler CSS for HTML5!

Look, I love the browser as much as the next person, but that is as a user. I have no love for web development and the developers of html and css and the browsers are the reason why. Some things are not as hard as they are making it out to be.

HTML5 is becoming all the rage and the buzz world of the day. “Hey, just use HTML5 and all your problems will be solved.” Non-technical decision makers (and technical ones for that matter) are buying this. What nobody tells these people is that HTML5 is a current problem in and of itself. First, it is not a complete standard yet. Second, everyone is implementing the standard now, but doing it slightly differently. The problem is exacerbated by the use of vendor specific tags for future standards.

There are 13 known prefixes.

prefix organization
-ms-, mso- Microsoft
-moz- Mozilla
-o-, -xv- Opera Software
-atsc- Advanced Television Standards Committee
-wap- The WAP Forum
-khtml- KDE
-webkit- Apple
prince- YesLogic
-ah- Antenna House
-hp- Hewlett Packard
-ro- Real Objects
-rim- Research In Motion
-tc- TallComponents

The design currently is the implement a feature first using a vendor tag and only later make it a standard feature. It is not possible to sustain this model for browser progress.

Could you imagine if there was a setting and every vendor implemented it with its prefix. For example, the display setting is already a problem and could get worse. What if it was as bad as this?

#main
{
  display: -ms-box;
  display: mso-box;
  display: -moz-box;
  display: -o-box;
  display: -xv-box;
  display: -atsc-box;
  display: -wap-box;
  display: -khtml-box;
  display: -webkit-box;
  display: prince-box;
  display: -ah-box;
  display: -hp-box;
  display: -ro-box;
  display: -rim-box;
  display: -tc-box;
}

Is it  possible that we may someday have to call a setting for each an every vendor prefix? Sure, but it is not likely. Ok, that above is a little absurd and an exageration, as nobody would use all those tags, we don’t even know what half those vendors are. However, even twice is too much! Do we really want to call a setting more than once? Should we ever have to? No, we shouldn’t. That is one of the biggest problems with web applications today.

I just can’t believe that we as developers are putting up with this html/css/browser problem.

I have to put the setting that is going to be the standard, and then for each browser, I have to put the browser specific setting. They are not smart enough to have each browser use the same tag for future standards, maybe something like -fs- for future standard, but instead lets use the vendor specific tag -moz- for mozilla and -webkit so we have to have a different tag for the same setting added for every browser we wish to support.

This is nonsense. I am so embarrassed for the organizations and their developers who have brought us to this point. We have to make every setting multiple times? Really? I am so glad I am not a developer for a browser because I take pride in my work and I would be so embarrassed to be part of such a mess.

How is it that browser developers aren’t smart enough to figure out a way we can use a single css tag, even for future standards?

Too many browsers

Competition is supposedly a good thing right? Well, I am not so sure that when dealing with free projects that is the case. I believe it is true for competitive businesses, but nobody is selling a browser.

Browsers are starting to sprawl worse than Linux. How many browsers do we rally need?

Here is a short list of browsers and they are all free:

  • IE 6, 7, 8, 9
  • Firefox
  • Chrome
  • Opera
  • Safari
  • Konqueror (KDE)

Sometimes with free projects, different from commercial projects, a division of the work force is a bad thing. I feel the same way about browsers as I do for Linux. If two groups worked together, they would often get more done than working apart. Sometimes there are natural divisions that lead to benefits in different areas, such as a desktop Linux version versus a server Linux version. With browsers there really isn’t a natural division like that.

We are re-inventing the wheel with each browser.

Unfortunately, control of the browser is coveted. The browser is the single most used application by the billions of computer users on our world. Controlling something as simple as the default browser homepage could mean the difference of millions, and perhaps billions, of dollars in advertising sales.

So to me, the question is this: How can we have a single browser but every commercial company still gets this “control” that they so desperately want?  Wow…once you really get the question pinned down, the answer is easy.

There is no reason that a single browser shouldn’t exist and all current browser developers could stop working on their browser and get one single browser to work. Use a BSD license so Windows and Apple and everyone else could include this browser with their own default settings (the default home page however they want, etc…), and mobile phones could do the same.

Then the next time the standard is increased from html5 to html6, we won’t have the mess we have now trying to go to html5. And we won’t have to wait as long because the combined efforts will take us to there so much faster.

A simple Log singleton in C#

Here is a simple Log singleton in C#.

Updated: 7/25/2016

using System;
using System.IO;

namespace Rhyous.Logging
{
    public class Log
    {

        #region Singleton

        private static readonly Lazy<Log> Lazy = new Lazy<Log>(() => new Log());

        public static Log Instance { get { return Lazy.Value; } }

        internal Log()
        {
            LogFileName = "Example";
            LogFileExtension = ".log";
        }

        #endregion

        public StreamWriter Writer { get; set; }

        public string LogPath
        {
            get { return _LogPath ?? (_LogPath = AppDomain.CurrentDomain.BaseDirectory); }
            set { _LogPath = value; }
        } private string _LogPath;

        public string LogFileName { get; set; }

        public string LogFileExtension { get; set; }

        public string LogFile { get { return LogFileName + LogFileExtension; } }

        public string LogFullPath { get { return Path.Combine(LogPath, LogFile); } }

        public bool LogExists { get { return File.Exists(LogFullPath); } }

        public void WriteLineToLog(string inLogMessage)
        {
            WriteToLog(inLogMessage + Environment.NewLine);
        }

        public void WriteToLog(string inLogMessage)
        {
            if (!Directory.Exists(LogPath))
            {
                Directory.CreateDirectory(LogPath);
            }
            if (Writer == null)
            {
                Writer = new StreamWriter(LogFullPath, true);
            }

            Writer.Write(inLogMessage);
            Writer.Flush();
        }

        public static void WriteLine(string inLogMessage)
        {
            Instance.WriteLineToLog(inLogMessage);
        }

        public static void Write(string inLogMessage)
        {
            Instance.WriteToLog(inLogMessage);
        }
    }
}

Note: This is not tested with multiple threads as this is a simple example.

AOP – Implementing a lazy loading property in C# with PostSharp

When developing in C#, you may have an object that contain properties that need to be initialized before they can be used. Think of a List<String> property. If you forget to initialize it, you are going to a NullReferenceException error. The List can be initialized as part of the constructor to solve this exception. However, maybe the List isn’t always used and you only want to load it if it needs to be used. So many people create a property that initializes iteself on first use. While this is not a bad idea, in C# it results in one line of code becoming at least six lines of code because you have to break out the auto property.

Here is the one line version verses the six line version (I can make it five lines if I put the private variable on the same line as the last bracket, which is a syntax I like with full properties).

List AddressLines { get; set; }
public List AddressLines
{
    get { return _AddressLines; }
    set { _AddressLines = value; }
}
private List<String> _AddressLines;

Wouldn’t it be nice if we could do this by only added single line of code, in this case an attribute? It can be that easy. Creating an instance on first use, or lazy loading, is a cross-cutting concern and can be extracted to an aspect using PostSharp. This article is going to show you how to do this.

It is assumed you have the following already installed and licensed:

  1. Visual Studio
  2. PostSharp

Step 1 – Create your Visual Studio Project

So to show you how this works, let’s get started.

  1. Create a sample Console Application project in Visual Studio.
  2. Add a reference to PostSharp.

Step 2 – Create an example class with properties

Ok, so let’s go ahead and create an example class called Address.

  1. Right-click on your project and choose Add | Class.
  2. Give the class file a name.
    I named this class Address.cs.
  3. Click OK.
  4. Add properties needed to store and address.
    Here my Address class working.
using System;
using System.Collections.Generic;

namespace ExampleAspects
{
    public class Address
    {
        public List AddressLines
        {
            get { return _AddressLines; }
            set { _AddressLines = value; }
        } private List<String> _AddressLines;

        public String City { get; set; }

        public String State { get; set; }

        public String Country { get; set; }

        public String ZipCode { get; set; }
    }
}

So our goal is to use Aspect-oriented programming to extract the lazy load something like this:

[LazyLoadAspect]
public List AddressLines { get; set; }

For me this is much clearer and more readable than the full property. Let’s make this happen in the next step.

Step 3 – Create the LazyLoadAspect

Ok, so let’s go ahead and create an example class called Address.

  1. Right-click on your project and choose Add | Class.
  2. Give the class file a name.
    I named this aspect class LazyLoadAspect.cs. Another good name might be InstantiateOnFirstUse or something.
  3. Make the class inherit from LocationInterceptionAspect.
  4. Override the OnGetValue method.
  5. Write code to get the value, check if it is null, and if null instantiate and set the value.
  6. Add a Type property that takes a type and implement that type if it is set, just in case you want to initialize using a child class. Otherwise how would you implement an interface.
using System;
using PostSharp.Aspects;

namespace Rhyous.ServiceManager.Aspects
{
    [Serializable]
    public class LazyLoadAspect : LocationInterceptionAspect
    {
        public Type Type { get; set; }

        public override void OnGetValue(LocationInterceptionArgs args)
        {
            args.ProceedGetValue();
            if (args.Value == null)
            {
                args.Value = Activator.CreateInstance(Type ?? args.Location.PropertyInfo.PropertyType);
                args.ProceedSetValue();
            }
        }
    }
}

Note: You may have a factory for creating your objects and you could replace the Activator.CreateInstance method with your factory method.

As discussed, replace the full property with this:

[LazyLoadAspect]
public List AddressLines { get; set; }

Step 4 – Prove your LazyLoadAspect works

Give it a try by creating an instance of Address in the Main method of Program.cs.

using System;
using Common.Aspects;
using PostSharp.Aspects;

namespace AspectExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            Address address = new Address();
            // NullReferenceException would occur here without the LazyLoadAspect
            address.AddressLines.Add("To: John Doe");
            address.AddressLines.Add("100 N 100 E");
            address.AddressLines.Add("Building 12 Floor 5 Suite 530");
            address.City = "SomeCity";
            address.State = "Utah";
            address.Country = "USA";
        }
    }
}

Well, you are done.

Please take time to look at how the code actually ended up using ILSpy or .NET Reflector.

Return to Aspected Oriented Programming – Examples

AOP – Implementing try catch in C# with PostSharp

I’ll be honest, I always cringe whenever I have to use try/catch. I do everything I can to avoid it. Besides being a resource hog, try/catch statements clutter code making it harder to read. So naturally I was excited when learning about Aspect-oriented programming (AOP) and PostSharp (the AOP library for C#) that try/catch statements are cross-cutting concerns and can be implemented as aspects.

It is assumed you have the following already installed and licensed:

  1. Visual Studio
  2. PostSharp

Step 1 – Create your Visual Studio Project

So to show you how this works, lets get started.

  1. Create a sample Console Application project in Visual Studio.
  2. Add a reference to PostSharp.
  3. Populate the Program.cs with an example exception as shown.
using System;
using Common.Aspects;

namespace AspectExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            ThrowSampleExecption();
        }

        private static void ThrowSampleExecption()
        {
            throw new ApplicationException("Sample Exception");
        }
    }
}

Ok, now we have an example exception, lets show how we can catch this exception, log it, and continue.

Step 2 – Creating an exception aspect

  1. Right-click on your project and choose Add | Class.
  2. Give the class a name.
    I named my class ExceptionAspect.
  3. Click OK.
  4. Make the class inherit from OnExceptionAspect.
    Note: If you haven’t added a reference to PostSharp, you’ll need to do that now.
  5. Add a string property called Message.
  6. Add a Type property called ExceptionType.
  7. Add a FlowBehavior property called Behavior.
    The default value is FlowBehavior.Default.
  8. Override the OnException method.
  9. In the OnException method, create a message and log it.
    For this example, I will just log to the Visual Studio  Output window.
  10. In the OnException method, set the FlowBehavior to the Behavior property.
  11. Override the GetExceptionType method and configure it to return the ExceptionType property.
using System;
using System.Diagnostics;
using PostSharp.Aspects;

namespace Common.Aspects
{
    [Serializable]
    public class ExceptionAspect : OnExceptionAspect
    {
        public String Message { get; set; }

        public Type ExceptionType { get; set; }

        public FlowBehavior Behavior { get; set; }

        public override void OnException(MethodExecutionArgs args)
        {
            string msg = DateTime.Now + ": " + Message + Environment.NewLine;
            msg += string.Format("{0}: Error running {1}. {2}{3}{4}", DateTime.Now, args.Method.Name, args.Exception.Message, Environment.NewLine, args.Exception.StackTrace);
            Debug.WriteLine(msg);
            args.FlowBehavior = FlowBehavior.Continue;
        }

        public override Type GetExceptionType(System.Reflection.MethodBase targetMethod)
        {
            return ExceptionType;
        }
    }
}

Your ExceptionAspect class is complete and ready to use.

Step 3 – Apply the ExceptionAspect

  1. Add ExceptionAspect as an attribute to the ThrowSampleException method.
  2. Set the ExceptionType property to type of exception being thrown, which is an ApplicationException in this example.
  3. Set the Message property to hold a message.
  4. Set the Behavior property to FlowBehavior.Continue.
using System;
using Common.Aspects;
using PostSharp.Aspects;

namespace AspectExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            ThrowSampleExecption();
        }

        [ExceptionAspect(ExceptionType = typeof(ApplicationException), Message = "An example exception.", Behavior = FlowBehavior.Continue)]
        private static void ThrowSampleExecption()
        {
            throw new ApplicationException("Sample Exception");
        }
    }
}

This is now complete. You have now implemented try/catch as an aspect.
You should take the time to look at your code with .NET Reflector or ILSpy to see what is really being done.
So here is the resulting code for the method accord to ILSpy.

  • Notice that our one line of code in the original method is in the try block.
  • Notice that in the catch block, the OnException method is called.
  • Notice that the catch block also has a switch statement based on the FlowBehavior to determine whether to continue or rethrow, etc.
// AspectExamples.Program
private static void ThrowSampleExecption()
{
	try
	{
		throw new ApplicationException("Sample Exception");
	}
	catch (ApplicationException exception)
	{
		MethodExecutionArgs methodExecutionArgs = new MethodExecutionArgs(null, null);
		MethodExecutionArgs arg_1F_0 = methodExecutionArgs;
		MethodBase m = Program.<>z__Aspects.m2;
		arg_1F_0.Method = m;
		methodExecutionArgs.Exception = exception;
		Program.<>z__Aspects.a0.OnException(methodExecutionArgs);
		switch (methodExecutionArgs.FlowBehavior)
		{
		case FlowBehavior.Default:
		case FlowBehavior.RethrowException:
			IL_55:
			throw;
		case FlowBehavior.Continue:
			methodExecutionArgs.Exception = null;
			return;
		case FlowBehavior.Return:
			methodExecutionArgs.Exception = null;
			return;
		case FlowBehavior.ThrowException:
			throw methodExecutionArgs.Exception;
		}
		goto IL_55;
	}
}

You now can implement pretty much any try/catch block as an Aspect using the ExceptionAspect.

Reusability

One of the main benefits of Aspects is that they take cross-cutting concerns and make them modular. That means that like class files, they are now reusable. Now it is easy to use, link to, or copy and paste your ExceptionAspect class into any other project.

Return to Aspected Oriented Programming – Examples

Why I used the ‘goto’ statement in C# today

Today I did something I have only ever done once before. I used the goto statement in C#.

In batch files I used goto all the time. For those who don’t know, LANDesk Management Suite supports batch file distribution packages and I became an expert at scripting with batch files. Of course, as a batch file scripting expert, I am very good at using the goto statement, but honestly using it in C# is generally frowned upon. I am sure there are other poeple like me that have used a language where goto is popular and can recognize uses for it when they crop up.

Anyway, I needed to start, stop, or restart a windows service and I need to perform the actions asynchronously in the background. Everytime I tried to create three methods, a Start, Stop, and Restart, the code grew in size and there was lots of duplication. So I kept going back to a single method that takes an action of start, stop, restart.

Since I wanted to run the action in the background, I created a ServiceWorker that inherits from BackgroundWorker and has an Action property (for Stop, Start, Restart) and here is the method I used.

private void StartOrStopService(object sender, DoWorkEventArgs doWorkEventArgs)
{
    ServiceWorker worker = sender as ServiceWorker;
    if (worker != null)
    {
    restart:
        switch (worker.Action)
        {
            case "Start":
                Log.WriteLine("Attempting to start service: " + worker.ServiceController.DisplayName);
                worker.ServiceController.Start();
                worker.ServiceController.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMilliseconds(30000));
                break;
            case "Restart":
            case "Stop":
                worker.ServiceController.Stop();
                worker.ServiceController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMilliseconds(30000));
                if (worker.Action == "Restart")
                {
                    worker.Action = "Start";
                    goto restart;
                }
                break;
            default:
                return;
        }
    }
}

I of course have other options, but if I break this method out into more methods, it is actually more code. For example, if I make Start and Stop methods,

private void StartOrStopService(object sender, DoWorkEventArgs doWorkEventArgs)
{
    ServiceWorker worker = sender as ServiceWorker;
    if (worker != null)
    {
        switch (worker.Action)
        {
            case "Start":
                StartService(worker);
                break;
            case "Stop":
                StopService(worker);
                break;
            case "Restart":
                StopService(worker);
                StartService(worker);
                break;
            default:
                return;
        }
    }
}

private void StartService(ServiceWorker worker)
{
    Log.WriteLine("Attempting to start service: " + worker.ServiceController.DisplayName);
    worker.ServiceController.Start();
    worker.ServiceController.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMilliseconds(30000));
}

private void StopService(ServiceWorker worker)
{
    Log.WriteLine("Attempting to stop service: " + worker.ServiceController.DisplayName);
    worker.ServiceController.Stop();
    worker.ServiceController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMilliseconds(30000));
}

What’s your opinion?

Do you like 1 method with 28 lines including a goto statement?

Do you like 3 methods totaling 36 lines without the goto statement?

Leave a comment and let me know.

AOP – Tracing methods in C# with PostSharp

Suppose you are tasked with adding logging to trace when a method starts and when it ends. Now suppose that you are tasked to do this for every method in a project, lets say you have to do this for 1,000 methods scattered throughout all your objects. Every method included would have two lines of logging code, one at the start, one at the end. That means you have to add two lines of code per method or 2,000 lines of code.  Sure, you could extract the logging methods into a static or singleton making it “easier”, but in the end, you still end up with 2,000 lines of code, two per method.

Is adding 2,000 lines of code the right solution? No it is not. These lines of code can be distracting and can make a method less readable. A single line method becomes three lines. Your class files get bigger, especially if they are method heavy. Also, these lines of code break the SOLID principles in that 1) you are repeating yourself, and 2) your method no longer has a single responsibility as it is doing what it was design for and it is doing tracing, etc. It doesn’t have to be this way.

AOP can allow you to do the same task but have the code in a single place. Including spaces and brackets, the C# MethodTracingAspect file is only 36 lines of code and to implement this into all methods in a namespace an AspectInfo.cs file is used with only three lines of code.

Which would you rather deal with: 39 lines of code in two class files, or 2,000 lines of code spread throughout ever class file?

This document assumes you have the done the following already:

  1. Installed Visual Studio
  2. Installed PostSharp
  3. Licensed PostSharp

Note: While PostSharp has a free version, my examples will likely require the licensed version.

Step 1 – Create a new C# project for Aspects

  1. In Visual Studio, choose File | New | Project.
  2. Choose a Visual C# Console Application.
  3. Give the project a Name.
    Note: I named my project AspectExamples
  4. Click Ok.

Your project is now created.

Step 2 – Add a reference to PostSharp

  1. In Solution Explorer, right-click on your new project and choose Add Reference.
  2. In the Add Reference window, click to select the .NET tab.
  3. Locate PostSharp and click to highlight it.
  4. Click Ok.

You have now added PostSharp as a reference to your project.

Step 3 – Create an Aspect for method tracing

  1. Right-click on your project and choose Add | Class.
  2. Give the class a Name.
    Note: I named my version of this class MethodTraceAspect.
  3. Add a using reference to the PostSharp.Aspects namespace.
  4. Make the object inherit from OnMethodBoundaryAspect.
  5. Override the OnEntry method.
  6. Override the OnExit method.
  7. Add code to each method for logging to the Output window using Debug.WriteLine().
    Note: Obviously, you can use any logging library you software may use.
  8. Add code to make sure that methods inside methods are properly tabbed.

Here is my final class file.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using PostSharp.Aspects;

namespace AspectsExamples
{
    [Serializable]
    public class MethodTraceAspect : OnMethodBoundaryAspect
    {
        private static int _TabCount = 0;
        private static Stack<long> _StartTimeStack = new Stack<long>();

        public override void OnEntry(MethodExecutionArgs args)
        {
            Debug.WriteLine(GetTabs() + "Method started: " + args.Method.Name);
            _TabCount++;
        }

        public override void OnExit(MethodExecutionArgs args)
        {
            _TabCount--;
            Debug.WriteLine(GetTabs() + "Method completed:" + args.Method.Name);
        }

        private static String GetTabs()
        {
            string tabs = string.Empty;
            for (int i = 0; i < _TabCount; i++)
            {
                tabs += "\t";
            }
            return tabs;
        }
    }
}

You now have a modular Aspect that you can use to add method start, method end logging to any method in any C# project.

Step 4 – Implement the Aspect for method tracing

Implementing the Aspect for method tracing is accomplished by using an Attribute. The attribute can be added to a single method, a class, or a namespace.

We will use the following Program.cs file will demonstrate this.

using System;

namespace AspectExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            HelloWordMethod();
        }

        private static void HelloWordMethod()
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

Option 1 – Adding the Aspect to methods

When adding this to method, you have to add it for each method.

  1. Add the MethodTraceAspect to the Main method.
  2. Add the MethodTraceAspect to the HelloWordMethod.
using System;

namespace AspectExamples
{
    class Program
    {
        [MethodTraceAspect]
        static void Main(string[] args)
        {
            HelloWordMethod();
        }

        [MethodTraceAspect]
        private static void HelloWordMethod()
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

Ok, lets test this.

  1. Click Debug | Start Debugging to run the application in debug mode.
  2. Look at the Output and you should see the following lines.
Method started: Main
	Method started: HelloWordMethod
	Method completed:HelloWordMethod
Method completed:Main

Option 2 – Adding the Aspect to classes

When adding this to a class, you don’t have to add it for each method in the class.

  1. Add the MethodTraceAspect to the Program class.
using System;

namespace AspectExamples
{
    [MethodTraceAspect]
    class Program
    {
        static void Main(string[] args)
        {
            HelloWordMethod();
        }

        private static void HelloWordMethod()
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

Ok, lets test this.

  1. Click Debug | Start Debugging to run the application in debug mode.
  2. Look at the Output and you should see the following lines.
Method started: Main
	Method started: HelloWordMethod
	Method completed:HelloWordMethod
Method completed:Main

Option 3 – Adding the Aspect to a namespace

When adding this to a namepsace, you don’t have to add it for each class or every method in each class. Instead it is automatically added to every method in every class in the namespace.

  1. Add the MethodTraceAspect to the namespace.
    Note: Notice the syntax is slight different for adding to a namespace than for a class or method.
using System;

[assembly: MethodTraceAspect]
namespace AspectExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            HelloWordMethod();
        }

        private static void HelloWordMethod()
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

Ok, lets test this.

  1. Click Debug | Start Debugging to run the application in debug mode.
  2. Look at the Output and you should see the following lines.
Method started: Main
	Method started: HelloWordMethod
	Method completed:HelloWordMethod
Method completed:Main

Note: For real projects that aren’t just examples, it is a good idea to implement Aspects to a namespace in a separate file, such as an AspectInfo.cs file.

using Common.Aspects;
[assembly: MethodTraceAspect]
namespace AspectExamples {}

Congratulations, you have implemented an Aspect in C# using PostSharp.

Return to Aspected Oriented Programming – Examples

How to insert table rows using a DataTable in C#

You may have already read How to query a SQL database in C#? and How to insert a row into a Microsoft SQL database using C#? but you are looking for more information on how to insert rows using a DataTable.  Well, here is how.

The example code below assumes you have a simple database called ExampleDB, with one table called Person that has an Id (Primary Key and auto increments), a FirstName, and a LastName column.

Further information is in the comments in the sample code below.

using System.Data;
using System.Data.SqlClient;

namespace SQLExamples
{
    public class Program
    {
        static void Main(string[] args)
        {
            // Step 1 - Create the connection with a Connection string

            // Create a connection builder
            var connectionBuilder = new SqlConnectionStringBuilder();
            connectionBuilder.IntegratedSecurity = true;
            connectionBuilder.DataSource = "localhost";
            connectionBuilder.InitialCatalog = "ExampleDB";

            // Create a connection that uses the connection string
            SqlConnection connection = new SqlConnection(connectionBuilder.ConnectionString);

            // Step 2 - Open the Connection
            connection.Open();

            // Step 3 - Perform database tasks with the open connection (Examples provided...)

            //
            // Example 1 - Insert data with a query
            //

            // Create an insert query
            string insertQuery = "Insert into Person (FirstName, LastName) Values ('Jared', 'Barneck')";

            // Create an SqlCommand using the connection and the insert query
            SqlCommand insertCommand = new SqlCommand() { Connection = connection, CommandText = insertQuery };

            // Run the ExecuteNonQuery() method
            int rowsAffected = insertCommand.ExecuteNonQuery();

            //
            // Example 2 - Select * from a table
            //

            // Create a String to hold the query.
            string selectQuery = "SELECT * FROM Person";

            // Create an SqlCommand using the connection and the insert query
            SqlCommand selectCommand = new SqlCommand() { Connection = connection, CommandText = selectQuery };

            // Use the above SqlCommand object to create a SqlDataReader object.
            SqlDataReader queryCommandReader = selectCommand.ExecuteReader();

            // Create a DataTable object to hold all the data returned by the query.
            DataTable dataTable = new DataTable();

            // Use the DataTable.Load(SqlDataReader) function to put the results of the query into a DataTable.
            dataTable.Load(queryCommandReader);

            //
            // Example 3 - Insert many rows DataTable insert
            //

            // Add to the DataTable from example 2
            DataRow row1 = dataTable.NewRow();
            row1["FirstName"] = "John";
            row1["LastName"] = "Johnson";
            dataTable.Rows.Add(row1);

            DataRow row2 = dataTable.NewRow();
            row2["FirstName"] = "Jenni";
            row2["LastName"] = "Jenson";
            dataTable.Rows.Add(row2);

            string adapterInsertQuery = "Insert into Person (FirstName, LastName) Values (@FirstName, @LastName)";
            SqlCommand adapterInsertCommand = new SqlCommand() { Connection = connection, CommandText = adapterInsertQuery };
            adapterInsertCommand.Parameters.Add("@FirstName", SqlDbType.NVarChar, 255, "FirstName");
            adapterInsertCommand.Parameters.Add("@LastName", SqlDbType.NVarChar, 255, "LastName");

            SqlDataAdapter adapter = new SqlDataAdapter(selectCommand);
            adapter.InsertCommand = adapterInsertCommand;
            adapter.Update(dataTable);

            // Step 4 - Close the connection
            connection.Close();
        }
    }
}

You show now have a good starting point for using ADO.NET to manipulate a Database.

 

Return to ADO.NET and Database with C#