Newest Posts

FaultException`1 was unhandled when trying to deserialize parameter http://tempuri.org/:request

Microsoft .NET

I just finished my activation system which is just a WCF service, finished all the unit tests and ensured they passed and met requirements. Now its time to make a test client, so I load up Visual Studio and start a simple Console Application with the service reference to IIS Express, and boom! Failure. The WCF code that consumes the service is rather simple.

static void Main(string[] args) {
    ActivationServiceClient client = new ActivationServiceClient();

    ActivationRequest request = new ActivationRequest();
    request.DateCreated = DateTime.Now;
    request.MachineName = Environment.MachineName;
    request.ProductCode = Guid.NewGuid();
    request.ProductKey = "ABCDEFGHIJKLMNPQRSTUVWXYZ";

    ActivationResponse response = client.Activate(request);

    byte[] license = response.License;
    string licenseHash = response.LicenseHash;
    ActivationResult result = response.Result;
}

I highlighted line 10, because that’s where the failure is. Here’s the full exception.

FaultException`1 was unhandled
There was an error while trying to deserialize parameter http://tempuri.org/:request. Please see InnerException for more details.

I do the obvious and check the inner exception, but there is none. However I noticed there was a Details property with some extra data that read the following.

{An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.Runtime.Serialization.InvalidDataContractException: There was an error while trying to deserialize parameter http://tempuri.org/:request. Please see InnerException for more details. —-> System.Runtime.Serialization.InvalidDataContractException: No set method for property ‘ProductKey’ in type ‘DCOMProductions.Activation.ActivationRequest’. The class cannot be deserialized.

In short, it says that there is no set method for property `ProductKey`. This is true because the ActivationRequest structure is immutable by design. I designed the class so that the properties are initialized through constructor parameters, and the class itself is immutable. However, you will notice that on the client that consumes the service, the service reference created a type that is not immutable and has no constructor parameters. In addition, the type created by the service reference is mutable.

After thinking about the problem and doing some research I found that WCF requires two-way serialization by default. This means that by applying [DataMember] attribute on a property, it would need to have both the get and set accessors. While its not recommended to mark member fields as a DataMember, in this scenario it is the solution. Let’s take a look at some code.

private string name;
[DataMember]
public string Name {
    get {
        return name;
    }
}
[DataMember]
private string name;

public string Name {
    get {
        return name;
    }
}

The first code example would cause the WCF service to fail because it does not allow for two-way serialization, however the second would be fine since we are decorating the backing field as the DataMember instead of the read-only property. There’s really not much else to say here, but there are tradeoffs for one good practice over another. In this case we are trading the good practice of decorating properties as DataMembers for the good practice of immutable structures.

Cannot obtain Metadata from WCF service when using Microsoft WCF Test Client.

Microsoft .NET

I just finished writing the technical whitepapers for my product activation service, so I started the actual implementation using WCF services. All was good, added the usual WCF Service Application project, ran a quick F5, and swapped out all the default services with my own. Then I ran a F5 debug, and wait what? The WCF Test Client could not run my service.

Microsoft WCF Test Client

Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.

I vigorously checked the configuration, because I often write my by hand instead of using the WCF tool, and everything checked out. Here is what my configuration looked like, which is a valid configuration.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.web>
        <compilation debug="true" />
    </system.web>
    <system.serviceModel>
        <services>
            <service name="DCOMProductions.Activation.ActivationService">
                <endpoint binding="wsHttpBinding" contract="DCOMProductions.Activation.IActivationService">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/DCOMProductions.Activation/ActivationService/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior>
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

What the heck? Because everything I could think of is valid, I then pointed my finger at something being wrong with my code. Something has to be causing the test client to fail. I tested this theory by navigating to the service address in Internet Explorer, which revealed that it was encountering a server error, which proved my theory.

Taking a look at my code, I quickly realized that I had some Composite Types in my service. One of the composite types is an Enum.

//-----------------------------------------------------------------------------
// <copyright file="ActivationResult.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace DCOMProductions.Activation
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.Serialization;

    /// <summary>
    /// The result of the activation request
    /// </summary>
    [DataContract]
    public enum ActivationResult
    {
        [DataMember]
        None,
        [DataMember]
        Passed
    }
}

If you notice, I have highlighted lines 21 and 23. The problem is that enumeration fields should use the EnumMemberAttribute, and not DataMemberAttribute. I changed the attributes, ran a F5 debug and low-and-behold, the service worked great.

If you find yourself pulling your hair out over WCF configuration problems, check your code too. It may just be something simple.

Math in C# using the Quadratic Formula

Microsoft .NET
namespace QuadraticFunc 
{
    using System;
    using System.Diagnostics;

