Microsoft Communities

Welcome to WindowsClient.net | Sign in | Join

Writing n-Tier Applications using Windows Forms

Jason Beres
Senior Technology Evangelist, Infragistics
Infragistics - Powering the Presentation Layer
http://www.infragistics.com

There are many examples of ASP.NET applications on the web today, from the Start Kits at http://www.asp.net to the various community efforts like DotNetNuke. The hole that seems to exist is an example of a well designed and architected Windows Forms application. The Tracker application is a Windows Forms reference application that starts to fill that hole. The main purpose of this application is to demonstrate best practices for using Microsoft .NET technologies, such as the Application Blocks for .NET and WS-Security, along with a clean and exciting user interface which can also be Tablet PC enabled. While I was writing the Tracker application, I also wrote a 10 chapter 110 page e-Book that goes into details over the how and why the application was written. The purpose for this article is to give you a high-level overview of the Tracker application, and the information you need to get it running on your machine so you can dig into the code yourself.

Note:  To download the code for the Tracker reference application, and the 110 page e-Book, visit DevCenter at http://devcenter.infragistics.com/RefApps/Tracker/tracker.aspx.

Overview of Tracker

Tracker is a Windows Forms application that helps project managers or developers manage three main aspects of daily software development tasks:

  • Create tasks for a project (Tasks can be generic tasks, bugs, defects, etc…)
  • Track time for tasks (Time is a schedule and time per task, which in turn could be used for billing)
  • Track resources, such as contacts, documents and schedule

The Tracker application does this through the use of Project Workspaces (workspaces). Workspaces contain modules that implement the flow of developing a software project. Within a workspace, you may have resources that Tracker manages for you on a workspace by workspace basis. The concept for what Tracker can do is a combination of several actual bug and defect tracking applications, as well as the TaskVision Windows Forms reference application that can be found at http://www.windowsclient.net.

 A typical session when logged into Tracker might be:

Logging in to Tracker: Tracker can be configured in one of two ways for data access. You can use an XML Web Service or you can access SQL Server directly. The login screen allows you to choose where the data source for Tracker is.

Figure 1.1: The Tracker login screen

Tasks View: All of the Tasks for the selected workspace are listed. A task can be marked as a bug, defect, suggestion, request or task. Using the context menu on the grid, or the View main menu, you can filter the display of tasks that are listed. If you look at the process of developing a piece of software, the details of an item would start as a task, then move to testing, could be a defect, may be referred back as a bug or marked as completed. Each task that you enter tracks the type of task, the status of the task, who is assigned the task, and the percentage complete of the task. Figure 1.2 shows the Task view of Tracker.

Figure 1.2: The Tracker Tasks view.

Contact Manager: The Contact Manager allows you to create a top level company, and then add additional people that represent that company. This is different from Outlook, where everyone is a contact. In Tracker, each Workspace is linked to a company, each company has users.

Figure 1.3: The Tracker Contacts view.

Schedule and Timeline: The Schedule and Timeline module allows you to link tasks that are created by a user or manager to the developers that are working on them. This is not a full blown Microsoft Project like charting application, rather a scheduling interface that allows you to track what resources are being used and when.

Figure 1.4: The Tracker Timeline view.

Reports: Using the charting capabilities of the NetAdvantage 2004 Volume 1 toolset, various reports can be viewed using the Report menu item.

Figure 1.5: The Tracker Reports view

Technologies used in Tracker

With the great tools from Microsoft, as well as Infragistics, key infrastructure aspects of the Tracker application are simply plugged into the Tracker application and configured for use. The Application Blocks found at the Microsoft Architecture Center at http://msdn.microsoft.com are used in Tracker, as well as the user interface elements from Infragistics.

The application blocks are provided by Microsoft as Best Practice implementations of .NET Technologies. The following application blocks are used in the Tracker application:

  • Data Access Application Block
  • Exception Management Application Block
  • Application Updater Application Block

If you have not downloaded the Application Blocks, you can do so at the Microsoft .NET Architecture Center at: http://msdn.microsoft.com/architecture/.

Microsoft provides several more application blocks not used, and there were reasons for why some were implemented and some were not. In Chapter 6 of the accompanying e-Book, Integrating the Microsoft Application Blocks in Tracker, you will learn how each application block was used and why.

Tracker Security Model

Security is always a big deal when writing applications, and Tracker is no different. Since XML Web Services are used, I decided to implement the WS-Security implementation which is part of the Web Services Enhancements Toolkit. Using WS-Security, the plumbing of a robust security model is built in, so there was no need to customize how authentication is handled.

The Tracker application can be configured not to use Web Services, so other security models can easily be implemented. In Chapter 2 of the e-Book, Understanding the Architecture Design and Goals, I explain how WS-Security is used, give you some resources to articles and books that will help you decide what security model to use in your own applications.

Key Concepts used in Tracker

In order to showcase what can be done with Windows Forms in the .NET Framework; Tracker implements some other important aspects of writing commercial class Windows applications. Considering the Application Blocks from Microsoft are being used, as well as the WS-Security implementation, some other key concepts that Tracker showcases are:

  • XML Web Services
  • Complete separation of user interface, data access and business logic
  • Writing a scalable .NET application that does not use ADO.NET Datasets for data manipulation
  • Security and Authentication
  • Professional, Clean User Interface using Infragistics controls
  • Multiple threads in a Windows Forms application

Tracker Architecture Goals

The Tracker architecture is similar to several other enterprise type samples you can find on the Internet. The problem with Windows Forms that I see is there are not enough sample applications on the web that use something different than a direct data bind to a Dataset coming from either an XML Web Service or SQL Server. With Tracker, I wanted to take the same approach used by Enterprise applications like .NET Pet Shop or FMStocks, which have a clearly defined layered approach to the application architecture, without using the Dataset object.

This added more complexity to the application, since without Datasets, you lose a lot of "built-in" functionality, but it was worth the effort. The biggest complaint of using Datasets in an enterprise application is the overhead they incur, especially when used with XML Web Services. I somewhat agree and somewhat disagree with this notion, but I think it would be useful to you (hopefully you feel the same way), to see a pretty cool Windows Forms application with a different, non-Dataset approach. Of course, using Windows Forms, you obviously want to take advantage of features such as data binding. Data binding helps you get things done fast, and even though Datasets are not used in this application, the .NET Framework fully supports data binding using objects such as ArrayList.

Understanding the Architecture

To get an understanding of Tracker, let's first look at the actual Solution file in Visual Studio .NET, project by project, and list a description of each project and why it is important to the application.

Visual Studio .NET Solution file: Infragistics.Tracker

Projects within the solution:

AppSettings: This project contains 1 class, AppSettings, which holds the serialized application settings for an individual user. The following code will give you an idea of what this class looks like. (Only a portion of the code is shown)

<Serializable()> _
Public Class AppSettings
        Public LastName As String
        Public FirstName As String
        Public EmailAddress As String
        Public TypeOfConnection As String
        Public LANLocation As String
        Public WSLocation As String
        Public Password As String
        Sub New ( ByVal FirstName As String , ByVal LastName As String , _
                ByVal EmailAddress As String , ByVal TypeOfConnection As String , _
                ByVal LANLocation As String , ByVal WSLocation As String , _
  ByVal Password As String )
            Me .FirstName = FirstName
            Me .LastName = LastName
            Me .EmailAddress = EmailAddress
            Me .TypeOfConnection = TypeOfConnection
            Me .LANLocation = LANLocation
            Me .WSLocation = WSLocation
            Me .Password = Password
        End Sub
    End Class 

Tracker: The main Windows Forms application. This project references the Tracker.BusinessLogic application and the Tracker.Info application.

Tracker. BusinessLogic: Contains the business logic methods for the Tracker application. The business logic accepts and returns the business entity objects from the Tracker.Info project to and from the data access layer and the client application. The following snippet gives you a glimpse of how this class is designed.