    class Program 
    {
        static void Main(string[] args) 
        {
            Action<object> Print = (obj) => { Debug.WriteLine(obj.ToString()); };

            // Returns Quadratic (+,-)
            Func<double, double, double, Tuple<double, double>> Quadratic = (a, b, c) => {
                double x1 = (-b + Math.Sqrt((b * b) - ((4 * a) * c))) / (2 * a);
                double x2 = (-b - Math.Sqrt((b * b) - ((4 * a) * c))) / (2 * a);
                return new Tuple<double, double>(x1, x2);
            };

            Print(Quadratic(1, 3, -4));     // (1, -4)
            Print(Quadratic(2, -4, -3));    // (2.58113883008419, -0.58113883008419)
            Print(Quadratic(0, 0, 0));      // (NaN, NaN)

            Tuple<double, double> result = Quadratic(1, 3, -4);
            Print(result.Item1);
            Print(result.Item2);
        }
    }
}

Simple enough. If you want to ensure exact order translate the local variable function Func(Of double,double,double,Tuple(Of double,double)) to an actual member function or static function.

Async, Await, Tasks, and UI synchronization with C# 5, .NET 4.5 and WinForms

Microsoft .NET

I’m going to cover a easy example on the new asynchronous programming model in C# 5 and .NET 4.5 with the recent release of Visual Studio 11. The example we will be writing is a small WinForm that will calculate the square root of a large number while providing progress updates to the UI, and moreso, doing all of this asynchronously, and safely.

The first note is that all this can be done right inside our form class (eg. Form1.cs), so I won’t include a ZIP file or source download, the example should be very straight forward and simple. Let’s dig right in.

To start with, we’re going to create a SynchronizationContext. This part is not anything new, and has been around since .NET 2.0 so I won’t be covering it. In short, it’s just a very helpful object that allows you to perform synchronization between threads or other asynchronous environments. Add a field, and initialize it in the constructor.

public partial class Form1 : Form 
{
    public Form1() 
    {
        InitializeComponent();
        m_SynchronizationContext = SynchronizationContext.Current;
    }

    private SynchronizationContext m_SynchronizationContext;
}

We will be using this to invoke calls to the UI thread safely later on. Next, let’s declare our async method.

private async void ComputeSquareRootAsync(object sender, EventArgs e) 
{
    double sqrt = await Task<double>.Run(() => 
    {
        double result = 0;

        for (int i = 0; i < 5000000; i++)
        {
            result += Math.Sqrt(i);
        }

        return result;
   });
}

There are a few things to note here. One, notice the declaration private async void. Here we are telling the compiler that this method will be intrinsically asynchronous, and because the method will contain awaiters, the C# compiler will know to rewrite our method appropriately under the hood.

If you don’t know already, async and await simply work off of the existing Task objects in the framework. By telling the program to await Task.Run, we are saying “Run all code up until this point synchronously, then run the task on a background method, but don’t block the UI, and return control to the caller when the result is returned”. This means that while our Task is running and doing some work off on a background thread, our program will not continue the normal flow of execution until the result is returned, but at the same time will not block the calling context.

Now drag a button onto your form (eg. button1) and set it’s click event to our ComputeSquareRootAsync method. Now drag a label (eg. label1) and a progressbar (eg. progressBar1). Let’s update our method a bit.

private async void ComputeSquareRootAsync(object sender, EventArgs e) 
{
    label1.Text = "Calculating sqrt of 5000000";
    button1.Enabled = false;
    progressBar1.Visible = true;

    double sqrt = await Task<double>.Run(() => 
    {
        double result = 0;

        for (int i = 0; i < 5000000; i++)
        {
            result += Math.Sqrt(i);
        }

        return result;
   });

   label1.Text = "The sqrt of 5000000 is " + sqrt;
   button1.Enabled = true;
   progressBar1.Visible = false;
}

Set the label’s initial text in the designer to “Click the button to begin”, and the progress bar’s visiblility to false initially. I also set the button’s text to “Calculate”. This is just cosmetic, but we are making a small, but not really practical, good demo app.

Now what will happen is that the square root will be executed asynchronously while not blocking the UI, but at the same time the last three lines of code that update the controls will not execute until the result is returned (eg. the Task is returned). This is the magic of the new async model.

Let’s implement our progress updates now. To do this, we’re going to implement a new interface onto our form that is provided by .NET 4.5 explicitly for this scenario, and it is called IProgress(Of T).

To make things simple, we will use IProgress(Of Tuple(Of int, int)) (eg. IProgress>) so we can pass in the maximum value and current value of our progress operation (eg. computing the square root).

public partial class Form1 : Form, IProgress<Tuple<int,int>>

Now implement the interface’s Report method.