Namespace Tracker.BusinessLogic
    <Serializable()> _
    Public Class Company
        Inherits App
        Function GetCompany( ByVal companyID As Integer ) _
            As Tracker.Info.CompanyInfo()
            
            If GetConnectionString Then
                Select Case TypeOfConnection
                    Case "WS"
                         Dim proxy As TrackerWS.DataServ1Wse = GetProxy()
                        Try
                            Return proxy.GetCompany(companyID)
                        Catch ex As Exception
                            Throw New ApplicationException(Exceptions.HandleError(ex))
                        End Try
                    Case "LAN"
                        Dim x As New Tracker.DataAccess.CompanyDB
                        Return x.GetCompany(companyID)
                End Select
            End If
        End Function

Tracker. DataAccess: Contains the code which interacts with SQL Server. The methods in the data access layer accept and return the objects from the Tracker.Info project to and from the business logic layer. The following code shows the GetCompany method from the CompanyDB class in the Tracker.DataAccess project that is called from the GetCompany method shown above.

Namespace Tracker.DataAccess
    <Serializable()> _
    Public Class CompanyDB
        Public Function GetCompany( ByVal companyID) As CompanyInfo()
            Dim d As SqlDataReader = _
SqlHelper.ExecuteReader(cnString, "Company_Sel_ByID", companyID)
            Dim c As New ArrayList
            While d.Read
                Dim al As CompanyInfo = New CompanyInfo
                al.CompanyID = IIf(IsDBNull(d("CompanyID")), "", d("CompanyID"))
                al.CompanyName = IIf(IsDBNull(d("CompanyName")), "", d("CompanyName"))
                al.Address = IIf(IsDBNull(d("Address")), "", d("Address"))
                al.City = IIf(IsDBNull(d("City")), "", d("City"))
                al.State = IIf(IsDBNull(d("State")), "", d("State"))
                al.ZipCode = IIf(IsDBNull(d("ZipCode")), "", d("ZipCode"))
                al.BillToAddress = IIf(IsDBNull(d("BillToAddress")), "", _ 
			d("BillToAddress"))
                al.BillToCity = IIf(IsDBNull(d("BillToCity")), "", d("BillToCity"))
                al.BillToState = IIf(IsDBNull(d("BillToState")), "", d("BillToState"))
                al.BillToZipCode = IIf(IsDBNull(d("BillToZipCode")), "", _ 
			d("BillToZipCode"))
                al.DateAdded = IIf(IsDBNull(d("DateAdded")), "", d("DateAdded"))
                al.AddedBy = IIf(IsDBNull(d("AddedBy")), "", d("AddedBy"))
                al.ChangeStamp = IIf(IsDBNull(d("ChangeStamp")), "", d("ChangeStamp"))
                c.Add(al)
            End While
            Return CType (c.ToArray( GetType (CompanyInfo)), CompanyInfo())
        End Function 

Tracker.Info: Business entity objects which map to the tables and fields in SQL Server. The classes in the Tracker.Info assembly are filled with serialized Arraylist types which are used in the other layers of the application. The following code is the CompanyInfo class, which is filled with data via the GetCompany method in the CompanyDB class, and sent from the CompanyDB class to its caller, which could be the Tracker.BusinessLogic project or the TrackerWS project. I am only showing a few of the fields from this class for brevity.

Namespace Tracker.Info
     <Serializable()> _
    Public Class CompanyInfo
        
        Private _companyID As Integer = 0
        Private _companyName As String = ""
        Private _address As String = ""
        Private _city As String = ""
        
        Sub New()
            MyBase.New()
        End Sub
        
        Sub New(ByVal CompanyID As Integer, _
            ByVal CompanyName As String, _
            ByVal Address As String, _
            ByVal City As String)
        End Sub
        
        Public Property CompanyID() As Integer
            Get
                Return _companyID
            End Get
            Set(ByVal value As Integer)
                _companyID = Integer.Parse(value)
            End Set
        End Property
        
        Public Property CompanyName() As String
            Get
                Return _companyName
            End Get
            Set(ByVal value As String)
                _companyName = value
            End Set
        End Property
        
        Public Property Address() As String
            Get
                Return _address
            End Get
            Set(ByVal value As String)
                _address = value
            End Set
        End Property
        
        Public Property City() As String
            Get
                Return _city
            End Get
            Set(ByVal value As String)
                _city = value
            End Set
        End Property
 
TrackerWS: Web Service which lies between the data access layer and the business logic layer. The XML Web Service accepts and returns the typed objects of the Tracker.Info project. The following code is the GetCompany method from the DataServ.asmx.vb class, which contains all of the public methods of the XML Web Service.

    <WebMethod()> _
    Public Function GetCompany(ByVal companyID As Integer) _
As Tracker.Info.CompanyInfo()
       
        If Authenticater() Then
            Dim x As New Tracker.DataAccess.CompanyDB
            Return x.GetCompany(Integer.Parse(companyID))
        End If
    End Function

The TrackerWS XML Web Service uses WS-Security from the Web Services Enhancements toolkit provided by Microsoft. Using this security model, each call to the web service is authenticated based on the hashed username and password token from the client. Each method has a call to another method named Authenticater which uses the current SOAP context to verify that the username and password is valid by looking up the data in SQL Server. The code for the Authenticater method is as follows:


    Private Function Authenticater() As Boolean
        Dim requestContext As SoapContext = HttpSoapContext.RequestContext
        Dim userToken As UsernameToken
        Dim returnValue As String
        If requestContext Is Nothing Then
            Throw New SoapException("Non-SOAP Message - Are you a hacker?", _
                            SoapException.ClientFaultCode)
        End If
        For Each userToken In requestContext.Security.Tokens
            If TypeOf userToken Is UsernameToken Then
                If userToken.PasswordOption = _
                        PasswordOption.SendHashed Then
                    Return True
                    Exit For
                Else
                    Throw New SoapException _
                        ("Password must be hashed", SoapException.ClientFaultCode)
                End If
            End If
        Next
    End Function 