public void Report(Tuple<int, int> value) 
{
    DateTime now = DateTime.Now;

    if ((now - m_PreviousTime).Milliseconds > 20) 
    {
        m_SynchronizationContext.Post((@object) => 
        {
            Tuple<int, int> minMax = (Tuple<int, int>)@object;
            progressBar1.Maximum = minMax.Item1;
            progressBar1.Value = minMax.Item2;
        }, value);

        m_PreviousTime = now;
    }
}

Now you will notice one thing off the bat, I included a reference to a DateTime value named m_PreviousTime. Add this as a field in the Form1 class and set its value to DateTime.Now.

private DateTime m_PreviousTime = DateTime.Now;

You could also do that in the constructor where we initialized our synchronization context. The method is simple. We are creating an anonymous function that passes in an object instance of our Tuple as a parameter, which we explicitly convert through an explicit cast. Through the usage of the Post method, it is actually calling this anonymous function on the synchronization context, which is actually our UI thread, thus giving us a safe UI update and no cross-thread violations. This is similar do doing a Control.Invoke, and I suspect somewhere under the hood it may actually do that but I haven’t looked at the implementation yet.

And now we’re done. Here’s the full Form1 class code so you can make sure you implemented all the steps.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Async {
    public partial class Form1 : Form, IProgress<Tuple<int,int>> {
        public Form1() {
            InitializeComponent();
            m_SynchronizationContext = SynchronizationContext.Current;
        }

        private SynchronizationContext m_SynchronizationContext;
        private DateTime m_PreviousTime = DateTime.Now;

        private async void ComputeSquareRootAsync(object sender, EventArgs e) {
            label1.Text = "Calculating Sqrt of 5000000";
            button1.Enabled = false;
            progressBar1.Visible = true;

            double sqrt = await Task<double>.Run(() => {
                double result = 0;

                for (int i = 0; i < 5000000; i++) {
                    result += Math.Sqrt(i);
                    Report(new Tuple<int,int>(5000000, i));
                }

                return result;
            });

            progressBar1.Visible = false;
            button1.Enabled = true;
            label1.Text = "The sqrt of 5000000 is " + sqrt;
        }

        public void Report(Tuple<int, int> value) {
            DateTime now = DateTime.Now;

            if ((now - m_PreviousTime).Milliseconds > 20) {
                m_SynchronizationContext.Post((@object) => {
                    Tuple<int, int> minMax = (Tuple<int, int>)@object;
                    progressBar1.Maximum = minMax.Item1;
                    progressBar1.Value = minMax.Item2;
                }, value);

                m_PreviousTime = now;
            }
        }
    }
}

I may come back and add the source when I have more time.

How to fix Visual Studio Import and Export Settings Dialog when it disappears or crashes when trying to import or export settings.

Microsoft .NET

I am definitely posting about this, because it annoyed the living crud out of me. If you are like me, you often have heavily modified your Visual Studio settings to your likings. This includes environment settings, user settings, and the works.

The Problem
When you go to ‘Tools > Options > Import and Export Settings…’ and you select either Export or Import and click next, the Import and Export Settings Dialog crashes (disappears)!

Cause
This is caused because at some point you imported settings from a non-standard location (eg. MyDocuments\Visual Studio 2010\Settings). What happens is Visual Studio makes some key registry changes that tell devenv.exe how to handle settings going forward. Because of this, it messes with how default settings are handled. The solution is to undo all this to factory settings, which is easily enough done with some registry hacks.

How to resolve this problem

Disclaimer: If you are not comfortable making changes to the Registry, you should try to repair Visual Studio using the Visual Studio Setup. I take no responsibility for problems caused by you editing your Registry, and this is not guarunteed to work for all cases.

Step 1.
1. Navigate to HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\10.0\Profile
2. Change the value of AutoSaveFile (REG_SZ) to %vsspv_visualstudio_dir%\Settings\CurrentSettings.vssettings

Step 2.
1. Navigate to HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\10.0\Profile\BrowseFiles.
2. Delete all registry values under the above registry key.
3. Create a new REG_DWORD value and set its name to %vsspv_visualstudio_dir%\Settings\CurrentSettings.vssettings.
4. Set the value of the REG_DWORD value you just created to 0x00000001 (1).

Step 3.
1. Navigate to HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\10.0\ImportExportSettings\BrowsePaths.
2. Delete all registry values under the above registry key.
3. Create a new REG_DWORD value and set its name to C:\Users\{USER}\Documents\Visual Studio 2010\Settings where {USER} is your Windows User Account name.
4. Set the value of the REG_DWORD value you just created to 0x00000001 (Hex), or 1 (Decimal).

Step 4.
1. Navigate back to HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\10.0\Profile
2. Make sure that registry value named DefaultSettingsDirectory has a value of %vsspv_visualstudio_dir%\Settings\