WinFormsEx: A helper application that displays the Tracker splash screen on the Windows Forms client. This application was found at the Microsoft Regional Directors site and is written by Juval Lowy of iDesign (http://www.idesign.com), and also has a cool implementation of the Singleton pattern to only allow a single instance of your application to run. The reason I used this application was to demonstrate how to call a C# application on another thread from a VB.NET application, plus I thought the idea of having a reusable splash screen application was very cool.

Hopefully by seeing some of the code, you will get an idea of how the Tracker application ticks. Once you get into the e-Book and play with the code, you will learn more about how each layer of the application is implemented.

To get an idea of what all of this looks like in Visual Studio .NET, figure 1.6 is a representation of the Solution Explorer for the Infragistics.Tracker.

Figure 1.6: The Infragistics.Tracker Solution

All of these projects may seem like a lot, but this architecture serves a purpose. It breaks up the dependency of the client on the database, and it allows you to further enhance the client application, the business logic or the database without dramatically affecting each of the respective layers.

For example, while I was working on the application, I took this approach:

  • Create the Database in SQL Server.
  • Create the Business Entity Objects - these map to the database fields.
  • Create the Data Access Layer - interacts with the database, and uses the business entity objects.
  • Create the Web Service - calls the data access layer directly, and returns business entity objects to the caller.
  • Create the Business Logic Layer - calls the data access layer directly, or calls the XML Web Service.
  • Create the Tracker client - calls the business logic layer.

As I was modifying various aspects of the application, there were times when I needed to change a field in SQL Server. Since the client code, the XML Web Service, or the business logic layer had no knowledge of the data source (because the business entity objects are holding the data in ArrayLists), all I needed to do was modify either the data access layer code or the business entity object.

This approach made it easy to make changes knowing that my client would not be broken, and during deployment, there may be times when only one of the major layers of the application needs to be re-deployed because of a change, not the entire application. Figure 1.7 shows you how all of this comes together from 10,000 feet.

Figure 1.7: The Tracker Architecture from 10,000 feet

In figure 1.7, you can see how the various projects shown in figure 1.6 are used in the architecture. I have also shown in figure 1.7 where the application blocks from Microsoft are used. The application blocks saved a lot of code from being written, especially in the data access layer. In chapter 6 of the e-Book, you'll learn more about the application blocks and how they are implemented.

Now that you have an idea of the architecture of Tracker, the next section looks at the design goals of Tracker, and what you should expect to learn by going through this application.

Tracker Design Goals

The design goals for tracker are simple:

  • Create a cleanly architected Windows Forms application that showcases Visual Basic .NET and the .NET Framework.
  • Effectively use the application blocks provided by Microsoft.
  • Demonstrate a clean and effective user interface using Infragistics user interface elements of the NetAdvantage 2004 Volume 1 toolset.
  • Show how to easily create an ink-enabled user interface for the Tablet PC using the ink-enabled framework of the NetAdvantage 2004 Volume 1 toolset.

Each of the next sections will highlight how these points are built into the design goals of Tracker.

Create a cleanly architected Windows Forms application that showcases Visual Basic .NET and the .NET Framework

As you read e-Book and dig into the Tracker code, keep in mind that application architecture is a hotly debated topic by many of the smartest people that I know, all the time. I think that in each application that you write, you need to decide what is best for the task at hand. Immediately determining that an application’s architecture is good or bad without knowing what the application is doing is not a good idea. You may have to write utility applications that are console based and you can write all of the code in the Sub Main of the Console1 class. This approach would suite the purpose of the task at hand.

When looking at the various Starter Kit applications found at http://www.asp.net (the official ASP.NET web site hosted by Microsoft), which showcase how to write ASP.NET applications, you will notice that each one of them is architected different. As a developer trying to learn your way around .NET, you might find it confusing as to which "best practice" is actually a best practice, since each application is architected differently. I honestly do not think that matters, since each of the applications can stand their ground in high-capacity environments. Take the IBuySpy e-Commerce application as an example. This application is being used all over the Internet, for real live e-Commerce web sites that get thousands of hits per day. I would say that is a good example of ASP.NET!

The reason I am giving you my opinion on architecture is because Tracker is my opinion on a fairly cool, and proven, architecture. I think it is scalable, certainly reusable, and can be used by various clients, including Windows Forms, ASP.NET, .NET Remoting, Compact Framework applications, etc, without changing any of the core back end code. Writing Tracker was a fun adventure of up's and downs on dealing with some limitations of XML Web Services and how they handle serialization, but it ends up being a great example of how to take a solid layered approach to application design. My inspiration for the Tracker architecture was the .NET Petshop application, which demonstrates ASP.NET, and was written by Microsoft to showcase .NET versus Java. The .NET Petshop shows how using .NET minimizes the amount of code needed to write an enterprise application using .NET, and how the .NET Petshop out-performs the Java Petshop 3 or 4 to 1. I did not go as deep as the .NET Petshop, which uses an Interface based approach to the application. I just separated out the layers, and show you how you can communicate in a simple way between each of the layers of the application. I really hope that you learn something by studying the application, and I really hope the code in the Tracker application will help you get your own applications done faster.

Effectively use the application blocks provided by Microsoft

At the .NET Architecture Center on MSDN, located at http://msdn.microsoft.com/architecture, you can find some of the most valuable information about writing robust and scalable applications using the .NET Framework. Along with the many articles and resources, you will find a link to the Patterns and Practices site on MSDN at http://www.microsoft.com/resources/practices, which showcases the Microsoft Application Blocks. The application blocks are pre-built, pluggable components written by Microsoft that provide an immediate framework for various tasks that you may need to implement in your applications. The following application blocks are available:

  • Application Updater Application Block
  • Asynchronous Invocation Application Block
  • Caching Application Block
  • Configuration Management Application Block
  • Data Access Application Block
  • Exception Management Application Block
  • Service Aggregation Application Block
  • User Interface Process Application Block

The Tracker application uses the following application blocks:

  • Application Updater Application Block
  • Data Access Application Block
  • Exception Management Application Block

Each of the application blocks are thoroughly tested by Microsoft, and are recommended for use if your application can take advantage of the services they provide. Some are more complex than others to integrate, but overall, once you get the hang of them, you will truly be amazed at what they can offer your applications. In chapter 6 of the e-Book, Integrating the Application Blocks, I will go into more detail of why I chose the three application blocks, why I did not need the other application blocks, and how they are worked into the Tracker code. At the end of the day though, the application blocks saved me from writing of many lines of code.

Demonstrate a Clean and Effective User Interface

In order for an application to be accepted by end-users, it needs to be easy to use. Without a clean user interface, that mimics other applications they are used to, such as Microsoft Outlook, your hard work will be all for nothing. Users really do not care how cool or clean the underlying code is, they just care about getting their job done. Using the tools provided in the NetAdvantage 2004 Volume 1 toolset, you can rapidly create a very professional and easy to use user interface.

Many times, developers want to re-invent the wheel, write their own controls and tools. This is OK if you have the time to spend on such activities. Almost all of the time though, it is much easier to use someone else's tools, which are proven and tested. Using NetAdvantage, you have over 50 user interface elements to choose from for Windows Forms to improve the look and feel as well as the functionality of your application. In the Tracker application, all of the major user interface elements are created using the NetAdvantage 2004 Volume 1 toolset. This allows for a consistent look and feel across all forms, and allows a level of customization not available with the controls that ship with Visual Studio .NET.

I think you will really enjoy going through the code for the user interface of Tracker, it has some cool stuff, and I think it looks pretty good. Always remember, when designing a user interface, it needs to be user friendly, or users will fight you every inch of the way. Always work as close as you can with end-users when you are designing a user interface, your life will be a lot easier when the application gets deployed.

Show how to easily create an ink-enabled user interface for the Tablet PC

Tablet PC's are going to be the next killer app. Once I started to use a Tablet PC, I was shocked at how cool they were. Just being able to have a fully digital notebook to take notes with changed the way I work. It is now up to all of us to write applications that target the Tablet PC. The Tracker application is Tablet PC ready. Each of the Windows Forms user interface elements in the NetAdvantage 2004 Volume 1 toolset is ink-enabled. This means that you can create a user interface using the tools from Infragistics, then simply drag the Ink Provider component onto your forms, and like magic, the controls on the form are ink aware. It cannot get any easier than that.

What’s in the e-Book

The Tracker e-Book will guide you through the creation of the Tracker application, explain key points in the design, and discuss how the user interface and back end infrastructure were created. The e-Book is broken down into 10 chapters:

  • Chapter 1: Overview of the Tracker Application
  • Chapter 2: Understanding the Architecture Design and Goals
  • Chapter 3: Implementing the Tracker Database
  • Chapter 4: Implementing the Tracker Data Access Layer
  • Chapter 5: Implementing the Tracker Business Logic Layer
  • Chapter 6: Integrating the Microsoft Application Blocks in Tracker
  • Chapter 7: Designing the Tracker User Interface
  • Chapter 8: Implementing the Tracker User Interface
  • Chapter 9: Enhancing the Tracker User Interface
  • Chapter 10: Where to go from here

By reading each chapter, you will understand why the end product looks and acts like it does, how .NET fits in, and how the Infragistics toolset is used. You will also get an understanding of how to modify and extend the application to fit your needs. During the process of each chapter, screen shots of the actual application will be used, so you can easily reference back to what each topic is covering.

Summary

This article gave you a high-level overview of the Tracker reference application, and some of the key concepts used in Tracker. The next step is to download the code and go through the e-Book, which contains all of the details on understanding the Tracker application. To get started, you will need to this URL to get all of the setup instructions and file for putting Tracker on your own machine:

http://devcenter.infragistics.com/RefApps/Tracker/tracker.aspx

Make sure you check out all of the ReadMe information to understand what needs to be installed to make Tracker work on your own machine.

There is also a newsgroup set up to discuss Tracker and get help if you need it. The URL for that NNTP server is:

news://news.infragistics.com/infragistics.dotnet.referenceapplications

About the Author:

Jason Beres is the .NET Technical Evangelist for Infragistics, Inc, a Microsoft Visual Studio Integration Partner. Jason is a Microsoft .NET MVP, is on the INETA Speakers Bureau (http://www.ineta.org) and is the co-Chair of the INETA Academic Committee. Jason is the author of Teach Yourself Visual Studio .NET 2003 in 21 Days from Sams, the co-author of the Visual Basic .NET Bible from Wiley, the C# Bible from Wiley, and is currently finishing up Teach Yourself Visual C# .NET in 21 Days from Sams.



Page view counter