Step 5.
1. Run cmd.exe (does not have to be as administrator
2. Navigate to devenv.exe (eg. cd c:\program files (x86)\microsoft visual studio 10.0\common7\ide)
3. Run the command devenv.exe /ResetSettings

You should now be able to utilize the Import and Export Settings dialog.

Subscribing to DWebBrowserEvents2::FileDownload from WinForms WebBrowser control through the Dynamic Language Runtime (DLR).

Microsoft .NET

I will come back and add more detail to this blog at a later date, but I was helping on MSDN forums and wrote this neat example for someone. It uses the dynamic language runtime and C# 4.0 to take advantage of some of the events exposed by COM through the ActiveXInstance of the WebBrowser control. It intercepts the file download dialog when it detects you downloading an exe file and cancels the download.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;

namespace WindowsFormsApplication12 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
            webBrowser1.Url = new Uri("http://www.dcomproductions.com/products/faulttrack");
        }

        /// <summary>
        /// Fires before navigation occurs in the given object (on either a window or frameset element).
        /// </summary>
        /// <param name="pDisp">Object that evaluates to the top level or frame WebBrowser object corresponding to the navigation.</param>
        /// <param name="url">String expression that evaluates to the URL to which the browser is navigating.</param>
        /// <param name="Flags">Reserved. Set to zero.</param>
        /// <param name="TargetFrameName">String expression that evaluates to the name of the frame in which the resource will be displayed, or Null if no named frame is targeted for the resource.</param>
        /// <param name="PostData">Data to send to the server if the HTTP POST transaction is being used.</param>
        /// <param name="Headers">Value that specifies the additional HTTP headers to send to the server (HTTP URLs only). The headers can specify such things as the action required of the server, the type of data being passed to the server, or a status code.</param>
        /// <param name="Cancel">Boolean value that the container can set to True to cancel the navigation operation, or to False to allow it to proceed.</param>
        private delegate void BeforeNavigate2(object pDisp, ref dynamic url, ref dynamic Flags, ref dynamic TargetFrameName, ref dynamic PostData, ref dynamic Headers, ref bool Cancel);

        /// <summary>
        /// Fires to indicate that a file download is about to occur. If a file download dialog box can be displayed, this event fires prior to the appearance of the dialog box.
        /// </summary>
        /// <param name="bActiveDocument">A Boolean that specifies whether the file is an Active Document.</param>
        /// <param name="bCancel">A Boolean that specifies whether to continue the download process and display the download dialog box.</param>
        private delegate void FileDownload(bool bActiveDocument, ref bool bCancel);

        protected override void OnLoad(EventArgs e) {
            dynamic d = webBrowser1.ActiveXInstance;
            string uri = string.Empty;

            d.BeforeNavigate2 += new BeforeNavigate2((object pDisp,
                ref dynamic url,
                ref dynamic Flags,
                ref dynamic TargetFrameName,
                ref dynamic PostData,
                ref dynamic Headers,
                ref bool Cancel) => {

                uri = url.ToString();
                Trace.WriteLine(uri);
            });

            d.FileDownload += new FileDownload((bool bActiveDocument, ref bool bCancel) => {
                bool isFile = uri.EndsWith("exe");

                if (isFile) {
                    bCancel = true;
                    Trace.Write("Canceled a file download from the DLR.");
                }
            });
        }
    }
}

Embedding referenced assemblies as an Embedded Resource, and resolving dependencies at runtime.

Microsoft .NET

This was inspired by this question on StackOverflow. First off, this is bad design unless you are designing some sort of setup application. But, specifically for those who still wish to proceed, here is how you do it.

Download Example Code
EmbeddedReferenceApplication.zip

In this example, there are two projects. ‘EmbeddedReferenceApplication.exe’ and ‘EmbeddedReference.dll’. Here are the steps.

  1. Add a hard reference to EmbeddedReference.dll from EmbeddedReferenceApplication.exe
  2. Go to the reference Properties, and set Copy Local = False
  3. Right click your project and add the referenced assembly as a link (Add As Link)
  4. Right click the linked assembly in your project, and set its build output to ‘Embedded Resource’
  5. Modify your code with proper manifest name handling/resolution
  6. See the example code or post comments for more help
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Reflection;
using EmbeddedReference;

namespace EmbeddedReferenceApplication {
    class Program {
        static void Main(string[] args) {
            AppDomain.CurrentDomain.AssemblyResolve += AppDomain_AssemblyResolve;
            MyMain();
        }

        private static void MyMain() {
            EmbeddedReference.MessageHelper.ShowMessage();
        }

        private static Assembly AppDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
            string manifestResourceName = "EmbeddedReferenceApplication.EmbeddedReference.dll"; // You can also do Assembly.GetExecutingAssembly().GetManifestResourceNames();
            string path = Path.Combine(Application.StartupPath, manifestResourceName.Replace("EmbeddedReferenceApplication.", ""));
            ExtractEmbeddedAssembly(manifestResourceName, path);
            Assembly resolvedAssembly = Assembly.LoadFile(path);
            return resolvedAssembly;
        }

        private static void ExtractEmbeddedAssembly(string manifestResourceName, string path) {
            Assembly assembly = Assembly.GetExecutingAssembly();
            using (Stream stream = assembly.GetManifestResourceStream(manifestResourceName)) {
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);
                using (FileStream fstream = new FileStream(path, FileMode.Create)) {
                    fstream.Write(buffer, 0, buffer.Length);
                }
            }
        }
    }
}

What this does is subscribes to AssemblyResolve and allows the application domain to resolve your assembly to a custom path – in our case, we resolve to the application directory but we are extracting the assembly first, and returning the resolved assembly. You can use this same code to resolve dependencies and assemblies from custom directories and paths.

A key note is lines 12 and 13. You must not use any code directly in the Main method that would otherwise reference a dependency. What this causes is for your exception to be thrown while Main is compiled, and before it is run. You will never give the application domain a chance to perform dependency resolution. However, a quick fix is to throw it into a helper method called MyMain (call it SubMain or something similar), that would not otherwise reference the dependency until its invoked.

Adding extension method support for .NET 2.0

Microsoft .NET

.NET Framework 2.0 does not support extension methods out of the box, because you cannot reference System.Core that was introduced in .NET 3.5. However, by adding a simple attribute class you can use extension methods in .NET 2.0 as well. Here is the snippet.

namespace System.Runtime.CompilerServices {
    /// <summary>
    /// Mimics the .NET 3.5 extension methods attribute
    /// </summary>
    [AttributeUsage(AttributeTargets.Method)]
    internal sealed class ExtensionAttribute : System.Attribute {
        /// <summary>
        /// Instantiates a new instance of the ExtensionAttribute class
        /// </summary>
        public ExtensionAttribute()
            : base() {
        }
    }
}

Here is an example afterwards using extension methods in one of our applications.

namespace Setup.AppCode {
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.Text;
    using System.Runtime.CompilerServices;

    /// <summary>
    /// Extension methods class
    /// </summary>
    public static class ExtensionMethods {

        public static void DisableAllLinks(this LinkLabel control) {
            foreach (LinkLabel.Link link in control.Links) {
                link.Enabled = false;
            }
        }

        public static void EnableAllLinks(this LinkLabel control) {
            foreach (LinkLabel.Link link in control.Links) {
                link.Enabled = true;
            }
        }

    }
}

And don’t forget to import the namespace that contains your extension methods where you will need them so they appear correctly.

N-Tier Architecture Best Practices, Part 2: 3-Tier Architecture with interfaces and a Data Tier

Microsoft .NET

N-Tier Architecture Best Practices, Part 1: 2-Tier Architecture with just a Data Tier
N-Tier Architecture Best Practices, Part 2: 3-Tier Architecture with interfaces and a Data Tierthis article
N-Tier Architecture Best Practices, Part 3: DLinq / Linq to SQL
N-Tier Architecture Best Practices, Part 4: Entity Framework
N-Tier Architecture Best Practices, Part 5: Unity Framework

Download the Source Code for this Article
N-Tier Architecture (3-Tier)

In the previous article I covered 2-Tier Architecture with just a presentation layer and a data tier. In this article, I will show you how to expand this into a 3-tier architecture that will allow you to utilize your data tier with flexibility. You will need to download the source code from the previous article for this example, because I will be expanding upon it. You should already be very familiar with the code before proceeding.

Now let’s say you wanted to add a library to the project to handle all the rules of the business. This might be something like making sure that all employees in the company have valid pay rates and salaries. So we add a new Class Library project and call it NTier.BusinessRules along with a class called EmploymentValidation.

//-----------------------------------------------------------------------------
// <copyright file="EmploymentValidation.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace NTier.BusinessRules {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// Validates employees to ensure their profiles meet business rules and standards
    /// </summary>
    public static class EmploymentValidation {
        /// <summary>
        /// Validates the specified pay rate
        /// </summary>
        public static bool ValidatePayrate(float rate) {
            if (rate < 0f) {
                return false;
            }
            return true;
        }
    }
}

Now this is great, because in NTier.Data.DataTier we can validate the employee’s payrate in AddEmployee and UpdateEmployee. So let’s add a reference to NTier.BusinessRules from NTier.Data and add our validation. Note that I will use an elipse ( … ) to represent sections of code we are not changing to help condense this post.

Changes to NTier.Data.DataTier.cs

namespace NTier.Data {
    using System;
    using System.Collections.Generic;
    using System.Data.SqlServerCe;
    using NTier.Data.Objects;
    using NTier.BusinessRules;
    ...
}
public static bool AddEmployee(NTier.Data.Objects.Employee employee) {
    if (!EmploymentValidation.ValidatePayrate(employee.Payrate)) {
        return false;
    }
    ...
}
public static bool UpdateEmployee(NTier.Data.Objects.Employee employee) {
    if (!EmploymentValidation.ValidatePayrate(employee.Payrate)) {
        return false;
    }
    ...
}

Okay, great; if we try to add or update an employee that has a payrate below 0, it will fail and that is what we want. Now this seems great, we just added validation to our project with ease. Now, what if your employee object actually has 50+ properties that need to be validated? Often times you want to keep your object itself simple. This will help you maintain it in the future, so the first thought is to pass the object itself to our validation library. Wait, we can’t!

NTier.Data references NTier.BusinessRules, therefore NTier.BusinessRules can never reference NTier.Data as this would cause a circular dependency. This is where 3-tier architecture using interfaces comes into play. We don’t need to pass the object itself, we can pass a contract that defines that object and stores the valuable information we need to validate. We don’t need anything else, but we need to add another new project called NTier.Common.Interfaces and our IEmployee interface to represent our object.

//-----------------------------------------------------------------------------
// <copyright file="IEmployee.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace NTier.Common.Interfaces {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// Defines the base properties for an Employee
    /// </summary>
    public interface IEmployee {
        int ID { get; }
        string Email { get; set; }
        string FirstName { get; set; }
        string LastName { get; set; }
        float Payrate { get; set; }
        string Title { get; set; }
    }
}

Now first what we want to do is add a reference to NTier.Common.Interfaces from NTier.Data and derive Employee from IEmployee. Also don’t forget that because NTier.Presentation uses NTier.Data, it must also use NTier.Common.Interfaces, so we add that as a reference as well. Add your references, and make the following change to Employee.cs.

public class Employee : NTier.Common.Interfaces.IEmployee {
    ...
}

Now to resolve the circular dependency we are going to reference NTier.Common.Interfaces from NTier.BusinessRules. Add your reference, then make the following changes to EmploymentValidation.

namespace NTier.BusinessRules {
    ...
    using NTier.Common.Interfaces;

    ...
    public static class EmploymentValidation {
        ...

        /// <summary>
        /// Validates the specified employee
        /// </summary>
        public static bool ValidateEmployee(IEmployee employee) {
            if (string.IsNullOrEmpty(employee.FirstName))
                return false;
            if (string.IsNullOrEmpty(employee.LastName))
                return false;
            if (string.IsNullOrEmpty(employee.Title))
                return false;
            if (string.IsNullOrEmpty(employee.Email))
                return false;
            if (!ValidatePayrate(employee.Payrate))
                return false;
            return true;
        }
    }
}

Now notice that I left in the ValidatePayrate() method. This is because often times you are already using this in various portions of your software, and removing or changing this would be a breaking change that could break the software. So we’ll leave that in. But now you can see that we can pass in an interface of IEmployee and validate everything we need. But first, we need to go back and update our AddEmployee() and UpdateEmployee() methods in our data tier.

public static bool AddEmployee(NTier.Data.Objects.Employee employee) {
    if (!EmploymentValidation.ValidateEmployee(employee)) {
        return false;
    }
    ...
}
public static bool UpdateEmployee(NTier.Data.Objects.Employee employee) {
    if (!EmploymentValidation.ValidateEmployee(employee)) {
        return false;
    }
    ...
}

And, we’re done. We can pass around our IEmployee interface because it is shared among all the core libraries, where before we could not have passed around Employee due to circular dependencies. This is what 3-tier architecture with interfaces provides, flexibility and loose coupling between your libraries. Technically it is still pretty tightly coupled, but much more better than a 2-tier architecture.

N-Tier Architecture Best Practices, Part 1: 2-Tier Architecture with just a Data

Microsoft .NET

Before I start off on my lengthy post, this article is what sparked my interest. With that linked for you, this will be split into a 5 part blog series each part covering a specific type of n-tier architecture. If there is not a link to the article it has not been published yet.

N-Tier Architecture Best Practices, Part 1: 2-Tier Architecture with just a Data Tierthis article
N-Tier Architecture Best Practices, Part 2: 3-Tier Architecture with interfaces and a Data Tier
N-Tier Architecture Best Practices, Part 3: DLinq / Linq to SQL
N-Tier Architecture Best Practices, Part 4: Entity Framework
N-Tier Architecture Best Practices, Part 5: Unity Framework

Download the Source Code for this Article
N-Tier Architecture (2-Tier)

In most projects you will have to communicate with other objects or a data tier (database engine, file system, or other data source), and passing your objects around can make for some complicated scenarios. One common rut that many developers find themselves in is circular-dependencies.

What is N-Tier Architecture?
N-Tier Archiecture is a term that refers to the number of assemblies, modules, or services that make up a system that allows its different parts to communicate with one another. An example would be a simple system that has some business objects and a database. You may have a module that handles the communication with the data tier, and also stores your business objects, and then maybe a second module that actually handles the processing of the objects such as input and change. This would be a 2-Tier architecture. A 3-Tier architecture would be something like having a module that stores interfaces that defines your business objects, another module that actually implements the business objects, and then a third module that again handles the input and change. N-Tier architecture can get vastly complex, especially in software applications like video games. Imagine a game engine where you have modules that must communicate with one another for handling rendering, player locations, particle effects, game data, network information. You can easily get into a complex system.

What I will cover

  • 2-Tier with just a data tier
  • 3-Tier with common interfaces, and a data tier
  • Briefly explain DLinq (Linq to Sql)
  • Briefly explain Entity Framework (Linq to Entities)
  • Briefly explain Unity Framework (Data Injection Framework)

Technologies we will be using for this article

  • C# 4.0
  • .NET 3.5
  • SQL Server CE

2-Tier architecture with a Data Tier Project Structure (image to the left)
We are going to create a solution with two projects. The first, ‘NTier.Data’ will act as the Data Tier. Thie purpose of this is to act as the dependency for all other aspects of the software. It will store the database objects, as well as the class that handles communication between the objects and the database. The second will be ‘NTier.Presentation’, which acts as the executable that is actually used by the client as the UI, and in our case is a very simple Console Application.

The database
The database is just a SqlCe database with an Employees table. Our employee object will match the database schema perfectly in terms of its properties (ie. FirstName, LastName, Email, etc).

The code
There are only three class files, here is the code of all three.

//-----------------------------------------------------------------------------
// <copyright file="Employee.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace NTier.Data.Objects {
    using System;

    /// <summary>
    /// Represents a Employee in the data tier
    /// </summary>
    public class Employee {
        /// <summary>
        /// Gets the Employee's ID
        /// </summary>
        public int ID {
            get;
            internal set;
        }

        /// <summary>
        /// Gets or sets the Employee's email address
        /// </summary>
        public string Email {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the Employee's first name
        /// </summary>
        public string FirstName {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the Employee's last name
        /// </summary>
        public string LastName {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the Employee's payrate
        /// </summary>
        public float Payrate {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the Employee's title
        /// </summary>
        public string Title {
            get;
            set;
        }

        /// <summary>
        /// Overrides base.ToString()
        /// </summary>
        public override string ToString() {
            return string.Format("{0} {1}, {2}", FirstName, LastName, Title);
        }
    }
}
//-----------------------------------------------------------------------------
// <copyright file="DataTier.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace NTier.Data {
    using System;
    using System.Collections.Generic;
    using System.Data.SqlServerCe;
    using NTier.Data.Objects;

    /// <summary>
    /// Interactive class between business logic and the data tier
    /// </summary>
    public static class DataTier {

        private static string m_ConnectionString = @"Data Source=.\Northwind.sdf";
        /// <summary>
        /// Gets the connection string for SQL Server CE
        /// </summary>
        public static string ConnectionString {
            get {
                return m_ConnectionString;
            }
        }

        /// <summary>
        /// Adds the specified employee to the data tier
        /// </summary>
        public static bool AddEmployee(NTier.Data.Objects.Employee employee) {
            using (SqlCeConnection connection = new SqlCeConnection(ConnectionString))
            using (SqlCeCommand command = new SqlCeCommand(Properties.Resources.InsertCommandText, connection)) {
                command.Parameters.AddWithValue("@Email", employee.Email);
                command.Parameters.AddWithValue("@FirstName", employee.FirstName);
                command.Parameters.AddWithValue("@LastName", employee.LastName);
                command.Parameters.AddWithValue("@Payrate", employee.Payrate);
                command.Parameters.AddWithValue("@Title", employee.Title);
                try {
                    connection.Open();
                    return command.ExecuteNonQuery() == 1;
                }
                catch (System.Data.SqlServerCe.SqlCeException) {
                    return false;
                }
            }
        }

        /// <summary>
        /// Returns a collection of all the employee's in the data tier
        /// </summary>
        public static IEnumerable<NTier.Data.Objects.Employee> GetEmployees() {
            using (SqlCeConnection connection = new SqlCeConnection(ConnectionString))
            using (SqlCeCommand command = new SqlCeCommand(Properties.Resources.SelectCommandText, connection)) {
                try {
                    connection.Open();
                }
                catch (System.Data.SqlServerCe.SqlCeException) {
                    yield break;
                }
                using (SqlCeDataReader reader = command.ExecuteReader()) {
                    while (reader.Read()) {
                        Employee employee = new Employee();
                        employee.ID = (int)reader["ID"];
                        employee.Email = (string)reader["Email"];
                        employee.FirstName = (string)reader["FirstName"];
                        employee.LastName = (string)reader["LastName"];
                        employee.Payrate = (float)(double)reader["Payrate"];
                        employee.Title = (string)reader["Title"];
                        yield return employee;
                    }
                }
            }
        }

        /// <summary>
        /// Removes the specified employee from the data tier
        /// </summary>
        public static bool RemoveEmployee(NTier.Data.Objects.Employee employee) {
            using (SqlCeConnection connection = new SqlCeConnection(ConnectionString))
            using (SqlCeCommand command = new SqlCeCommand(Properties.Resources.DeleteCommandText, connection)) {
                command.Parameters.AddWithValue("@ID", employee.ID);
                try {
                    connection.Open();
                    return command.ExecuteNonQuery() == 1;
                }
                catch (System.Data.SqlServerCe.SqlCeException) {
                    return false;
                }
            }
        }

        /// <summary>
        /// Updates the specified employee's information in the data tier
        /// </summary>
        public static bool UpdateEmployee(NTier.Data.Objects.Employee employee) {
            using (SqlCeConnection connection = new SqlCeConnection(ConnectionString))
            using (SqlCeCommand command = new SqlCeCommand(Properties.Resources.UpdateCommandText, connection)) {
                command.Parameters.AddWithValue("@Email", employee.Email);
                command.Parameters.AddWithValue("@FirstName", employee.FirstName);
                command.Parameters.AddWithValue("@LastName", employee.LastName);
                command.Parameters.AddWithValue("@Payrate", employee.Payrate);
                command.Parameters.AddWithValue("@Title", employee.Title);
                command.Parameters.AddWithValue("@ID", employee.ID);
                try {
                    connection.Open();
                    return command.ExecuteNonQuery() == 1;
                }
                catch (System.Data.SqlServerCe.SqlCeException) {
                    return false;
                }
            }
        }
    }
}
//-----------------------------------------------------------------------------
// <copyright file="Program.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace NTier.Presentation {
    using System;
    using NTier.Data.Objects;
    using NTier.Data;
    using System.Collections.Generic;

    internal static class Program {
        /// <summary>
        /// Entry Point
        /// </summary>
        public static void Main() {
            Employee employee = new Employee();
            employee.Email = "danderson@dcomproductions.com";
            employee.FirstName = "David";
            employee.LastName = "Anderson";
            employee.Payrate = 35F;
            employee.Title = "President";
            DataTier.AddEmployee(employee);
            foreach (Employee item in DataTier.GetEmployees()) {
                Console.WriteLine(item.ToString());
                Console.ReadKey(true);
            }
            Console.Write("Press any key to exit...");
            Console.ReadKey(true);
        }
    }
}

Something to note is lines 33, 54, 81, 98 of Employee.cs. I saved the query texts in the project’s resource file to keep the code tidy.

Now you can write Program.cs to act however you want, and play with the code. In my example all I am doing is adding an employee to the table with my name, then enumerating the employees and listing them to the console window. Since each time you run my example it adds an employee with the same information and never removes it, you will have x(f) employees where f is the number of times the application has been launched, in the database with the same information.

What advantage does 2-Tier architecture serve?
Alright, in this 2-tier architecture, the advantage is its simple. That’s all there is to it. For each data tier object (ie. something that would need to be committed into a data source), you can simply create the object with its properties, and write the methods in your data tier class to do the work. The simplicity of being able to just pass your object is what makes it desireable. Also note that you do not have any complex dependencies between assemblies, thus you never have to worry about a circular dependency, and its extremely easy to note where everything is at in your project.

In large projects, your Objects folder would get rather large with data tier objects. Which is fine. The disadvantage of a 2-tier architecture is generally as your application becomes exceedingly complex, the simple structure of the project no longer becomes viable because its just not that flexible. Further down the road if you wanted to refactor your objects out of the data tier assembly into a 3-tier architecture, your data tier breaks because you can no longer pass the reference of the object. Thus bringing us into the next part of the blog series, 3-tier architecture.

When to use 2-Tier Architecture
When your requirements are simple and you have a minimal number of assemblies that must reference your business objects. More so, it is actually easier to explain when not to use 2-tier architecture. I’ve compiled a short list of the most common scenarios you should not use 2-tier architecture for.

  • An assembly needs to reference your business objects, but not have access to the data tier
  • You want to extend your business object with additional functionality, but not expose those new features to the data tier

Those are actually the only two reasons that come to mind immediately. If you have some other reasons you can think of that are good, throw a comment down and I will add it to the list. At any rate, the point is that 2-tier is easy to implement, and pretty easy to manage with little effort. The huge downside is once it becomes large, it will be hard to refactor later on. The next blog in the series will be on 3-tier architecture which I will hope to start writing by Monday.