Programming, Policitcs, and uhhh Pineapples.
# Friday, February 19, 2010

FluentNHibernate And NHibernate.Linq

Friday, February 19, 2010 7:44:43 PM UTC

Just a little blurb on FluentNHibernate and NHibernate.Linq.

I've been working through the samples for FNH and decided to try out some different query scenarios to see how the queries would be generated.  I stumbled a bit on the first rather simple scenario: selecting an item based on the total count of related items.  In this case, from the FNH demo, I wanted to select "all stores with more than 2 employees".  Seems like a simple enough query, right?

You can see from the full code that this should return "Bargain Basement".  However, in going through the documentation, it wasn't exactly apparent how this could be done; it seemed a lot more convoluted than necessary using criteria queries and it simply wasn't working.  Via Google, I came across a blog post that mentioned using either DetachedCriteria or HQL.  Quite frankly, neither was very appealing.

So I figured I'd download NHibernate.Linq and see if it would be better.  Not knowing what I would get, SQL-wise, I wrote the following query:

using (session.BeginTransaction())
{
    IQueryable<Store> stores = from s in session.Linq<Store>()
                               where s.Staff.Count > 2
                               select s;

    foreach (Store store in stores)
    {
        Console.WriteLine("STORE: {0}", store.Name);
    }
}

Of course, the interesting question is whether the the Staff list would be loaded to perform the count and to my pleasant surprise, it was not.  Here's the query in profiler (reformatted for legibility):

exec sp_executesql N'
    SELECT 
        this_.Id as Id1_0_, 
        this_.Name as Name1_0_ 
    FROM 
        [Store] this_ 
    WHERE 
        @p0 <   (
                SELECT 
                    count(staff1_.Id) as y0_ 
                FROM [Store] this_0_ 
                    left outer join [Employee] staff1_ 
                        on this_0_.Id=staff1_.Store_id 
                WHERE 
                    this_.Id = this_0_.Id
                )',N'@p0 int',@p0=2

Sweet! The framework correctly builds a sub-select query to count the staff members.

I guess I'm just easy to impress :-) but I'm digging it.

I think what I like about FluentNHibernate the most is that I can stop building database applications.  What I mean by this is an application built from the database up.  The main issue this raises is complexity with regards to mapping to a data layer and of course continuously having to synchronize your DDL and SQL with your class files.  The following code configures the database, including dropping and creating the tables based on mapping classes in my assemblies:

private static ISessionFactory CreateSessionFactory()
{
    return Fluently.Configure()
        .Database(
        MsSqlConfiguration.MsSql2008.ConnectionString(
            @"Data Source=SCOOBY;Initial Catalog=FluentNHDemo;
            Integrated Security=SSPI;Application Name='FNHDemo'"))
        .Mappings(m =>
                  m.FluentMappings.AddFromAssemblyOf<Store>())
        .ExposeConfiguration(BuildSchema)
        .BuildSessionFactory();
}

private static void BuildSchema(Configuration config)
{
    // this NHibernate tool takes a configuration (with mapping info in)
    // and exports a database schema from it
    SchemaExport schema = new SchemaExport(config);

    schema.Drop(false, true); // Drops the tables only.
    schema.Create(false, true);
}

With no mapping files to speak of, persistence plumbing becomes trivial and I can work entirely within Visual Studio.  Of course, for complex queries and queries that need to be highly performant, you may still be better off writing stored procedures (as I've advocated in the past), but the productivity gains to be had can't be ignored and I find the compile-time validation of the queries eases some of my indifference towards dynamic SQL.

# Friday, February 05, 2010

Paging With SPListItemCollectionPosition

Friday, February 05, 2010 10:48:01 PM UTC

Let it be known that Microsoft's terrible design of list paging is inexecusable and to make matters worse, the documentation is practically non-existent.  You would think that paging with a SPQuery would be a piece of cake!  I mean, I write paged data queries all the time.

NOT!

Colby Africa has a good overview of the issues and some basics that gave me some good insight into the core issues.  Of course, the difficulty with the SPQuery and paging isn't really with going forward, it's with going backwards.  One MSDN poster suggested storing the previous pages (see the last post here), which when you think about it, isn't a really good solution given the amount of paging strings you'd have to store (you can't just store the last navigation since going "Previous" twice requires going back twice).

Since going forward is the easy part, I won't get into that.  With regards to paging to previous pages, I hacked around a bit and spent a good 2-3 hours trying to deduce how the paging query string worked before I finally figured it out.

The algorithm works like so:

  1. When paging FORWARD, capture the ID <AND SORT FIELD VALUE> of the first item on the newly retrieved result collection.
  2. When paging BACKWARDS, use the previously captured ID <AND SORT FIELD VALUE> of the first item on the current result collection to generate the paging string.
  3. Once paged BACKWARDS, capture the ID <AND SORT FIELD VALUE> of the first item on the loaded page for the next BACKWARDS operation (just leave this off of the input query if going forwards again).

By capture, I mean to store the data and persist the data somehow (perhaps in the ViewState or SessionState).

And there you have it: three simple steps :-D

As an example, consider the following data set, sorted by Title:

ID		TITLE
---------------------------PAGE 1
17		Apple
21		Banana
18		Currant
---------------------------PAGE 2
19		Durian
5		Elderberry
1		Fig
---------------------------PAGE 3
7		Guava
10		Honey Dew
12		Indian Gooseberry

Consider a scenario where we're building a web application.  After the result set for page 3 of the data is loaded, I want to capture three pieces of data if I want to be able to load the previous page:

  1. The value of the ID of the FIRST item on the page
  2. The value of the TITLE of the FIRST item on the page (or whatever field you are sorting on)
  3. The PagingInfo string after the query is executed

The PagingInfo is already set for paging foward again.  When I page backwards, I will need to generate a new query using the PagingInfo.  To do so, I will need to:

  1. Replace the p_ID and set it to p_ID=7
  2. Replace the p_Title and set it to p_Title=Guava (replace p_Title with the static name of your sort field)
  3. Add two parameters:
    1. PagedPrev=TRUE
    2. PageLastRow=6 (last index of the second page, where we're going - this is easily calculated if you know your page size and your current page (keep these in the ViewState))

I used the following two regular expression patterns:

Regex _pidPattern = new Regex("p_ID=(?'pid'\\d+)");
Regex _pTitlePattern = new Regex("p_Title=[^&]+");

To replace the values in the string like so:

pagingInfo = _pidPattern.Replace(pagingInfo, 
	string.Format("p_ID={0}", firstItemId));
pagingInfo = _pTitlePattern.Replace(pagingInfo, 
	string.Format("p_Title={0}", firstTitle));

In this case, if I'm on page 3, the string for going back to page 2 should be:

Paged=TRUE&PagedPrev=TRUE&p_ID=7&p_Title=Guava&PageLastRow=6

And once I'm on page 2, the string required to go back to page 1 should be:

Paged=TRUE&PagedPrev=TRUE&p_ID=19&p_Title=Durian&PageLastRow=3

Well, actually, you don't need the string to go back to page 1; but this is just to give you the general idea.  In summary, the trick is pretty simple: you always need to store the PageInfo string for paging SharePoint queries and when you retrieve a resultset, you want to capture the ID and sort field of the first item.  When you go forward, the PageInfo string is enough.  When you go backwards, you need to use the captured pieces of info.

Hope that this has shed some light on the otherwise nebulous paging functionality with SharePoint list queries!

# Tuesday, January 26, 2010

Simple (?) AJAX Upload For ASP.NET

Tuesday, January 26, 2010 11:59:36 PM UTC

As I was working on an AJAX upload web part for SharePoint, I looked around to see if there was anything out there that would be suitable before I rolled my own after discovering that the ASP.NET UpdatePanel doesn't play nicely with file inputs.  Since I'm using jQuery, I figured I'd start there and see if there were any plugins which would meet the need.

To my dismay, it seems as if kids these days are all using flash (flash!) to implement asynchronous upload.  This was wholly unacceptable to me for some reason (not to mention it might cause compatibility issues for downstream clients) so I ended up tackling it myself :-D

The basics of getting this to work are simple enough; the solution is made of three main components:

  1. The main page that is displaying the upload control.  Since I was using this in a SharePoint site, I wanted to write my uploader as a web part (the control) that could be placed on any page.  The main page is simply the container for your control.  It does not post back.
  2. The control that basically just renders the <iframe/>.  The control is relatively simple.  It provides a container for the <iframe/> and also the scripts which are executed when the frame is loaded and unloaded.  The control also holds the progress layer since we want this to be shown when the user starts the upload.   This also does not post back.
  3. The upload page that receives the actual file.  This page is the target for the <iframe/> and contains the logic that validates the posted file.  This is the only page that posts back.

Before we go into the details, let's look at the screens of this in action (pay particular attention to the times):

The first screen shows the general layout of the page in the default state.  In case you're wondering, I found a handy guide for hacking the file input control and used that to customize the appearance.  Again, note the time.

Once you click "Upload", a progress layer is shown over the control.  You can also see that we've got an unloaded time now as well.

And finally, you can see that the loaded time changed once the form upload completes.

The control ASCX file contains two very simple scripts:

    function handleFrameLoaded() {
        // Do animation here.
        $("#progress").hide();
        
        $("#load").html("<b>Loaded!</b> " + 
            (new Date()).toTimeString());
    }

    function handleFrameUnloaded() {
        // Do animation here.
        $("#progress").show().fadeTo("fast", .90);
        
        $("#unload").html("<b>Unloaded!</b> " + 
            (new Date()).toTimeString());
    }

The first function is called when the frame is loaded and the second function is invoked when the file upload is submitted.  Note that both functions are called from the upload page in the <iframe/>.  In this case, I've just added simple animation calls to show and hide a progress panel.  You can hook up whatever custom code you want here.

On the upload page itself, we need to wire the events to the functions above:

    $(window).load(function() {
        parent.handleFrameLoaded();
    });

    $(document).ready(function() {
        $(".upload-button").click(function() {
            parent.handleFrameUnloaded();
        });

        /* simulate hover */
        $("#fake-container").hover(
            function() {
                $(this).addClass("hover");
            },
            function() {
                $(this).removeClass("hover");
            });

        /* simulate populating the file value since 
            we can't see the file input */
        $("input.file").change(function() {
            $("#fake input").val($(this).val());
        });
    });

It's important to note that the upload page gets its own set of window events since it's loaded inside of the frame.  The upload page makes calls to functions in the control.  I've highlighted the points of interest; you'll note that I only bind the load event of the window (I don't bind the unload).  It's also possible to do this using the onbeforeunload event, but I found that this would fire the progress layer even if I was browsing away from the page (which may confuse your users).  So it made more sense to just do it simply from the upload button click.

The upload page itself is remarkably simple:

<body>
    <form id="_form" runat="server">
    <div>
        <div id="fake-container">            
            <input type="file" id="_file" runat="server" class="file"/>            
            <div id="fake">
                <input type="text" />
            </div>            
        </div>
        <asp:Button runat="server" ID="_upload" 
            Text="Upload" OnClick="HandleUploadClick" 
            CssClass="upload-button"/>
    </div>
    </form>
</body>

The control isn't much more complex either:

<div id="frame">
    This is an asynchronous upload control.  
    The control load time is <asp:Label ID="_time" runat="server"/>

    <iframe id="upload-frame" src="Upload.aspx" 
        frameborder="0" scrolling="no" height="100px">

    </iframe>  
    <div id="progress" style="display:none;"></div>
</div>
<div>
    <div id="load"></div>
    <div id="unload"></div>
</div>

There's no codebehind for the control to speak of. The only place where you need to implement custom code is in the codebehind of the upload page to receive the posted file:

using System;
using System.Threading;
using System.Web.UI;

namespace AsyncUploadControlTest
{
    /// <summary>
    /// This is the actual page that handles the upload.
    /// </summary>
    public partial class Upload : Page
    {
        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> 
        /// instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            
        }

        /// <summary>
        /// Handles the upload click.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> 
        /// instance containing the event data.</param>
        protected void HandleUploadClick(object sender, EventArgs e)
        {
            // Just fake a long running upload for dramatic effect
            Thread.Sleep(2500);

            // Add your logic here
        }
    }
}

There you have it. Works in SharePoint 2007 just fine.  Works in IE7 and Firefox 3.5 as well.  Because the receiving upload page is just an ASPX page, you can simply output your errors or success messages to the page itself; no special hackery required.

Download the source code here: AsyncUploadControlTest.7z (17.54 KB)

# Tuesday, December 22, 2009

SharePoint Design Patterns: Entry 2.5

Tuesday, December 22, 2009 3:11:48 AM UTC

In the previous entry, we looked at how we can model a SharePoint list item using a more domain specific model to simplify programmatic access to the list item thus reducing otherwise error prone data access code and making the overall framework easier to use.  Again: the idea is to promote reuse and decrease complexity through domain specific code that abstracts the underlying SharePoint object models, making it easier for a team to build functionality on top of this framework.

One interesting point is that if you're already building your fields and content types using features XML, the work required to generate the domain specific wrappers can be simplified dramatically using automation.  In a sense, a content type is basically a class (this is generally how I map them in my domain design); why double your effort and write both the content types and the classes?

So how do we go about this?

(Side note: this isn't so much a "design pattern" as it is an "implementation pattern")

As an example, here is a simple XML file which defines a set of fields and content types which use those fields:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Field DisplayName="Model Code"
    Name="Model_Code"
    StaticName="Model_Code"
    ID="{F0000000-0000-0000-0000-000000000001}"
    Type="Integer"
    SourceID="http://schemas.someusedcarinventory.com"
    Group="My Custom Columns"/>
  <Field DisplayName="VIN"
    Name="VIN"
    StaticName="VIN"
    ID="{F0000000-0000-0000-0000-000000000002}"
    Type="Text"
    SourceID="http://schemas.someusedcarinventory.com"
    Group="My Custom Columns"/>
  <Field DisplayName="Make"
    Name="Make"
    StaticName="Make"
    ID="{F0000000-0000-0000-0000-00000000003}"
    Type="Text"
    SourceID="http://schemas.someusedcarinventory.com"
    Group="My Custom Columns"/>
  <ContentType Name="Vehicle"
    ID="0x0100FC000000000000000000000000000001"
    Description="Used car inventory"
    Group="My Custom Content Types" >
    <FieldRefs>
      <FieldRef ID="{c042a256-787d-4a6f-8a8a-cf6ab767f12d}" Name="ContentType" />
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" 
        Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE" />
      <FieldRef ID="{F0000000-0000-0000-0000-000000000001}" Name="Model_Code"/>
      <FieldRef ID="{F0000000-0000-0000-0000-000000000002}" Name="VIN"/>
      <FieldRef ID="{F0000000-0000-0000-0000-000000000003}" Name="Make"/>
    </FieldRefs>
  </ContentType>  
  <Field DisplayName="Dealership Code"
    Name="Dealership_Code"
    StaticName="Dealership_Code"
    ID="{F0000000-0000-0000-0000-00000000004}"
    Type="Integer"
    SourceID="http://schemas.someusedcarinventory.com"
    Group="My Custom Columns"/>
  <Field DisplayName="Dealership Fax Number"
    Name="Dealership_Fax_Number"
    StaticName="Dealership_Fax_Number"
    ID="{F0000000-0000-0000-0000-00000000005}"
    Type="Text"
    SourceID="http://schemas.someusedcarinventory.com"
    Group="My Custom Columns"/>
  <ContentType Name="Dealership"
    ID="0x0100FC000000000000000000000000000002"
    Description="Dealerships"
    Group="My Custom Content Types" >
    <FieldRefs>
      <FieldRef ID="{c042a256-787d-4a6f-8a8a-cf6ab767f12d}" Name="ContentType" />
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" 
        Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE" />
      <FieldRef ID="{F0000000-0000-0000-0000-000000000004}" Name="Dealership_Code"/>
      <FieldRef ID="{F0000000-0000-0000-0000-000000000005}" Name="Dealership_Fax_Number"/>
    </FieldRefs>
  </ContentType>    
</Elements>

When approaching this problem, I considered three ways of handling the class file generation:

  1. Use an object model and StringTemplate to create .cs files.  This invovled writing POCO classes (or generating them from the schema) which I could deserialize the XML to and then passing those objects to a template instance.  This seemed like too much work, given that I really didn't feel like maintaining all of that code as well.  Plus, while StringTemplate isn't - by any sense of the imagination - hard, it is a non-standard syntax that someone would have to learn to maintain and/or extend the conversion.
  2. Use an XDocument and CodeDom to create .cs files.  This seemed like even more work!  While it's framework supported, I feel like this solution would be hard to extend and maintain for most developers.
  3. Use an XSL transform to create .cs files.  This seemed to be the most natural solution given that the source file is already in XML format and a the target content structure is far from complex (the basic class file is fairly simple).  Plus, while XSLT isn't trivial, it's not that hard either (and the syntax is "standard").

One of the cool features of XSL 2.0 is the xsl:result-document element which allows you to create multiple documents from one source document.  Only one problem: .NET's XSLT engine doesn't implement XSLT 2.0!  What a bummer; it seemed like if I wanted to get this to work and generate multiple output files, it was going to take some work in code or find an XSLT 2.0 capable processor.

Enter Saxon, which provides an XSLT 2.0 processor for .NET.  The following code takes the XML above and uses the xsl:result-document to create two class files, one for each content type:

using System;
using System.IO;
using Saxon.Api;

namespace FeatureToClass
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Uri xmlFile = new Uri(
                @"C:\Users\Charles\Desktop\elements.xml");

            // Create a Processor instance.  
            Processor p = new Processor();

            // Load the source document.  
            XdmNode node = p.NewDocumentBuilder().Build(xmlFile);

            using (Stream stream = File.OpenRead("core-transform.xslt"))
            {
                // Create a transformer for the stylesheet.  
                XsltTransformer transformer = 
                    p.NewXsltCompiler().Compile(stream).Load();

                // Set the root node of the source document
                // to be the initial context node.  
                transformer.InitialContextNode = node;

                // BaseOutputUri is only necessary for xsl:result-document.  
                transformer.BaseOutputUri = xmlFile;

                transformer.SetParameter(
                    new QName("ct", "http://www.customtransform.com", "namespace"), 
                    new XdmAtomicValue("My.Custom.Package"));

                // Create a serializer.  
                Serializer serializer = new Serializer();
                transformer.Run(serializer);
            }
        }
    }
}

The code above is a simple console program that takes a (hardcoded) path to a source XML file (a SharePoint elements.xml file) and (hardcoded) namespace and loads an XSL file to transform the XML to C# class files.

Here's the transform (it's a bit messy for output formatting reasons, so you're best off copying it into an XML aware text editor to get a better view):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stylesheet [
    <!ENTITY space "<xsl:text> </xsl:text>">
    <!ENTITY cr "<xsl:text>
</xsl:text>">
]>

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:sp="http://schemas.microsoft.com/sharepoint/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:functx="http://www.functx.com"
  xmlns:ct="http://www.customtransform.com"
  version="2.0">
    <xsl:param name="ct:namespace"/>
    <xsl:output method="text"/>

    <xsl:template match="/">
        <xsl:for-each select="//sp:ContentType">
            <xsl:variable name="classname" select="replace(@Name, ' ', '')"/>
            <xsl:variable name="filename" select="concat($classname,'.cs')" />
            <xsl:value-of select="$filename" />
            <!-- Creating  -->
            <xsl:result-document href="{$filename}">
using System;

    namespace <xsl:value-of select="$ct:namespace"/>
    {
        public partial class <xsl:value-of select="$classname"/>
        {
            private string _contentTypeId;
            
            public string ContentTypeId {
                get { return _contentTypeId; }
                set { _contentTypeId = value; }
            }

            public <xsl:value-of select="$classname"/>()
            {
                _contentType = "<xsl:value-of select='@Name'/>";
                _contentTypeId = "<xsl:value-of select='@ID'/>";
            }

            <xsl:apply-templates/>
    }
}
            </xsl:result-document>
        </xsl:for-each>
    </xsl:template>

    <!--///
        Templates
    ///-->
    <xsl:template match="sp:FieldRef">
        <xsl:variable name="fieldname" select="functx:lower-first(replace(@Name, '_', ''))"/>
        <xsl:variable name="fieldid" select="@ID"/>
        <xsl:variable name="dotnettype">
            <xsl:choose>
                <xsl:when test="//sp:Field[(@ID = $fieldid) and (@Type = 'Integer')]">int</xsl:when>
                <xsl:otherwise>string</xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        private <xsl:value-of select="$dotnettype"/> _<xsl:value-of select="$fieldname" />;
        <xsl:call-template name="attribute"><xsl:with-param name="fieldid" select="$fieldid"/></xsl:call-template>
        public <xsl:value-of select="$dotnettype"/>&space;<xsl:value-of select="replace(@Name, '_', '')"/>
        {
            get { return _<xsl:value-of select="$fieldname" />; }
            set { _<xsl:value-of select="$fieldname" /> = value; }
        }
    </xsl:template>

    <xsl:template name="attribute">
        <xsl:param name="fieldid"/>
    <xsl:if test="exists(//sp:Field[@ID = $fieldid]/@ID)">[Caml(Id="<xsl:value-of select='//sp:Field[@ID = $fieldid]/@ID'/>", StaticName="<xsl:value-of select='//sp:Field[@ID = $fieldid]/@StaticName'/>", Type="<xsl:value-of select='//sp:Field[@ID = $fieldid]/@Type'/>")]</xsl:if></xsl:template>


    <!--///
        Custom functions
    ///-->
    <xsl:function
        name="functx:lower-first" as="xs:string"
        xmlns:functx="http://www.functx.com" >
        <xsl:param name="arg" as="xs:string"/>
        <xsl:sequence select="concat(lower-case(substring($arg,1,1)), substring($arg,2))"/>
    </xsl:function>
</xsl:stylesheet>

I borrowed one function from the FunctX library to create the camelCased field names.  The XSL probably isn't nearly as clean or optimized as it should be (my XSL is admittedly a bit rusty), but it gets the job done.  Here's one of the two classes (and class files) which get generated at the source directory of the input XML file:

using System;

namespace My.Custom.Package 
{
    public partial class Dealership
    {
        private string _contentTypeId;
        public string ContentTypeId {
            get { return _contentTypeId; }
            set { _contentTypeId = value; }
        }   

        public Dealership()
        {
            _contentType = "Dealership";
            _contentTypeId = "0x0100FC000000000000000000000000000002";
        }
                        
        private string _contentType;
        public string ContentType
        {
            get { return _contentType; }
            set { _contentType = value; }
        }      

        private string _title;
        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }
    
        private int _dealershipCode;
        [Caml(Id="{F0000000-0000-0000-0000-000000000003}", 
            StaticName="Dealership_Code", Type="Integer")]
        public int DealershipCode
        {
            get { return _dealershipCode; }
            set { _dealershipCode = value; }
        }
    
        private string _dealershipFaxNumber;
        [Caml(Id="{F0000000-0000-0000-0000-000000000004}", 
            StaticName="Dealership_Fax_Number", Type="Text")]
        public string DealershipFaxNumber
        {
            get { return _dealershipFaxNumber; }
            set { _dealershipFaxNumber = value; }
        }
    }
}

Awesome!  It's amazing how little code was required to get this basic scenario working.

Now we have a single source which defines our SharePoint artifacts and our code artifacts; I love it.  Write your fields and content types in your feature and you get class files for free!  You'll note that I've added a simple CamlAttribute where applicable.  This will prove handy when it comes time to automate construction of the object instance from a SharePoint list item, which we'll look at next time (for the time being, feel free to modify the XSL and remove the line for it or write an implementation of CamlAttribute).

Again, to reiterate: the goal is make it easy to build applications on top of a SharePoint deployment by adding a layer of domain specific APIs and objects so that a team can be productive while reducing duplication and the ramp up time required to understand the business domain. 

Other points for improvement and enhancement (look for these in a future installment):

  1. Parameterize the program.
  2. Consider making it a Visual Studio add-in or a custom tool.
  3. Make it go the other way; in other words: generate the content type and field XML from class files (which would be cool, too).

But even as it is, it's incredibly useful.  On the next installment, we'll see how we can build more intelligence into the model and make it more useful.

# Wednesday, September 30, 2009

Chain Of Command And Passing Parameters

Wednesday, September 30, 2009 2:02:46 AM UTC

One of the more useful patterns that I've used quite frequently is a version of Chain of Responsibility that integrates with the Command pattern.  In a classic CoR, the idea is that only one component in the chain handles the request and then execution flows out of the chain.  In a CoC pattern, the idea is that the execution flows through the entire chain.

I like Shahan Khatchadourian's description of this pattern:

When programming, certain sections of code can sometimes be viewed as a workflow or preset sequence of tasks or commands. This can considered to be the design pattern called Chain of Command...

There are two key problems that this pattern solves that make it immensely useful in everyday programming (it's a bit surprising that dofactory's listing of CoR lists the frequency of use as a 2/5).

The first problem that it solves is extensibility.  By implementing the chain as a list of abstract types (Command or Validator or whatever), using reflection (one way or another), you can build a list of concrete commands, giving each element in the chain a chance of working on the input request.  One example of how I use this is to implement validation where I might have an abstract base class called Validator.  To build the chain of validators, one very quick and easy solution is to reflect on the assembly and simply find all of the classes which implement Validator (additional complexity can be added as necessary, such as supporting validators in external assemblies or different groupings of validators).

The second (related) problem that it solves is excessively large blocks of if statements.  In a validation example, you can imagine that if it were written in-line, each validation rule would essentially map to an if statement in a large block.  In a way, it's a very useful pattern for exchanging a tiny bit of performance and memory for more modular organization of logic.  Without the CoC pattern, adding a new validation rule would mean adding another if block - yuck!  Using CoC with reflection, we can simply add another class which inherits Validator to our project and count on the component building the chain to find our class and add it to the chain.

Here is a very simple, barebones implementation:

/// <summary>
/// A simple command chain factory that doesn't do wiring.
/// </summary>
public static class SimpleCommandChainFactory
{
    /// <summary>
    /// Creates a simple list of commands to execute using reflection.
    /// </summary>
    public static List<Command> Create()
    {
        var commands = new List<Command>();

        Type[] types = Assembly.GetExecutingAssembly().GetTypes();
        Type commandType = typeof (Command);

        foreach (Type type in types)
        {
            if (!type.IsSubclassOf(commandType))
            {
                continue;
            }

            MemberInitExpression init = Expression.MemberInit(
                Expression.New(type), new MemberBinding[0]);

            Command command = Expression.Lambda<Func<Command>>(init)
                .Compile().Invoke();

            commands.Add(command);
        }

        commands = commands.OrderBy(c => c.Priority).ToList();

        return commands;
    }
}

The code checks to see if a type if a sub-type of Command and, if so, creates an instance and puts it on the chain.  The commands could then be executed like so:

internal class Program
{
    private static void Main(string[] args)
    {
        List<Command> commands = SimpleCommandChainFactory.Create();

        // Execute each command.
        foreach(Command command in commands)
        {
            command.Execute();
        }
    }
}

In this case, I'm not passing in data or checking for stop conditions (which might be useful in a validation scenario where the first failure stops processing).  To do so, you could simply pass in a single instance of some context class to each command when executing and check to see if the stop condition is true after the execute call (and break out of the for-loop).

While this pattern is immensely useful any time you find a big if or switch block that's particularly volatile, one problem that I've found with this pattern is passing parameters between two elements in the chain.  Ideally, no element in the chain should have a dependency on another element in the chain.  We want to decouple each of the elements to make it easier to build the chain dynamically.  What this means is that no element should directly set values on another element in the chain.  In essensce, to emulate the functionality of DependencyObject and DependencyProperty that we find in WF and WPF.  (Why not just use WF then?  Complexity and performance.)

At least two solutions come to mind.  The first is to pass a context with a dictionary through each element of the chain.  This would allow each element to place an output value into the dictionary and downstream components to pull these values out.  The downside of this approach is that unless you force everything into one value type (i.e. serialize to an XML string?), you can't really pass strongly typed data and now you're keyed by strings (or whatever value type) which you need to have know about in order to retrieve the value. 

A second approach would be to leverage DependencyObject and DependencyProperty.  While this sounds good in principle, it requires a mess of code to accomplish in your own code with your own objects.  Not only that, it seems to be overkill since many times, you don't need the full capabilities of the dependency system - you just want to pass a value downstream in a nice, strongly typed manner.

(There is a third approach using thread local storage, but this is probably an even worse option than the first since it wouldn't be very accessible to most developers and it doesn't really address the issue at hand.)

In the past, I've relied on the dictionary based approach.  While it wasn't ideal, it was the simplest solution that got the job done.  Deep down, I always hated this approach because I didn't like having to know the keys and having to know how to cast the results retrieved from the dictionary.  However, I recently came up with a much better solution to this issue: dynamically wired events.

We introduce two attribute classes which we can use to identify our event publishers and event subscribers.  For brevity, I'll only show the publisher attribute (they are pretty much the same in this implementation):

/// <summary>
/// Attribute used to identify event publishers.
/// </summary>
[AttributeUsage(AttributeTargets.Event)]
public class EventPublisherAttribute : Attribute
{
    private readonly string _eventName;

    /// <summary>
    /// Initializes a new instance of the <see cref="EventPublisherAttribute"/> class.
    /// </summary>
    /// <param name="eventName">Name of the event.</param>
    public EventPublisherAttribute(string eventName)
    {
        _eventName = eventName;
    }

    /// <summary>
    /// Gets the name of the event.
    /// </summary>
    /// <value>The name of the event.</value>
    public string EventName
    {
        get { return _eventName; }
    }
}

The only difference between the two in this case is the AttributeUsageAttribute.  In the case of the subscriber, we want it to apply to methods, not events.  Next, we need to apply these attributes to our concrete command types that we're going to chain.  For this example, let's say that the first item in the chain generates a GUID key that the rest of the items in the chain also need to use:

/// <summary>
/// Generates a GUID that may be needed by the rest of the chain.
/// </summary>
public class GenerateKeyCommand : Command
{
    /// <summary>
    /// Raised when a key is generated;
    /// </summary>
    [EventPublisher(EventNames.KeyGenerated)]
    public event EventHandler<EventArgs<Guid>> KeyGenerated;

    /// <summary>
    /// Executes this instance.
    /// </summary>
    public override void Execute()
    {
        Guid key = Guid.NewGuid();

        Console.Out.WriteLine("From GenerateKeyCommand: {0}", key);

        OnKeyGenerated(key);
    }

    /// <summary>
    /// Gets the priority.  A lower value indicates higher priority.
    /// </summary>
    /// <value>The priority.</value>
    public override int Priority
    {
        get { return 1; }
    }

    /// <summary>
    /// Raises the key generated event.
    /// </summary>
    /// <param name="key">The key.</param>
    private void OnKeyGenerated(Guid key)
    {
        if(KeyGenerated != null)
        {
            KeyGenerated(this, new EventArgs<Guid>(key));
        }
    }
}

As you can see, it's pretty standard stuff, with the exception of the additional attribute on the event.  Downstream, we want to handle these events in other commands:

/// <summary>
/// Simple command just for demonstration purposes.
/// </summary>
public class DoSomethingWithKeyCommand : Command
{
    private Guid _key;

    /// <summary>
    /// Executes this instance.
    /// </summary>
    public override void Execute()
    {
        Console.Out.WriteLine("From DoSomethingWithKeyCommand: {0}", _key);
    }

    /// <summary>
    /// Gets the priority.  A lower value indicates higher priority.
    /// </summary>
    /// <value>The priority.</value>
    public override int Priority
    {
        get { return 100; }
    }

    [EventSubscriber(EventNames.KeyGenerated)]
    private void HandleKeyGenerated(object sender, EventArgs<Guid> e)
    {
        _key = e.Data;
    }
}

You can see that in the event handler method, we just grab the value from the event arguments and set it on a local variable for use when Execute() is called.

Now the trick is to wire these events up using reflection to avoid creating the direct dependency between the different elements in the chain.  Spring.NET offers one way to do this using declarative events, however, it should be noted that it only works with singleton objects (this bit me in the butt until I figured it out).  Depending on the nature of your elements in the chain, that may or may not be sufficient for you.  If you need new instances every time, then we can accomplish this ourselves using a bit of reflection.

(Note that none of the code that follows has been optimized; there are a few caching opportunities to take advantage of to cut down on some of the reflection calls.)

The first step is to modify the factory method:

/// <summary>
/// Creates a command chain using reflection.
/// </summary>
/// <returns></returns>
public static List<Command> Create()
{
    List<Command> commands = new List<Command>();

    Type[] types = Assembly.GetExecutingAssembly().GetTypes();
    Type commandType = typeof (Command);

    Dictionary<string, List<EventCoupling>> eventSources
        = new Dictionary<string, List<EventCoupling>>();

    Dictionary<string, List<MethodCoupling>> eventTargets
        = new Dictionary<string, List<MethodCoupling>>();

    foreach(Type type in types)
    {
        if(!type.IsSubclassOf(commandType))
        {
            continue;
        }

        MemberInitExpression init = Expression.MemberInit(
            Expression.New(type), new MemberBinding[0]);

        Command command = Expression.Lambda<Func<Command>>(init)
            .Compile().Invoke();

        commands.Add(command);

        BuildHandlerCache(command, eventTargets, 
            type.GetMethods(_methodFlags));

        // Parse the events.
        EventInfo[] events = type.GetEvents(
            BindingFlags.Public | BindingFlags.Instance);

        if(events.Length == 0)
        {
            continue; 
        }

        BuildEventCache(command, eventSources, events);
    }

    WireEvents(eventSources, eventTargets);

    commands = commands.OrderBy(c => c.Priority).ToList();

    return commands;
}

We create two caches as we iterate through the types to hold the events and handler methods that we encounter as we iterate the types and as a final step, we wire the events together from the caches.  The cache building logic is fairly straightforward:

/// <summary>
/// Builds the handler cache.
/// </summary>
/// <param name="command">The command.</param>
/// <param name="eventTargets">The event targets.</param>
/// <param name="methods">The methods.</param>
private static void BuildHandlerCache(
    Command command, 
    IDictionary<string, List<MethodCoupling>> eventTargets, 
    IEnumerable<MethodInfo> methods)
{
    foreach(MethodInfo method in methods)
    {
        EventSubscriberAttribute[] subscriberAttributes =
            (EventSubscriberAttribute[])
            method.GetCustomAttributes(
                typeof(EventSubscriberAttribute), false);

        if (subscriberAttributes.Length == 0)
        {
            continue;
        }

        foreach(EventSubscriberAttribute attribute in subscriberAttributes)
        {
            if(!eventTargets.ContainsKey(attribute.EventName))
            {
                eventTargets[attribute.EventName] = new List<MethodCoupling>();
            }

            eventTargets[attribute.EventName].Add(
                new MethodCoupling(method, command));
        }
    }
}

/// <summary>
/// Builds the event caches.
/// </summary>
/// <param name="command">The command.</param>
/// <param name="eventSources">The event sources.</param>
/// <param name="events">The events.</param>
private static void BuildEventCache(
    Command command,
    IDictionary<string, List<EventCoupling>> eventSources,  
    IEnumerable<EventInfo> events)
{
    foreach(EventInfo eventInfo in events)
    {
        EventPublisherAttribute[] publisherAttributes =
            (EventPublisherAttribute[])
            eventInfo.GetCustomAttributes(
                typeof (EventPublisherAttribute), false);

        if(publisherAttributes.Length == 0)
        {
            continue;
        }

        foreach (EventPublisherAttribute attribute in publisherAttributes)
        {
            if(!eventSources.ContainsKey(attribute.EventName))
            {
                eventSources[attribute.EventName] = new List<EventCoupling>();
            }

            eventSources[attribute.EventName].Add(
                new EventCoupling(eventInfo, command));
        }
    }
}

The gist of it is that we want to iterate through the events and the methods, find the ones with the attributes, map them to instances of commands, and throw them into a dictionary.  As you can see, the dictionary values are generic lists on both sides; this means that a single event can fire multiple event names and a single handler method can handle multiple events (as long as the method input types are the same).  This may or may not be useful in any given scenario, but it's easy enough to rewrite this to make it a bit simpler if it's not required.

Finally, we need to wire the events together in the chain after it's created:

private static void WireEvents(
    Dictionary<string, List<EventCoupling>> eventSources, 
    Dictionary<string, List<MethodCoupling>> eventTargets)
{
    foreach(string key in eventSources.Keys)
    {
        if(!eventTargets.ContainsKey(key))
        {
            continue;
        }

        List<MethodCoupling> targets = eventTargets[key];
        List<EventCoupling> sources = eventSources[key];

        foreach(EventCoupling source in sources)
        {
            foreach(MethodCoupling target in targets)
            {
                Delegate d = Delegate.CreateDelegate(
                    source.Event.EventHandlerType, 
                    target.Command, 
                    target.Method);

                source.Event.AddEventHandler(source.Command, d);
            }
        }
    }
}

It's as simple as that: we loop through each event (publishers) and see if there is a list of methods (subscribers) to handle it in the chain.  If so, we add a delegate as a handler to the event.  In my sample project, I created three simple command types to demonstrate; here's the output when I run my program:

You can see, once the key is generated in the first command, the value is available in the downstream commands using the events.  The nice thing is that we can add more steps to our logic without much extra work.  This is particularly handy for something like implementing a chain of validation rules as it means that you don't end up writing a big if if block.  But even in general usage, this pattern is useful for breaking out a large method into smaller, more modular pieces in a much more extensible manner.

One neat thing is that it allows you to not only wire events downstream, but also upstream as well.  This means that if an element in your chain triggers an event, code in a previous even is executed if there is a handler wired for it.

In a more complete implementation, you may consider using Spring.NET or Unity or simply .NET configuration to statically identify the elements of the chain (instead of the basic reflection I've used).  You may also consider more error handling logic ;-) and passing an instance of a context through each element in the chain.

The full sample project is available here: ChainOfCommandSample.zip (11.21 KB)

# Monday, September 28, 2009

SharePoint? Is That You?

Monday, September 28, 2009 6:46:05 PM UTC

Weird discovery of the day: Recovery.gov is SharePoint (check the source or try a search).

Cool.

# Monday, September 21, 2009

Yet Another .NET Interview Questions List

Monday, September 21, 2009 5:56:11 PM UTC

There are tons of blog posts on .NET interview questions out there on the 'Net; here's another list...just because I feel like it, okay :-P?

In general, when I am interviewing people, I don't go for the obvious questions.  Not only are they boring because I've answered them so many times, but most of them can be easily studied for.  For most C#/.NET positions, there's a pretty standard set of questions that you'll encounter, most of which can be easily answered by simply reading Troelsen's Pro C# (I know because I picked it up the first time I was burned after a phone screen - I recommend this book to all junior developers looking to move up the payscale).

I do incorporate a few "template" questions, but in general, I like to keep things away from fact based questions and geared towards open-ended questions (I want to see that a candidate has actually done more than just use a feature after looking it up on MSDN or whatever - I want to see that a developer has actually sat there and thought about the technology or feature or whatever). 

Here are a few of my favorite questions for interviews; perhaps you'll find them useful for your own interviews:

[ASP.NET] Discuss the strengths and weaknesses of ASP.NET, out of the box.

I ask this question because I want to see if a developer has thought really thought about ASP.NET as a framework.  Developers who have can answer this pretty easily.  Developers who just write the code and move on will give some really perplexing answers or flat out stumble on this one.  I like this question because it's completely open-ended and a developer is free to use anything in his/her past experience as a context.  Some developers may compare and constrast it to other frameworks they've used (ASP, JSP, Python, Ruby, etc).  Some will describe past frustrations or projects as points of reference for weaknesses.  In general, I like this question because it shows whether an individual can discuss the technology intelligently.

[ASP.NET] What's the difference between an HtmlControl and a WebControl?

What I'm looking to find out with this question is whether a candidate can show some restraint with regards to using web controls on a page where an HTML control would work just as well.

[ASP.NET] Can you describe any approaches or patterns to make ASP.NET web forms programming more manageable?

In the simplest case, I'd like to hear something like "In the past, I've implemented MVC" or any sort of presenter/controller-view style pattern or - at the least - "I've created a custom base class which inherits Page", to show that the developer won't be inclined to just throw a bunch of code in the codebehind and call it a day.  One common answer is some variation of "I use an N-tier approach", but I find this answer to be insufficient since an N-tier approach doesn't mean much in terms of ensuring that your UI code is clean and well organized.  Developers who mostly think of ASP.NET as drag-drop-fill in code will never be able to give any sort of satisfactory answer to this question.

[.NET] How many major versions of the .NET runtime have there been?

Okay, this one is kind of a "gotcha" question, I admit, but it is relevant for a couple of reasons.  Developers who follow up on blogs and stay current will undoubtedly know that there is a new version of the runtime shipping with the next release of VS/.NET.  Developers who have worked extensively with ASP.NET will also know that in IIS, you can only select from 1.x or 2.x versions of the runtime.  I don't think anyone has gotten this one right yet, even though I put a particular emphasis on "runtime" when reading the question.

[.NET] What access modifier does Microsoft recommend for constructors on abstract classes?

What I'm hoping for is to one day hear: "Well, according to Framework Design Guidelines..." (or something equivalent).  The goal of the question is to see if a candidate understands some of the nuances of API and framework design, especially important for senior developer roles.  There are other questions along this vein, one of my other favorites is...

[.NET] What does the following code statement imply?

public readonly List MyStrings;

Again, the goal is to see how well a candidate understands the implications of their design decisions and some basic C#.  I won't give up on a candidate if they get it wrong; I try to coax them the correct conclusion, but few candidates can right the course once they make up their mind on this one.

If they bring up ReadOnlyCollection, they get bonus points.

[.NET] Can you expose abstract classes in an ASMX or WCF service contract?

This question can, answered correctly, indicate an above average level of understanding of .NET web services but, more importantly, I think it offers a peek at whether a candidate embraces object oriented design principals.  Candidates who have designed or worked with systems with rich object models will have undoubtedly encountered this problem (unless there were some specific interoperability scenarios which they had to design around).

[.NET] What is a custom attribute and how can you read one?

This question can reveal a lot about a candidate since there are some design scenarios that can be resolved pretty elegantly by taking advantage of custom attributes.  In addition, a candidate that can answer this question necessarily has experience working with reflection.  With regards to the second part, I'm not looking for specifics in terms of syntax and namespaces and classes, but rather a generic answer like "By using reflection" or something.

[.NET] What is the default() statement used for?

This is more of a textbook question, but candidates who have worked extensively with generics will be able to answer this with ease.  Again, being able to answer this reveals a lot about a candidate, especially when considering one for a senior developer position since being able to leverage generics is a big part of writing a solid API or framework.

[.NET] Desribe your approach to exception handling.

Another open-ended question that allows a candidate to shine - or to flail.  I've heard a wide range of responses to this one, but none that indicate that a developer has put any significant thought into one of the most important aspects of writing code on the .NET platform (especially framework level code).  Most responses fall into the basic structural elements of exception handling (try-catch-finally), but I am looking forward to the day that someone gives a response which addresses it at a much higher level than that.

[GENERAL] What is object oriented programming?

I usually preface this by stating that I'm not looking for the bullet-list textbook definition of it; I'm looking for a candidate to provide a much deeper answer than that.  There's no "right" answer, but there are definitely bad answers or responses (I've heard some wacky ones) that reveal that a candidate hasn't really thought deeply about just what it means to write good object oriented code.  To me?  Aside from the textbook stuff, OOP is about modeling complexity using structural interactions instead of straight-line, imperative logic.

This is just a small slice of my list, but they are perhaps the most important ones with regards to ASP.NET/C#, IMO.  What do you think?  Too abstract?  Too high level?  Too awesome ;-) ?  Hopefully, you've found something useful in here, either as an interviewer or an interviewee.

# Saturday, September 19, 2009

MbUnit CsvDataAttribute

Saturday, September 19, 2009 2:41:44 PM UTC

MbUnit has several cool features which distinguish it from some of the other unit testing frameworks on the .NET platform.  Among them are the RollbackAttribute, PrincipalAttribute, ThreadedRepeatAttribute, and the Csv/XmlDataAttribute.

I hadn't noticed the CsvDataAttribute previously when I've worked with MbUnit, but it's definitely one that I think that most teams can make the most use of.  While the RowAttribute allows developers to externalize and parameterize their unit tests, the CsvDataAttribute takes it to another level by allowing developers to put test parameters in a simple text file.  This is extremely handy since it becomes easier to add more test conditions as you come up with new scenarios without recompiling code.  Theoretically, you could even involve your QA team in getting the right set of test data since they could modify the external CSV file.  I find this extremely handy :-)

The documentation on how to use it was lacking a bit; while it explained that you can add metadata (custom attributes) via the CSV file, it didn't give an example for the ExpectedExceptionAttribute, one of the most common ones, I'd imagine.

Consider the following property which normalizes and validates a phone number (note: this was meant as a simple example):

/// <summary>
/// Gets or sets the number.
/// </summary>
/// <value>The number.</value>
public string Number
{
    get { return _number; }
    set
    {
        if (string.IsNullOrEmpty(value))
        {
            throw new ArgumentException(
                "The phone number cannot be null or empty.");
        }

        // Grab all the digits.
        char[] digits = value.ToCharArray()
            .Where(c => char.IsDigit(c)).ToArray();

        if (digits.Length != 10)
        {
            throw new FormatException(
                "A phone number must contain 10 digits.");
        }

        _number = new string(digits);
    }
}

The test method might look like this:

[Test]
[CsvData(FilePath = "CsvData\\PhoneNumbers.txt", HasHeader = true)]
public void TestPhoneNumberNormalizationWithCsv(
    string type, string number, string expected)
{
    PhoneNumber phoneNumber = new PhoneNumber(0, 0, number, type);

    Assert.AreEqual(expected, phoneNumber.Number);
}

Now we'd like to test our validation logic to gaurd against future refactorings to make sure that anyone refactoring this code throws the appropriate exceptions that our downstream callers expect.

You can see that I've used the FilePath property and the HasHeader property (you have to use this if there is a header, otherwise, it detects the header as a row; it's not true by default it seems).  The text file to go with this test would then look like:

Type, Number, Expected, [ExpectedException]
Home, (732) 555-1012, 7325551012
Home, , , ArgumentException

There are a few things to note here:

  1. If no exceptions are associated with the row, don't include a trailing comma and empty value (see the first line).
  2. The headers are not case sensitive.
  3. Null values can be specified using an empty value.
  4. When specifying exceptions, you do not need to use typeof(ArgumentException), just the type is enough. 

Happy (unit) testing!

# Saturday, July 25, 2009

Automatic Properties (And Why You Should Avoid Them)

Saturday, July 25, 2009 3:36:44 AM UTC

Ah yes, automatic properties.  Insn't it great that you don't have to do all of that extra typing now?  (Well, you wouldn't be doing it anyways with ReSharper, but that's besides the point.) For some reason, they've never sat well with me; they just seem like a pretty useless feature and, not only that, I think it severely impacts readability. 

Quick, are these members in a class, an abstract class, or an interface?

int Id { get; set; }

string FirstName { get; set; }

string LastName { get; set; }

Can't tell!  Perhaps you code at a leisurely pace, but when I'm in the zone, I'm flying around my desktop, flipping through tabs like crazy, ALT-TABbing between windows, and typing like a madman.  It's happened to me more than once where I've been working in a file, trying to add some logic to a getter and getting weird errors only to realize that I was working in the interface or abstract class instead of the concrete class.  Of course I don't normally write many non-public properties, but it's easy to make the mistake of missing the access modifier if you're working furiously and tabbing back and forth, especially if the file is long (so that you can see the class/interface declaration at the top of your file).

Look again:

public interface IEmployee
{
	int Id { get; set; }

	string FirstName { get; set; }

	string LastName { get; set; }
}

public class Employee
{
	int Id { get; set; }

	string FirstName { get; set; }

	string LastName { get; set; }
}

public abstract class AbstractEmployee
{
	int Id { get; set; }

	string FirstName { get; set; }

	string LastName { get; set; }
}

It's even more confusing when you're working within an abstract class and there's implementation mixed in.  Not only that, it looks like a complete mess as soon as you have to add custom logic to the getter or setter of a property (and add a backing field); it just looks so...untidy (but that's just me; I like to keep things looking consistent).  I'm also going to stretch a bit and postulate that it may also encourage breaking sound design in scenarios where junior devs don't know any better since they won't think to use a private field when the situation calls for one (just out of laziness).

I get that it's a bit more work (yeah, maybe my opinion would be different if I had to type them out all the time, too - but I don't :P), but seriously, if you're worried about productivity, then I really have to ask why you haven't installed ReSharper yet (I've been using it since 2.0 and can't imagine developing without it).  It's easy to mistake one for the other if you're just flipping through tabs really fast.  I've sworn off using them and I've been sticking to my guns on this.

There are three general arguments that I hear, from time to time, from the opposition:

  1. Too many keystrokes, man!  With R#, you simply define all of your private fields and then ALT+INS and in less than 5 or 6 keystrokes, you've generated all of your properties.  I would say even less keystrokes than using automatic properties since it's way easier to just write the private field and generate it using R#.  If you're worried about productivity and keystrokes and you're not using R#, then what the heck are you waiting for? 
  2. Too much clutter, takes up too much space! If that's the case, just surround it in a region and don't look at it.  I mean, if you really think about it, using KNF instead of Allman style bracing throughout your codebase would probably reduce whitespace clutter and raw LOC and yet...
  3. They make the assembly heavier!  Blah!  Not true!  Automatic properties are a compiler trick.  They're still there, just uglier and less readable (in the event that you have to extract code from an assembly (and I have - accidentally deleted some source, but still had the assembly in GAC!)).  In this case, the compiler generates the following fields:

    <FirstName>k__BackingField
    <Id>k__BackingField
    <LastName>k__BackingField

Depending on the project, there may also be unforseen design scenarios where you may want to get/set a private field by reflection to bypass logic implemented in a property (I dunno, maybe in a serialization scenario?).

So my take?  Just don't use them, dude!


Update: To clarify, McConnell has a whole section of Code Complete which discusses "code shape" and how it affects readability (see chapter 31). I think this is along the same veins. You gain NOTHING by using automatic properties, but you sacrifice readability and clarity. I don't think that the argument of "saving a couple lines" is a valid one since you can just as easily collapse those into regions and save many more lines or even switch bracing styles.

As McConnell writes:

"Making the code look pretty is worth something, but it's worth less than showing the code's structure. If one technique show the structure better and another looks better, use the one that shows the structure better."

"The smaller part of the job of programming is writing a program so that the computer can read it; the larger part is writing it so that other humans can read it."

My belief is that using backing fields shows the structure of the class file better than using automatic properties (which was my point in the blog post). Automatic properties are a convenience for the author, but it sacrifices structural cues to the purpose and usage of a given code file, IMO.  There is no benefit except to save a few keystrokes for the author, but in that case, even more keystrokes can be saved using R# and explicit backing fields.

# Thursday, July 23, 2009

Why ASP.NET (webforms) Sucks.

Thursday, July 23, 2009 12:57:02 AM UTC

Somehow, I got into a heated discussion at work today regarding the suckitude of ASP.NET web forms development model.  As a preface, I wrote Java for four years in a college, ASP in VBScript and JScript all throughout college, ASP after college, and then started working with ASP.NET when it released.

Undoubtedly, .NET and C# were a giant leap forward compared to ASP and JScript (my preferred scripting language for ASP).  But even from the start, I could never love ASP.NET.  Simple things that I used to do quite easily in ASP were now seemingly much more difficult and much more convoluted.  The HTML never quite came out the way I wanted it (remember the days when .NET wouldn't output cross browser compatible Javascript and markup?  And how that markup would always fail validation?  Yeah, I remember those days.) and it was a chore to get many development tasks done (had to overwrite this or implement that -- just to get a freaking icon in a table cell).  By the first year of use, I was already thinking that it was a terrible abomination of a framework; I never wanted to see a DataGrid ever again.

Ever since then, I've avoided writing applications in the traditional webforms model altogether.  First, I stumbled upon AJAX.NET, then I heard about this neat thing called "Atlas" (ASP.NET AJAX), then I picked up prototype, and finally, I have seen the light with jQuery (this is after writing my own Javascript for everything for the first several years of development).  I've never looked back; I've never once missed working with a web DataGrid.  I've never once missed working with most of the controls in ASP.NET web forms.  In fact, the only two four non-shitty controls worth using are the ScriptManager, Placeholder, LiteralControl, and Repeater.  That's it; that's where I draw the line.  UI controls?  They all suck.  Every.  Single.  One.  Why? 1) Because it mangles HTML output (ID's anyone?) which require ridiculous workarounds to do anything cool on the client side (i.e. writing the ClientID to the page?). 2) I hate viewstate...it's just extra...stuff (and yes, I'm intimately familiar with that "stuff" because I had to hack it to pieces at Factiva).

Don't get me wrong, I love .NET and C# to death; they're awesome (so awesome).  But ASP.NET webforms? I could smell coming from a mile away - like the stink of a dead skunk (or 20) in the middle of the road.  It's clever, I'll give you that, but it's been over-engineered to hell and back to account for the shittiness inherent in how it wants you to write web applications.

Finally, after what? 8, 9 years?  Microsoft has got it right with ASP.NET MVC.

What follows is the summary of my arguments as to why ASP.NET webforms suck (and it's only the tip of the iceberg!).


Undoubtedly, JSF and ASP.NET webforms suck giant elephant balls.  I mean giant balls of epic proportions of suck.  If this were the Richter scale, it would be a magnitude 10 level of suck (by the way, wiki describes that as "Epic.  Never recorded").

A simple google search for "JSF sucks" yields plenty of results.

Freddy D. has a nice summary list:

  • JSF + JSP = templates that are filled with way too much noise. f:verbatim? ack! Facelets helps here but it is still too hard to read.
  • The generated HTML is all kinds of black magic.
  • You can't have a simple link to a JSF bean with some parameters and invoking an action method, from outside the JSF context, without having to jump through all kinds of hoops.
  • Parameter binding and retrieval from a different page involves tricks and digging through the FacesContext.. yuk.
  • faces-config.xml. struts-config.xml all over again. Just too noisy and useless. What is the added value, really?
  • immediate="true"? are you kidding me?
  • the managed beans are supposed to be reusable POJOs. So why do you need to use SelectItem for select boxes? More useless code. This ties you to JSF for no good reason.
  • the data table is inept. Display Tag anyone?
  • writing your own component is way too much work.
  • want some AJAX? you'll need to add yet another framework to handle it, and if it doesn't work, you're SOL. if you want to write your own AJAX-enabled component.. read the item above and add a few more "way way WAY" in front of "too much work".
  • Even if you find ways to solve your problems, just knowing that it would be SO much easier with another framework, just adds to the frustration. Case in point, we switched to Stripes and our code is up to 30-50% more concise, clearer, easier to understand.. plus, as a small bonus, it actually works!
  • The principle of least surprise definitely does not apply when using JSF.

Well I'll be damned if those weren't some of the same reasons that ASP.NET webforms suck.

Since I'm not as familiar with JSF, I'll discuss this from the ASP.NET perspective.  First, why is ASP.NET the way it is?  Why did they design it like this?  Undoubtedly, one of the core reasons was because they thought VB6 developers were too damn stupid to know better.  To make these plebeian, lowest-of-the-low, bottom rung programmers "productive", they put together this abomination of an event model on top of a perfectly nice and awesome .NET and C#.  ASP.NET webforms are shitty beyond compare because of this.

To understand why this sucks, consider how you program for a client-server model when you are building a Windows forms application.  Your winform is responsible, clearly, for rendering data only.  It makes a service call that doesn't understand a damn thing about the winforms application, right?  The remote endpoint, the server side, cares about data and data only.  Once the service call completes, your client handles rendering of that data and putting it into grids and what not.  Your services called by the winforms client don't have silly "OnClick" handlers in the service implementation do they?  Can you imagine what that would be like if you had to write your WCF services or any sort of web service like that?  You'd have to do all this shitty state maintenance and pass around useless data (like what button was clicked); you would have to have UI logic in your service.  It sounds like it would suck to do that with your winforms to a WCF service.  This begs the question:  so why do you have them in your .aspx.cs?  .aspx.cs is an incredibly stupid model and absolutely forces you to mix your controller logic with your view logic, making it difficult to reuse, difficult to maintain, and difficult to understand.

Digest that for a moment.

(Granted, there are some differences in developing a winforms thin client and a web app and obviously some scenarios where it's advantageous to return generated/static markup.)

ASP.NET MVC is very, very far removed from JSP (I did a bit of JSP) since JSP was never an MVC design (and neither is ASP.NET webforms).  Out of the box JSP and ASP.NET webforms are both an almagam of the Page Controller and Template patterns with the shittiness of the faux event model layered on top.  ASP.NET MVC is a true MVC model (or at least it's pretty damn close) that uses a Front Controller pattern and truly separated concerns between the view, the model, and the controller.  Most of the shittiness and pain with ASP.NET stems from the fact that the page controller pattern violates all sorts of seperations of concern as it encourages mashing up code that should be isolated in a view with code that should be isolated in a controller.  The end result is a giant heaping pile of poo.  The control and event model only make the situation worse by requiring this ugly, terrible thing we've all come to hate known as viewstate.

I'm convinced that these frameworks were created for numbskull rent-a-coders because they're too lazy/stupid/incapable of grasping basic HTML, Javascript, CSS, and simple DOM.  Look, at the end of the day, if you're going to be a web developer and you're not going to put in the time to master HTML, CSS, and Javascript to some degree, you're not doing it right.  That would be like a baker that didn't want to learn the basic composition of breads and dough and the chemical reactions that make tasty baked goods out of simple ingredients like flour, yeast, eggs, water, salt, and sugar.  Web developers attached to ASP.NET web controls and fear Javascript (and I know some) are like "bakers" who open a "bakery" and buy their products from Costco and repackage them.  I guess it's efficient and productive, but at the end of the day, such a "baker" is constrained to a very small universe of possibilities...how boring.

I've come to beleive that ASP.NET webforms continue to perpetuate generations of developers who have no idea how all this "magic" works and when presented with a design scenario that calls for a truly innovative UI, they stumble because they can't figure out how to do it without a control to hold their hand...boo-hoo (I'm amazed when people are amazed by some stupid ASP.NET web control without realizing how easy it is to accomplish the same thing with some jQuery goodness (or conversely, how hard it was before we had nice things like prototype and jQuery)).  The list of companies that don't screw around with these stupid frameworks probably have some of the most brilliant developers working for them:  Yahoo!, Google, Facebook, Amazon, etc. -- these guys long ago learned the lesson that ASP.NET webforms/JSF is for simpletons (or masochists).

Okay, I concede that it's great for initial productivity.  Certainly, most developers can probably throw up a page with a grid with some databound recordset much faster than I could write a page with the same set of features.  But I wager that my implementation would be cleaner, easier to read, easier to understand, easier to maintain, easier to reuse, and easier to work with once the need arises to address a usage scenario not supported by the grid out of the box.  If first run development speed is your only concern, then I lose every time because I'm concerned about doing it right, making it maintainable, and making it easy to understand the programming model.  If you care about those things, then it's worth it to do it right.

ASP.NET MVC will be the litmus test that will differentiate the competent developers from the rent-a-coders and, hopefully, will come to replace webforms as the primary model of web application development on the .NET framework.  The "stateful web" was an experimental failure of epic proportions to satisfy the simple minds that couldn't wrap their heads around the fact that the web is inherently stateless.  Let's move on from that dark, dank, dreary past and bask in the light of ASP.NET MVC!

# Thursday, July 09, 2009

XMPP SASL Challenge-Response Using DIGEST-MD5 In C#

Thursday, July 09, 2009 3:46:19 PM UTC

I've been struggling mightily with implementing the SASL challenge-response portion of an XMPP client I've been working on. By far, this has been the hardest part to implement as it's been difficult to validate whether I've implemented the algorithm correctly as there doesn't seem to be any (easy to find) open source implementations of of SASL with the DIGEST-MD5 implementation (let alone in C#).

The trickiest part of the whole process is building the response token which gets sent back as a part of the message to the server.

RFC2831 documents the SASL DIGEST-MD5 authentication mechanism as such:

   Let { a, b, ... } be the concatenation of the octet strings a, b, ...

   Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s.

   Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string
   k, a colon and the string s.

   Let HEX(n) be the representation of the 16 octet MD5 hash n as a
   string of 32 hex digits (with alphabetic characters always in lower
   case, since MD5 is case sensitive).

      response-value  =
         HEX( KD ( HEX(H(A1)),
                 { nonce-value, ":" nc-value, ":",
                   cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))

   If authzid is specified, then A1 is


      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
           ":", nonce-value, ":", cnonce-value, ":", authzid-value }

   If authzid is not specified, then A1 is


      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
           ":", nonce-value, ":", cnonce-value }

   where

         passwd   = *OCTET

   If the "qop" directive's value is "auth", then A2 is:

      A2       = { "AUTHENTICATE:", digest-uri-value }

   If the "qop" value is "auth-int" or "auth-conf" then A2 is:

      A2       = { "AUTHENTICATE:", digest-uri-value,
               ":00000000000000000000000000000000" }

Seems simple enough, right?  Not!  It took a bit of time to parse through it mentally and come up with an impelementation, but I was still failing (miserably).

The breakthrough came when I stumbled upon a posting by Robbie Hanson:

Here's the trick - normally when you hash stuff you get a result in hex values. But we don't want this result as a string of hex values! We need to keep the result as raw data! If you were to do a hex dump of this data you'd find it to be "3a4f5725a748ca945e506e30acd906f0". But remeber, we need to operate on it's raw data, so don't convert it to a string.

The most important part of his posting is the last line (and that it included the intermediate hexadecimal string results. Win! Now I finally had some sample data to compare against to figure out where I was going wrong).  At one critical junction in my implementation of the algorithm, I was converting the MD5 hash value to a hexadecimal string -- thank goodness for Robbie's clarification of that point!

Armed with this test data, I was finally able to get it all working.  Here is the test code:

using MbUnit.Framework;
using Xmpp.Client;

namespace Xmpp.Tests
{
    [TestFixture]
    public class SaslChallengeResponseTests
    {
        [Test]
        public void TestCreateResponse()
        {
            // See example here: http://deusty.blogspot.com/2007/09/example-please.html

            // h1=3a4f5725a748ca945e506e30acd906f0
            // a1Hash=b9709c3cdb60c5fab0a33ebebdd267c4
            // a2Hash=2b09ce6dd013d861f2cb21cc8797a64d
            // respHash=37991b870e0f6cc757ec74c47877472b

            SaslChallenge challenge = new SaslChallenge(
                "md5-sess", "utf-8", "392616736", "auth", "osXstream.local");

            SaslChallengeResponse response = new SaslChallengeResponse(
                challenge, "test", "secret", "05E0A6E7-0B7B-4430-9549-0FE1C244ABAB");

            Assert.AreEqual("3a4f5725a748ca945e506e30acd906f0", 
                response.UserTokenMd5HashHex);
            Assert.AreEqual("b9709c3cdb60c5fab0a33ebebdd267c4", 
                response.A1Md5HashHex);
            Assert.AreEqual("2b09ce6dd013d861f2cb21cc8797a64d", 
                response.A2Md5HashHex);
            Assert.AreEqual("37991b870e0f6cc757ec74c47877472b", 
                response.ResponseTokenMd5HashHex);
        }
    }
}

I modeled the SASL challenge like so:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;

namespace Xmpp.Client
{
    /// <summary>
    /// Represents a SASL challenge in object code.
    /// </summary>
    public class SaslChallenge
    {
        private static readonly Dictionary<string, FieldInfo> _fields;

        private readonly string _rawDecodedText;
        private string _algorithm;
        private string _charset;
        private string _nonce;
        private string _qop;
        private string _realm;

        /// <summary>
        /// Initializes the <see cref="SaslChallenge"/> class.
        /// </summary>
        /// <remarks>
        /// Caches the properties which are set using reflection on <see cref="Parse"/>.
        /// </remarks>
        static SaslChallenge()
        {
            // Initialize the hash of fields.
            _fields = new Dictionary<string, FieldInfo>();

            FieldInfo[] fields = typeof (SaslChallenge).GetFields(
                BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (FieldInfo field in fields)
            {
                // Trim the _ from the start of the field names.
                string name = field.Name.Trim('_');

                _fields[name] = field;
            }
        }

        /// <summary>
        /// Creates a specific SASL challenge message.
        /// </summary>
        public SaslChallenge(string algorithm, string charset, 
            string nonce, string qop, string realm)
        {
            _algorithm = algorithm;
            _charset = charset;
            _nonce = nonce;
            _qop = qop;
            _realm = realm;

            Debug.WriteLine("algorithm=" + _algorithm);
            Debug.WriteLine("charset=" + _charset);
            Debug.WriteLine("nonce=" + _nonce);
            Debug.WriteLine("qop=" + _qop);
            Debug.WriteLine("realm=" + _realm);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SaslChallenge"/> 
        /// class based on the raw decoded text.
        /// </summary>
        /// <remarks>
        /// Use the <see cref="Parse"/> method to create an instance from 
        /// a raw encoded message.
        /// </remarks>
        /// <param name="rawDecodedText">The raw decoded text.</param>
        private SaslChallenge(string rawDecodedText)
        {
            _rawDecodedText = rawDecodedText;

            string[] parts = rawDecodedText.Split(',');

            foreach (string part in parts)
            {
                string[] components = part.Split('=');

                string property = components[0];

                _fields[property].SetValue(this, 
                    components[1].Trim('"'));
            }

            Debug.WriteLine("algorithm=" + _algorithm);
            Debug.WriteLine("charset=" + _charset);
            Debug.WriteLine("nonce=" + _nonce);
            Debug.WriteLine("qop=" + _qop);
            Debug.WriteLine("realm=" + _realm);
        }

        public string Realm
        {
            get { return _realm; }
        }

        public string Nonce
        {
            get { return _nonce; }
        }

        public string Qop
        {
            get { return _qop; }
        }

        public string Charset
        {
            get { return _charset; }
        }

        public string Algorithm
        {
            get { return _algorithm; }
        }

        public string RawDecodedText
        {
            get { return _rawDecodedText; }
        }

        /// <summary>
        /// Parses the specified challenge message.
        /// </summary>
        /// <param name="response">The base64 encoded challenge.</param>
        /// <returns>An instance of <c>SaslChallenge</c> based on 
        /// the message.</returns>
        public static SaslChallenge Parse(string encodedChallenge)
        {
            byte[] bytes = Convert.FromBase64String(encodedChallenge);

            string rawDecodedText = Encoding.ASCII.GetString(bytes);

            return new SaslChallenge(rawDecodedText);
        }
    }
}

And finally, here is the challenge response class which contains the meat of the response building logic:

using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;

namespace Xmpp.Client
{

    /// <summary>
    /// Partial implementation of the SASL authentication protocol 
    /// using the DIGEST-MD5 mechanism.
    /// </summary>
    /// <remarks>
    /// See <see href="http://www.ietf.org/rfc/rfc4422.txt"/> and 
    /// <see href="http://www.ietf.org/rfc/rfc2831.txt"/> for details.
    /// </remarks>
    public class SaslChallengeResponse
    {
        #region fields

        private static readonly Encoding _encoding;
        private static readonly MD5 _md5;
        private readonly SaslChallenge _challenge;
        private readonly string _cnonce;
        private readonly string _decodedContent;
        private readonly string _digestUri;
        private readonly string _encodedContent;
        private readonly string _password;
        private readonly string _realm;
        private readonly string _username;

        private string _a1Md5HashHex;
        private string _a2Md5HashHex;
        private string _responseTokenMd5HashHex;
        private string _userTokenMd5HashHex;

        #endregion

        #region properties

        /// <summary>
        /// Gets the final, base64 encoded content of the challenge response.
        /// </summary>
        /// <value>A base64 encoded string of the response content.</value>
        public string EncodedContent
        {
            get { return _encodedContent; }
        }

        /// <summary>
        /// Gets the unencoded content of the challenge response.
        /// </summary>
        /// <value>The response content in plain text.</value>
        public string DecodedContent
        {
            get { return _decodedContent; }
        }

        /// <summary>
        /// Gets the hexadecimal string representation of the user token MD5 
        /// hash value.
        /// </summary>
        /// <value>The hexadecimal representation of the user token MD5 hash 
        /// value.</value>
        public string UserTokenMd5HashHex
        {
            get { return _userTokenMd5HashHex; }
        }

        /// <summary>
        /// Gets the hexadecimal string representation of the response token 
        /// MD5 hash value.
        /// </summary>
        /// <value>The hexadecimal string representation of the response token 
        /// MD5 hash value.</value>
        public string ResponseTokenMd5HashHex
        {
            get { return _responseTokenMd5HashHex; }
        }

        /// <summary>
        /// Gets the hexadecimal string representation of the A1 MD5 hash 
        /// value (see RFC4422 and RFC2831)
        /// </summary>
        /// <value>The hexadecimal string representation of the A1 MD5 hash 
        /// value (see RFC4422 and RFC2831)</value>
        public string A1Md5HashHex
        {
            get { return _a1Md5HashHex; }
        }

        /// <summary>
        /// Gets the hexadecimal string representation of the A2 MD5 hash 
        /// value (see RFC4422 and RFC2831)
        /// </summary>
        /// <value>The hexadecimal string representation of the A2 MD5 hash 
        /// value (see RFC4422 and RFC2831)</value>
        public string A2Md5HashHex
        {
            get { return _a2Md5HashHex; }
        }

        #endregion

        /// <summary>
        /// Initializes the <see cref="SaslChallengeResponse"/> class.
        /// </summary>
        static SaslChallengeResponse()
        {
            _md5 = MD5.Create();
            _encoding = Encoding.UTF8;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SaslChallengeResponse"/> 
        /// class.
        /// </summary>
        /// <param name="challenge">The challenge.</param>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        public SaslChallengeResponse(SaslChallenge challenge, 
            string username, string password)
            : this(challenge, username, password, null, null, null)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SaslChallengeResponse"/> 
        /// class.
        /// </summary>
        /// <param name="challenge">The challenge.</param>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        /// <param name="cnonce">A specific cnonce to use.</param>
        public SaslChallengeResponse(SaslChallenge challenge, string username, 
            string password, string cnonce)
            : this(challenge, username, password, null, null, cnonce)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SaslChallengeResponse"/> 
        /// class.
        /// </summary>
        /// <param name="challenge">The challenge.</param>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        /// <param name="realm">A specific realm, different from the one in the 
        /// challenge.</param>
        /// <param name="digestUri">The digest URI.</param>
        /// <param name="cnonce">A specific client nonce to use.</param>
        public SaslChallengeResponse(SaslChallenge challenge, string username, 
            string password, string realm, string digestUri, string cnonce)
        {
            _challenge = challenge;
            _username = username;
            _password = password;

            if (string.IsNullOrEmpty(_challenge.Realm))
            {
                _realm = realm;
            }
            else
            {
                _realm = challenge.Realm;
            }

            if (string.IsNullOrEmpty(_realm))
            {
                throw new ArgumentException("No realm was specified.");
            }

            if (string.IsNullOrEmpty(cnonce))
            {
                _cnonce =
                    Guid.NewGuid().ToString().TrimStart('{').TrimEnd('}')
                        .Replace("-", string.Empty).ToLowerInvariant();
            }
            else
            {
                _cnonce = cnonce;
            }

            if (string.IsNullOrEmpty(digestUri))
            {
                _digestUri = string.Format("xmpp/{0}", _challenge.Realm);
            }
            else
            {
                _digestUri = digestUri;
            }

            // Main work here:
            _decodedContent = GetDecodedContent();

            byte[] bytes = _encoding.GetBytes(_decodedContent);

            _encodedContent = Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// Gets the body of the response in a decoded format.
        /// </summary>
        /// <returns>The raw response string.</returns>
        private string GetDecodedContent()
        {
            // Gets the response token according to the algorithm in RFC4422 
            // and RFC2831
            _responseTokenMd5HashHex = GetResponse();

            StringBuilder buffer = new StringBuilder();

            buffer.AppendFormat("username=\"{0}\",", _username);
            buffer.AppendFormat("realm=\"{0}\",", _challenge.Realm);
            buffer.AppendFormat("nonce=\"{0}\",", _challenge.Nonce);
            buffer.AppendFormat("cnonce=\"{0}\",", _cnonce);
            buffer.Append("nc=00000001,qop=auth,");
            buffer.AppendFormat("digest-uri=\"{0}\",", _digestUri);
            buffer.AppendFormat("response={0},", _responseTokenMd5HashHex);
            buffer.Append("charset=utf-8");

            return buffer.ToString();
        }

        /// <summary>
        /// HEX( KD ( HEX(H(A1)), { nonce-value, ":" nc-value, ":", cnonce-value, 
        /// ":", qop-value, ":", HEX(H(A2)) }))
        /// </summary>
        private string GetResponse()
        {
            byte[] a1 = GetA1();
            string a2 = GetA2();

            Debug.WriteLine("a1=" + ConvertToBase16String(a1));
            Debug.WriteLine("a2=" + a2);

            byte[] a2Bytes = _encoding.GetBytes(a2);

            byte[] a1Hash = _md5.ComputeHash(a1);
            byte[] a2Hash = _md5.ComputeHash(a2Bytes);

            _a1Md5HashHex = ConvertToBase16String(a1Hash);
            _a2Md5HashHex = ConvertToBase16String(a2Hash);

            // Let KD(k, s) be H({k, ":", s})
            string kdString = string.Format("{0}:{1}:{2}:{3}:{4}:{5}",
                _a1Md5HashHex, _challenge.Nonce, "00000001",
                _cnonce, "auth", _a2Md5HashHex);

            Debug.WriteLine("kd=" + kdString);

            byte[] kdBytes = _encoding.GetBytes(kdString);

            byte[] kd = _md5.ComputeHash(kdBytes);
            string kdBase16 = ConvertToBase16String(kd);

            return kdBase16;
        }

        /// <summary>
        /// A1 = { H( { username-value, ":", realm-value, ":", passwd } ), 
        /// ":", nonce-value, ":", cnonce-value }
        /// </summary>
        private byte[] GetA1()
        {
            string userToken = string.Format("{0}:{1}:{2}",
                                             _username, _realm, _password);

            Debug.WriteLine("userToken=" + userToken);

            byte[] bytes = _encoding.GetBytes(userToken);

            byte[] md5Hash = _md5.ComputeHash(bytes);

            // Use this for validation purposes from unit testing.
            _userTokenMd5HashHex = ConvertToBase16String(md5Hash);

            string nonces = string.Format(":{0}:{1}",
                                          _challenge.Nonce, _cnonce);

            byte[] nonceBytes = _encoding.GetBytes(nonces);

            byte[] result = new byte[md5Hash.Length + nonceBytes.Length];

            md5Hash.CopyTo(result, 0);
            nonceBytes.CopyTo(result, md5Hash.Length);

            return result;
        }

        /// <summary>
        /// A2 = { "AUTHENTICATE:", digest-uri-value }
        /// </summary>
        private string GetA2()
        {
            string result = string.Format("AUTHENTICATE:{0}", _digestUri);

            return result;
        }

        /// <summary>
        /// Converts a byte array to a base16 string.
        /// </summary>
        /// <param name="bytes">The bytes to convert.</param>
        /// <returns>The hexadecimal string representation of the contents 
        /// of the byte array.</returns>
        private string ConvertToBase16String(byte[] bytes)
        {
            StringBuilder buffer = new StringBuilder();

            foreach (byte b in bytes)
            {
                string s = Convert.ToString(b, 16).PadLeft(2, '0');

                buffer.Append(s);
            }

            Debug.WriteLine(string.Format("Converted {0} bytes", 
                bytes.Length));

            string result = buffer.ToString();

            return result;
        }
    }
}

Happy DIGESTing!

# Wednesday, July 08, 2009

Leveraging The Windows Forms WebBrowser Control (For The Win)

Wednesday, July 08, 2009 1:28:32 PM UTC

I've been working on a little utility to experiment with the XMPP protocol.  The idea was to write a tool that would allow me to send, receive, and display the XML stream and XML stanza messages at the core of XMPP.

Of course, I could have implemented it using a simple multi-line text box for the XML entry, but that would mean that I wouldn't have nice things like syntax highlighting (for XML) and nice (auto) indentation.

On the desktop, I'm not familiar with any free Windows Forms editor controls that are capable of syntax highlighting.  But on the web side, there are several free, open source script libraries at our disposal.  For example, CodePress, EditArea, and CodeMirror.

I chose CodeMirror for this application as it was the simplest library that met my needs.

There really aren't any tricks to this aside from getting the URL correct.  In this case, I have my static HTML content in a directory in my project:

And I set the content files to "Copy always" in the properties pane for the files so that they get copied to the output directory of the project.  To set the correct path, I find the executing directory of the application and set the URL properly:

protected override void OnLoad(EventArgs e)
{
    if (!DesignMode)
    {
        string path = Path.Combine(
            Environment.CurrentDirectory, 
            "HTML/input-page.html");
        path = path.Replace('\\', '/');

        _inputBrowser.Url = new Uri(path);
    }

    base.OnLoad(e);
}

Note that I check if the control is in design mode (the designer throws an error if you don't do this since the path points to Visual Studio's runtime directory instead of your applications output).  Now all that's left is to get the script and style references correct in your HTML page:

<script src="../HTML/CodeMirror/js/codemirror.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="../HTML/CodeMirror/css/docs.css" />  

And in your script:

<script type="text/javascript">
    var editor = CodeMirror.fromTextArea('code', {
        height: "210px",
        parserfile: "parsexml.js",
        stylesheet: "../HTML/CodeMirror/css/xmlcolors.css",
        path: "../HTML/CodeMirror/js/",
        continuousScanning: 500,
        lineNumbers: true,
        textWrapping: false
    });
</script>

The final part is getting your Windows forms code talking to the Javascript in the browser.  In this case, I've written some simple Javascript that interacts with the editor control:

<script type="text/javascript">
    var $g = document.getElementById;

    function resize(height) {
        var textArea = $g("code");

        // Get the iframe.
        var editor = textArea.nextSibling.firstChild;

        editor.style.height = (height - 1) + "px";
    }

    function reset() {
        editor.setCode("");
    }

    function addContent(data) {
        var code = editor.getCode();

        editor.setCode(code + data);

        editor.reindent();
    }

    function setContent(data) {
        editor.setCode(data);

        editor.reindent();

        // Scroll to bottom.
        editor.selectLines(editor.lastLine(), 0);
    }

    function getContents() {
        return editor.getCode();
    }
</script>

From the application code, we can call these script functions using the InvokeScript method:

private void AddStreamMessageInternal(string data)
{
    if (_streamBrowser.Document != null)
    {
        // Get the contents
        string code = (string) _streamBrowser.Document.InvokeScript(
            "getContents", new object[] {});

        code = code + data;

        code = code.Replace("><", ">\r\n<");

        _streamBrowser.Document.InvokeScript(
            "setContent", new object[] {code});
    }
}

private void AdjustSize()
{
    // Call a resize method to change the HTML editor size.
    if (_streamBrowser.Document != null)
    {
        _streamBrowser.Document.InvokeScript(
            "resize", new object[] {_streamBrowser.ClientSize.Height});
    }
}

public void RefreshBrowserContents()
{
    if (_streamBrowser.Document != null)
    {
        _streamBrowser.Document.InvokeScript(
            "reset", new object[] {});
    }
}

Awesome! You can see that I can both pass arguments into the Javascript functions and read the return data from the Javascript function as well.  The big win is that now you can take advantage of your favorite Javascript utilities in your Windows Forms applications.

# Friday, June 12, 2009

Discovering System.Linq.Expressions

Friday, June 12, 2009 3:24:08 AM UTC

I'm officially a fan: System.Linq.Expressions is one of the coolest namespaces.

I've been working on a simple workflow engine as an example codebase for exploring different aspects of object oriented programming (inheritance, encapsulation, polymorphism, design patterns, etc.) for training purposes.

As a side note, I've found that it's actually very difficult to describe good object oriented code; I can just kind of feel it when I'm writing it and I know it when I see it...but it's really, really hard to describe.  I was asked by an associate consultant why it mattered.  Why bother with good object oriented design?  For me (at least), more than anything, it's about organization of code, readability, maintainability, and usability.  Good object oriented code makes it easy to think about the models and how the interactions between the different moving parts are executed.  But that's a bigger topic for a different post.

Back on topic :-D The basic design scenario that I was trying to solve in this case is that the simple workflow engine (SWE) would have the capability of hydrating a workflow template instance from an XML definition file (much like WF does with .xoml files, but on a much more basic level, of course).  I thought this would be a good exercise for teaching purposes as it would cover various aspects of reflection.  Somewhere along the line, inspired by a comment by Richard Deeming (see bullet #4) on Rick Strahl's DataContextFactory implementation, I decided to see if I could do it using expression trees instead.

Here is a sample XML template definition:

<WorkflowTemplate>
    <Actions>
        <Action Type="SimpleWorkflowEngine.Extensions.CustomActions.EmailAction, 
            SimpleWorkflowEngine.Extensions">
            <Parameters>
                <Parameter Name="ContinueOnError">true</Parameter>
                <Parameter Name="FriendlyName">Send Email</Parameter>
                <Parameter Name="RecipientAddress">cchen@domain.com</Parameter>
                <Parameter Name="Message">Hello, World! From SimpleWorkflowEngine!</Parameter>
                <Parameter Name="Subject">Test Email</Parameter>
            </Parameters>
        </Action>
    </Actions>
</WorkflowTemplate>

Here are the classes which this XML deserializes to:

using System;
using System.Collections.ObjectModel;
using System.Xml.Serialization;

namespace SimpleWorkflowEngine.Core.Common
{
    /// <summary>
    /// Models a workflow template.
    /// </summary>
    [Serializable]
    [XmlRoot("WorkflowTemplate")]
    public class WorkflowTemplate
    {
        private Collection<WorkflowTemplateAction> _actions;

        /// <summary>
        /// Gets or sets the actions for this workflow template.
        /// </summary>
        /// <value>The actions.</value>
        [XmlArray("Actions"), XmlArrayItem("Action", 
            typeof(WorkflowTemplateAction))]
        public Collection<WorkflowTemplateAction> Actions
        {
            get { return _actions; }
            set { _actions = value; }
        }
    }

    /// <summary>
    /// Represents an action in the workflow.
    /// </summary>
    [Serializable]
    public class WorkflowTemplateAction
    {
        private string _typeName;
        private Collection<WorkflowTemplateParameter> _parameters;

        /// <summary>
        /// Gets or sets the type name of the concrete 
        /// <see cref="WorkflowAction"/> class.
        /// </summary>
        /// <value>
        /// The type name of the concrete <see cref="WorkflowAction"/> class.
        /// </value>
        [XmlAttribute("Type")]
        public string TypeName
        {
            get { return _typeName; }
            set { _typeName = value; }
        }

        /// <summary>
        /// Gets or sets the parameters which map to property values on 
        /// the action.
        /// </summary>
        /// <value>The parameters.</value>
        [XmlArray("Parameters"), XmlArrayItem("Parameter", 
            typeof(WorkflowTemplateParameter))]
        public Collection<WorkflowTemplateParameter> Parameters
        {
            get { return _parameters; }
            set { _parameters = value; }
        }
    }

    /// <summary>
    /// Represents a property value on the <see cref="WorkflowAction"/>.
    /// </summary>
    [Serializable]
    public class WorkflowTemplateParameter
    {
        private string _name;
        private string _value;

        /// <summary>
        /// Gets or sets the name.  It must match the name of the property.
        /// </summary>
        /// <value>The name of the property.</value>
        [XmlAttribute("Name")]
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>The value.</value>
        [XmlText(typeof(string))]
        public string Value
        {
            get { return _value; }
            set { _value = value; }
        }
    }
}

I've done something similar in a workflow engine that I put together for Zorch Software before the days of WF. Back then I used reflection to assemble a workflow instance from an XML template as well. (In that case, the engine supported state machine workflows; for this training sample, I thought that just sequential was good enough)

Here is the invocation code to get a new instance of a workflow from a workflow template definition:

using System;
using MbUnit.Framework;
using SimpleWorkflowEngine.Core.Common;
using SimpleWorkflowEngine.Core.Contracts;
using SimpleWorkflowEngine.Core.Runtime;

namespace SimpleWorkflowEngine.Tests.Fixtures
{
    [TestFixture]
    public class WorkflowFactoryTests
    {
        [Test]
        public void TestCreateInstance()
        {
            IWorkflowTemplateProvider provider =
                ApplicationContext.Instance.Resolve<IWorkflowTemplateProvider>();

            WorkflowTemplate template =
                provider.FromTemplateId(
                new Guid("1FE5526C-D0E7-4c58-8644-3B3144AEED0E"));

            Workflow instance = WorkflowFactory.Create(template);

            Assert.AreEqual(1, instance.Actions.Count);
        }
    }
}

The basics are that the factory has to create an instance by iterating through each WorkflowTemplateAction and creating a concrete WorkflowAction instance and set property values using the WorkflowTemplateParameter associated with the WorkflowTemplateAction.

Here is the implementation of the factory method (cool stuff in bold):

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using SimpleWorkflowEngine.Core.Common;

namespace SimpleWorkflowEngine.Core.Runtime
{
    /// <summary>
    /// Assembles a workflow instance based on an input template.
    /// </summary>
    public static class WorkflowFactory
    {
        private static string _nullPropertyError = 
            "The parameter \"{0}\" did not match a property on the class \"{1}\".";

        /// <summary>
        /// Assembles a workflow instance from a workflow template instance.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <returns>A workflow instance based on the workflow template.</returns>
        public static Workflow Create(WorkflowTemplate template)
        {
            Workflow instance = new Workflow();

            foreach(WorkflowTemplateAction templateAction in template.Actions)
            {
                Type actionType = Type.GetType(templateAction.TypeName);               

                List<MemberBinding> bindings = new List<MemberBinding>();

                foreach(WorkflowTemplateParameter parameter in templateAction.Parameters)
                {
                    BindingFlags flags = BindingFlags.SetProperty 
                        | BindingFlags.Instance | BindingFlags.Public;

                    // Get the property matching the parameter name.
                    PropertyInfo property = actionType.GetProperty(
                        parameter.Name, flags);

                    if(property == null)
                    {
                        throw new NullReferenceException(string.Format(
                            _nullPropertyError, parameter.Name, actionType.Name));
                    }

                    // Convert the parameter value type.
                    object value = Convert.ChangeType(
                        parameter.Value, property.PropertyType);

                    // Create an assignment binding (set the property value).
                    MemberAssignment binding = Expression.Bind(
                        property, 
                        Expression.Constant(value, property.PropertyType));

                    bindings.Add(binding);
                }

                // Create the code expression and execute it to get a new instance.
                MemberInitExpression init = Expression.MemberInit(
                    Expression.New(actionType), bindings);

                WorkflowAction action = Expression.Lambda<Func<WorkflowAction>>(init)
                    .Compile().Invoke();

                // Add the action to the workflow.
                instance.Actions.Add(action);
            }

            return instance;
        }
    }
}

The outer for loop iterates the actions to create and the inner for loop collects the properties to set on the action.  Object creation and initializaiton is done in one shot using Expression.Lambda.

For reference, here is the target class for the XML in the sample above:

using System;
using SimpleWorkflowEngine.Core.Attributes;
using SimpleWorkflowEngine.Core.Common;
using SimpleWorkflowEngine.Core.Constants;
using SimpleWorkflowEngine.Extensions.Components;

namespace SimpleWorkflowEngine.Extensions.CustomActions
{
    /// <summary>
    /// A worflow action which sends an email to a recipient.
    /// </summary>
    public class EmailAction : WorkflowAction
    {
        private MailClientService _mailClientService;
        private string _message;
        private string _recipientAddress;
        private string _subject;

        /// <summary>
        /// Sets the mail client service.
        /// </summary>
        /// <value>The mail client service.</value>
        public MailClientService MailClientService
        {
            set { _mailClientService = value; }
        }

        /// <summary>
        /// Gets or sets the recipient address.
        /// </summary>
        /// <value>The recipient address.</value>
        [Parameter(Usage.IsRequired, "Recipient e-mail")]
        public string RecipientAddress
        {
            get { return _recipientAddress; }
            set { _recipientAddress = value; }
        }

        /// <summary>
        /// Gets or sets the message.
        /// </summary>
        /// <value>The message.</value>
        [Parameter(Usage.IsRequired, "Message")]
        public string Message
        {
            get { return _message; }
            set { _message = value; }
        }

        /// <summary>
        /// Gets or sets the subject.
        /// </summary>
        /// <value>The subject.</value>
        [Parameter(Usage.IsRequired, "Subject")]
        public string Subject
        {
            get { return _subject; }
            set { _subject = value; }
        }

        /// <summary>
        /// Gets a value indicating whether this instance 
        /// [requires input].
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance [requires input]; 
        /// otherwise, <c>false</c>.
        /// </value>
        public override bool RequiresInput
        {
            get { return false; }
        }

        /// <summary>
        /// Inheriting member should override this method to implement 
        /// custom execution logic.
        /// </summary>
        /// <param name="context">The context.</param>
        protected override void OnExecute(ExecutionContext context)
        {
            if (_mailClientService == null)
            {
                throw new NullReferenceException(
                    "No mail service client is configured for this runtime.");
            }

            _mailClientService.SendMail(RecipientAddress, Subject, Message);
        }
    }
}

Admittedly, I didn't expect this to work...I had a hell of a time figuring out how to create the expression to set the property values.

# Tuesday, June 09, 2009

I Like Jeffrey Palermo's Prediction...

Tuesday, June 09, 2009 4:15:49 PM UTC

I've been playing around with ASP.NET MVC for about a week now and it does everything right that ASP.NET web forms did so wrong.  I've hated ASP.NET web forms with a passion as soon as I realized that the model was terrible for the majority of development shops in terms of managing unmanageable code jumbles -- huge methods written on event handlers...

Don't get me wrong, ASP.NET 1.0 was a huge step up from classic ASP, but it has exploded into this huge culture of control based RAD developers.  Not that you couldn't roll your own MVC pattern for ASP.NET, but having it as an officially supported development model should help bring more web developers out from the grips of the dark side.

Most consultants (even "senior" ones) simply take the quick-and-dirty route when it comes to ASP.NET web forms development, dragging and dropping controls all day long.  Not that it's a bad thing...for prototyping, but it quickly devolves into hard to manage, hard to maintain, and difficult to test codebases with very low levels of reusability.  This is especially true once you roll on junior or mid level developers to a web project.

Earlier in the year, Jeffrey Palermo predicted that MVC would replace web forms as the dominant web application development model on the .NET platform.  With the recent news of MVC 2, Palermo reasserts his prediction with even greater conviction.  I was already long convinced that ASP.NET web forms was a craptastic model for web application development, but I had some skepticism about MVC (after my pretty awesome experience with Django).  This past week has convinced me that MVC kicks ass and I hope that Jeffrey's prediction is right.

I wholeheartedly agree; I simply can't wait to dump ASP.NET web forms.

# Thursday, May 28, 2009

Visitor Pattern In C# 4.0

Thursday, May 28, 2009 7:19:17 PM UTC

I've blogged about the Visitor pattern previously and using double dispatch to resolve .NET's inherent inability to resolve methods by parameter type at runtime.

As I was reading about C# 4.0's dynamic types, I started to wonder if this would mean that we could finally get a more concise implementation of the pattern.  My hunch was correct.

Here is the updated code listing (key changes bolded):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace VisitorPatternConsole
{
    public class Program
    {
        private static void Main(string[] args)
        {
            // NOTE: Using dynamic collections.
            Collection<dynamic> visitors 
				= new Collection<dynamic>();
            Collection<dynamic> pets 
				= new Collection<dynamic>();
 
            // Initialize the pets
            pets.Add(new Fish());
            pets.Add(new Dog());

            // Initialize the visitors
            visitors.Add(new Feeder());
            visitors.Add(new Walker());

            // Visit each of the pets.
            foreach (dynamic pet in pets)
            {
                foreach (dynamic visitor in visitors)
                {
                    visitor.Visit(pet);
                }
            }

            // Check the results.
            foreach (Pet pet in pets)
            {
                Console.Out.WriteLine(pet.GetType().Name);
                foreach (String note in pet.Visitors)
                {
                    Console.Out.WriteLine("\t{0}", note);
                }
            }
        }
    }

    /// <summary>
    /// Handles the base cases.
    /// </summary>
    public abstract class AbstractVisitor
    {
        public void Visit(Pet pet)
        {
            pet.Visitors.Add(
                "Not supported for this type of pet...");
        }
    }

    /// <summary>
    /// Concrete visitor, a pet feeder.
    /// </summary>
    public class Feeder : AbstractVisitor
    {
        public void Visit(Dog dog)
        {
            // Feed the dog
            dog.Visitors.Add("Fed the dog");
        }

        public void Visit(Fish fish)
        {
            // Feed the fish
            fish.Visitors.Add("Fed the fish");
        }
    }

    /// <summary>
    /// Concrete visitor, a pet walker.
    /// </summary>
    public class Walker : AbstractVisitor
    {
        public void Visit(Dog dog)
        {
            dog.Visitors.Add("Walked the dog");
        }

        // Fish can't be walked!
    }

    /// <summary>
    /// Base class for pets.
    /// </summary>
    public abstract class Pet
    {
        private readonly Collection<string> visitors;

        public Collection<string> Visitors
        {
            get { return visitors; }
        }

        protected Pet()
        {
            visitors = new Collection<string>();
        }
    }

    /// <summary>
    /// A pet fish.
    /// </summary>
    public class Fish : Pet { }

    /// <summary>
    /// A pet dog.
    /// </summary>
    public class Dog : Pet { }
}

Here is the output:

Wow, just when I thought dynamic was going to suck :-D

What is somewhat interesting is that both collections have to be declared of type dynamic; I'm still mulling this over, but it's not clear why it doesn't work if only one of the collections is declared dynamic (I figured that it should have worked if the visitors collection alone was declared dynamic).

# Friday, April 17, 2009

WCF Load Balancing : An End To End Example For NetTcpBinding

Friday, April 17, 2009 6:17:08 PM UTC

Recently, I worked on prototyping WCF load balancing for our product, FirstPoint.  I built a simple example to test the configuration and behavior of load balancing.  Since there aren't many end-to-end examples of WCF load balancing on the web, I'm hoping this will be useful (since the Microsoft documentation on this is basically non-existent...well, for NetTcpBindings at least).

I will assume that you are already familiar with network load balancing and configuring the NLB on Windows Server 2003.

Here's a screenshot of how I've configured my network load balancer:

You'll notice that I've configured a specific port range for my service.  Also, take note of the cluster address: 192.168.1.220.  The two servers that make up the cluster are FPDEV1 (192.168.1.222) and FPDEV2 (192.168.1.223).

I've defined a simple service interface which simply echoes the message with a server name:

using System.ServiceModel;

namespace WcfLoadBalancingSample.Server.Contracts {
    /// <summary>
    /// A simple service contract definition which defines an echo operation.
    /// </summary>
    [ServiceContract(SessionMode = SessionMode.Allowed)]
    public interface IEchoService {

        /// <summary>
        /// Echoes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>The input message with a server identifier attached.</returns>
        [OperationContract]
        string Echo(string message);
    }
}

And here is the implementation:

using System;
using WcfLoadBalancingSample.Server.Contracts;

namespace WcfLoadBalancingSample.Server.Services {
    /// <summary>
    /// Implements the <c>IEchoService</c>.
    /// </summary>
    public class EchoService : IEchoService {
        #region IEchoService Members

        /// <summary>
        /// Echoes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>
        /// The input message with a server identifier attached.
        /// </returns>
        public string Echo(string message) {
            return string.Format("[{0}] {1}", Environment.MachineName, message);
        }

        #endregion
    }
}  

As you can see, I've simply prepended the machine name to each response so that we can track which server we are connecting to. Here is the main program which hosts the service:

using System;
using System.ServiceModel;
using WcfLoadBalancingSample.Server.Services;

namespace WcfLoadBalancingSample.Server {
    internal class Program {
        private static void Main(string[] args) {
            var program = new Program();
            program.Run();
        }

        public void Run() {           
            ServiceHost serviceHost = null;

            try {
                serviceHost = new ServiceHost(typeof (EchoService));
                serviceHost.Open();

                Console.Out.WriteLine("Service ready.");
                Console.Out.WriteLine("Press any key to terminate.");
                Console.Out.WriteLine("============================");
                Console.ReadKey();
            }
            catch (Exception exception) {
                Console.Out.WriteLine(exception);
                Console.ReadKey();
            }
            finally {
                if (serviceHost != null) {
                    serviceHost.Abort();
                }
            }
        }
    }
}  

This should be deployed on your each of your two (or more) servers in your cluster.  The magic comes next in the configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <services>
            <service name="WcfLoadBalancingSample.Server.Services.EchoService"
                     behaviorConfiguration="WcfLoadBalancingSample.Server.Services.EchoServiceBehavior">
                <!-- Service Endpoints -->
                <!--///
                    The configured endpoint address is the IP address of the load balanced
                    cluster.  The port number has been mapped to the cluster.
                ///-->
                <endpoint
                    address ="net.tcp://192.168.1.220:12345/lb/EchoService"
                    binding="customBinding"
                    bindingConfiguration="DefaultCustomBinding"
                    contract="WcfLoadBalancingSample.Server.Contracts.IEchoService">
                </endpoint>
            </service>
        </services>
        <bindings>
            <!--///
                A simple custom binding.  Note the leaseTimeout setting.
                This is referenced in the SDK documentation, but not described
                in any way as to how you're supposed to configure it.
            ///-->
            <customBinding>
                <binding name="DefaultCustomBinding">
                    <windowsStreamSecurity protectionLevel="None"/>
                    <binaryMessageEncoding/>
                    <tcpTransport>
                        <connectionPoolSettings leaseTimeout="00:00:01"/>
                    </tcpTransport>
                </binding>
            </customBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="WcfLoadBalancingSample.Server.Services.EchoServiceBehavior">
                    <serviceMetadata httpGetEnabled="True"
                                     httpGetUrl="http://192.168.1.220/lb/EchoService/MEX"/>
                    <serviceDebug includeExceptionDetailInFaults="True" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

The most important part of this configuration file is the setting for the lease timeout. The SDK documentation references this setting, but does not go into detail on how it's configured.  Note that it seems that you can only set the least timeout value in configuration using a custom binding.

There is one particularly important thing to note here: I've set the timeout to 1 second for demonstration purposes only.  The SDK documentation mentions that this value should be set to 30 seconds.  As we'll see later, I have the client creating a new connection every 2.5 seconds (on purpose so we can test connectivity).  What I found was that with the default setting (5 minutes, according to the SDK), if you initially connect to server A and server A goes down, it will not automatically connect to server B.  I assume this is because of the lease timeout value (it throws an exception).

Also note that the endpoint is configured using the IP address of the node balancing cluster and not the individual servers.

The client side of it is pretty straight forward as well:

using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using WcfLoadBalancingSample.Client.LoadBalancedService;

namespace WcfLoadBalancingSample.Client {
    public delegate void EchoDelegate();

    public class EchoEventArgs : EventArgs {
        public EchoEventArgs(string message) {
            Message = message;
        }

        public string Message { get; set; }
    }

    internal class Program {
        private static void Main(string[] args) {
            var program = new Program();
            program.Run();
        }

        public void Run() {
            // Start the server.
            Console.Out.WriteLine("Starting client...(press any key to exit)");

            // Start second thread to ping the server.
            EchoDelegate echoDelegate = EchoAsync;
            echoDelegate.BeginInvoke(EchoAsycCompleted, null);

            Console.Read();
        }
        
        /// <summary>
        /// Asynchronous execution of the call to the server.
        /// </summary>
        private void EchoAsync() {
            try {
                int count = 0;
                while (true) {
                    using (var serviceClient = new EchoServiceClient()) {
                        // Call the echo service.
                        string result = serviceClient.Echo(
                            count.ToString());

                        Console.Out.WriteLine(result);

                        count++;                        
                    }

                    Thread.Sleep(2500);
                }
            }
            catch (Exception exception) {
                Console.Out.WriteLine(exception);
            }
        }

        /// <summary>
        /// Handles the completion of the thread.
        /// </summary>
        /// <param name="result">The result.</param>
        private void EchoAsycCompleted(IAsyncResult result) {
            var r = (AsyncResult) result;
            var e = (EchoDelegate) r.AsyncDelegate;

            e.EndInvoke(r);
        }
    }
}

The only thing to note is that I used a delegate to spin off a second thread to make the call to the server.  Adding a reference to the server generates the following configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="CustomBinding_IEchoService">
                    <security mode="Transport">
                        <transport clientCredentialType="Windows" 
                                   protectionLevel="None" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint 
                address="net.tcp://192.168.1.220:12345/lb/EchoService"
                binding="netTcpBinding" 
                bindingConfiguration="CustomBinding_IEchoService"
                contract="LoadBalancedService.IEchoService" 
                name="CustomBinding_IEchoService">
                <identity>
                    <userPrincipalName value="Administrator@fpdev.com" />
                    <servicePrincipalName value="" />
                    <dns value="192.168.1.220" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Note that on this side, the binding is generated as a netTcpBinding.

And that's it!  Deploy the service to your clustered servers and start the services and then start the client.  If your cluster has a bias towards one server, you will see that the messages will come from that server.  To test that it actually is load balancing, simply stop the service on that server and you should see that the output will be coming from the other server.  Here's an example:

You can see that after I stop the service on FPDEV1 at the third echo message, it flips over to FPDEV2!  Awesome!

Here's the full project (VS2008): WcfLoadBalancingSample.zip (16.89 KB)

# Tuesday, March 10, 2009

The Follies of C# 4.0

Tuesday, March 10, 2009 3:43:12 PM UTC

Nikhil Kothari has been blogging furiously about Visual Studio 2010 and C# 4.0.  One of his posts covering the dynamic programming features in C# 4.0 raised some interesting discussion in the comments.

Some like Francois Ward:

I heavily dislike this. My philosophy has always been "right tool for the right job". There are dynamic languages that are vastly superior to C#, if you want dynamic. C# was meant to be a "pure" language, to do the stuff where you want as much strong typing as possible (also the reason behind Spec#), and as clean as possible.

This defeats that purpose in such a way that only an FxCop rule or code reviews could stop it from ruinning a codebase. If I wanted dynamic, I could do it in IronRuby (once thats fully out), and call the result from C#.

More so: this dynamic feature was mostly meant to help with COM interop, not as a convenience to save a few lines of code... and people are -already- thinking of ways to misuse it... Really, the .NET runtime was made so we could have all the languages we want on it, EXACTLY so we wouldn't need a "one language to rule them all" thing... The best codebases would use C# as the core, IronRuby (or something similar) for places where you need Dynamic, and F# for places where you need functional... there's no need to stick C# everywhere...and thus, there's no need to add this to C#. Its too late now, but at the very least we can make sure its not abused.

And some like poster "HB":

Why such resistance to this? Mandate to your team not to use it if you don't like it.

Every release of every programming language has the same problem. People resist the new features claiming that they will be abused and ruin everything and yet here we are in C# 4.0 and the use of 'var', anonymous <fill in the blank> and other C# 3.0 features haven't destroyed us.

For people that use a lot of Json (like in MVC), this will be especially handy

I tend to agree with Francois Ward.  While I appreciate the changes in C# 2.0 and 3.0 (moreso 2.0 than 3.0), this transition from "C# pure" to "C# bit-o-everything" is a bit disconcerting; it feels like change for the sake of change and it feels like change in the wrong direction.  As a disclaimer, JavaScript is perhaps my favorite programming language - I love how fluid the language is.  But on the other hand, I can also appreciate some of the structural rigidity of statically typed languages like C# in helping to coerce good OOP practices.

As many have made the argument "Well, you don't have to use it!", I'd like to respond from this angle. It's not a matter of whether I or any of us personally use it but rather how your stereotypical RAD developer (still the majority) uses it or rather abuses it.

I personally think that McConnell gets it right in Code Complete:

"The computer doesn't care whether your code is readable. It's better at reading binary machine instructions than it is at reading high-level-language statements. You write readable code because it helps other people to read your code."

"Making code readable is not an optional part of the development process, and favoring write-time convenience over read-time convenience is a false economy. You should go to the effort of writing good code, which you can do once, rather than the effort of reading bad code, which you'd have to do again and again"

In other words, programming in such a way as to reduce your LOC for a particular operation, while increasing the density (amount of logic in a given number of lines, words, or whatever other metric) or complexity of the statement has a negative effect on readability of the code (at least until the practices become standardized and fairly well understood). The problem I foresee with C# 4.0 is that it introduces features which will not be generally understood across the spectrum of developers. Remember: you are never writing code for yourself, you are writing code for your customers, you clients, the people who will maintain the code after your, your peers whom you work with, consultants who may not understand lambdas, and so on. You may have junior developers on your team (or even senior developers on your team) who may not be able to grasp your idea if you entwine your implementation with cool nifty tricks to reduce LOC.

From a practicality perspective -- as much as this sucks, it is always safer to program to the lowest common denominator; assume that you are writing your code for a novice to maintain and your code will be more legible, the structures will be easier to understand, and the comments will be less terse. Use patterns that are simple to understand. Use statements which are easy to read for a novice as a novice may one day be maintaining your code or extending it. For those reasons, I think that this is a mistake...a terrible mistake to satisfy a set of fringe developers who will actually "get" it and use these constructs in the proper manner.

The forward evolution of the C# language, while it does contain some awesome features and looks more and more like native JavaScript with each iteration, continues to confound me with the lack of concern for the general development community. Instead of focusing on constructs and framework extensions which promote design pattern usage, domain models, and good practices, we get extensions and constructs which undercut the effort to increase the development IQ of your average developer

It WILL be abused and then people like myself will have to go in there and try to untangle the intent of developers who misuse these facilities provided to them for all the wrong reasons just as I've seen people abuse System.Linq instead of writing good, performant code.

Microsoft's C# Future page is a good place to start with regards to some of the features coming out for C# 4.0.

# Friday, August 08, 2008

Fatal Execution Engine Failure(0x7927e03e) and WCF

Friday, August 08, 2008 11:48:13 PM UTC

An interesting issue cropped up during development this week.  It centered around a mysterious error that was happening in our web applications and causing IIS to crash...hard. 

Peeking in the event log, I found the following error:

Event Type:	Error
Event Source:	.NET Runtime
Event Category:	None
Event ID:	1023
Date:		8/8/2008
Time:		7:07:28 PM
User:		N/A
Computer:	ZORCH6
Description:
.NET Runtime version 2.0.50727.1433 - Fatal Execution Engine Error (79FFEE24) (80131506)

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

It was mind boggling even more so because the app worked on some environments and not others.  We chased various options around and none of them seemed to solve the issue.  Further confounding the issue was that IE would throw up an authentication dialog instead of outright generating an error on the AJAX call where the error was originating from.  This lead us in circles fiddling with the domain controller and permissions for a while, too.

There was no concrete info anywhere in the system which explained why we were getting this error.  Then I came across a post in the Microsoft Connect site which mentioned this issue.  I wasn't completely sure that this was the same as our issue, since we weren't using IEnumerable<T> in our contracts, but it was a lead.  So I built a small sample project to model our service calls.

It turns out that there's something borked with WCF data contract serialization in IIS when running in Windows 2003 environments.

In our case, we did not have IEnumerable<T> in our contracts (well, not explicitly anyways).  However, we had a few methods which took Collection<T> as an argument.  This worked all fine and dandy when sending a normal collection like so:

Collection<Person> c1 = new Collection<Person>();

Person thuy = new Person("Thuy", "Ha", "UT");

c1.Add(thuy);
client.ProcessPeople(c1);

Collection<Person> c2 = new Collection<Person>();

client.ProcessPeople(c2);

However, using this approach breaks it (I repeat, this does not work):

Person chuck = new Person("Charles", "Chen", "NJ");
Person[] a3 = new Person[1];
a3[0] = chuck;

client.ProcessPeople(new Collection<Person>(a3));

To work around this, you can use an intermediate step like so (of course, this is only necessary if you have data coming from an array to begin with):

Person chuck = new Person("Charles", "Chen", "NJ");
Person[] a3 = new Person[1];
a3[0] = chuck;

List<Person> l3 = new List<Person>();
l3.AddRange(a3);

client.ProcessPeople(new Collection<Person>(l3));

In any case, what further confounded the issue is that it worked in an XP environment but did not work in a server 2003 environment.  Glad to have this issue behind me :-D; hopefully, you won't waste as much time fiddling with this as I did.

# Monday, August 04, 2008

What Working With Python Has Taught Me...

Monday, August 04, 2008 2:25:11 PM UTC

I've been working with Python for the last few weeks on a pet project that I have going on.  I've been using PyDev with Eclipse and using Django as the application framework for this web app.  Part of it is because I'm kind of disillusioned with ASP.NET (Django is very clean, out of the box) and part of it is because it's a challenge and it's been fun to switch gears away from the daily grind.

If there is one lesson I've learned, it's that Microsoft developers are spoiled rotten.  Visual Studio is such an excellent development environment with so much flexibility that it makes it so easy, that perhaps there are more .NET developers than should have a right to call themselves professionals.  Switching to Eclipse has been a revalation in what I've been missing since I've started using Visual Studio and ReSharper.

I know this feeling; it's the same feeling I had when I was in college, writing Java in vi and emacs.  No drag and drop (not that I use this much in VS anyways as I've almost completely sworn off control based ASP.NET development).  No hand holding.  It's a raw and visceral programming experience.  It's hard to explain; it comes out kind of like a knock against Eclipse and PyDev, but a more fitting comparison is like the difference between shooting a semi-automatic rifle and a bolt action rifle; there's just something about the bolt action that makes the experience much more enjoyable.

In truth, it's been very challenging and not at all easy to transition.  At the same time, it's been fun and rewarding.  While I feel less productive with Eclipse at the moment due to the newness of it all, I do feel more productive with Python and the runtime interpreter than C#.

I've come to find that Django, while much, much better than ASP.NET in some respects, lacks a lot of the conveniences and facets that I've come to expect from a modern web framework like a rich and easy to use, out of the box JSON serialization library or pattern (it'll get there some day).  ASP.NET makes this nearly painless while the JSON serializer which ships with Django isn't really suited for working with arbitrary objects (I've been using jsonpickle instead).  PyDev and PyDev Extensions are also no match for ReSharper (I dunno, as a random guess, I would say that R# affords a 30-40% improvement in productivity).

So, that's the story so far.  Perhaps when I have more time, I'll round up some of the resources I've used to ramp up on Python development.

# Monday, June 09, 2008

WCF, Prototype, And Awesome-sauce

Monday, June 09, 2008 8:00:43 PM UTC

One of the most awesome features of WCF in .NET 3.5 is support for REST-style AJAX requests to the services.

Rick Strahl has an excellent post on how to get it up and running with jQuery.

Just some notes on working with it myself which I hope can help clarify some some issues:

  • When using POST and the postBody option with Ajax.Request, the format must be {"argument-name":"value"}.  I struggled with this for a while using single quotes and no quotes.  For example: {arg:'hello'}, {'arg':'hello'}, {arg:"hello"} will all result in 400 "Bad Request" errors.
  • The contentType parameter must be set to "application/json".
  • Be sure to decorate the service contract using the WebInvokeAttribute with ResponseFormat and RequestFormat set to WebMessageFormat.Json.

You can download a sample project from here: WcfAjaxSample.zip (3.83 KB)

# Friday, March 07, 2008

WSS And DateTime Error

Friday, March 07, 2008 5:16:40 PM UTC
In working with the SharePoint web services, I've noticed consistent errors with a few of the services which tend to return the following string:
String was not recognized as a valid DateTime
I hadn't been able to figure out what exactly the error was until today.

It's actually not related to a date/time string at all, but rather, the root of the error is in the service implementation itself.  The actual underlying error is an error indicating that a field value is no longer valid.  For example, if the item had a field referring to a lookup list, changes in the target list may invalidate a value on a given item.  Instead of returning a useful error, the web service returns the error above.

You may find this error when using the lists.asmx service or the dspsts.asmx service.

I "fixed" this by removing the offending field from the content type and also from the list and voila, no more errors.

It's hard to track down because the SharePoint itself will render the properties without any error indication in the view and edit properties view, but it will fail the entire request if one field is invalid and return a useless SOAP error.

# Tuesday, February 26, 2008

SharePoint Layout Pages With CodeBehind And Prototype

Tuesday, February 26, 2008 1:11:26 AM UTC

Let it be known that I hate out of the box ASP.NET.  Hate it, hate it, hate it, hate it.  I detest it.  The simplicity with which it allows the average developer to create applications leads to applications designed for RAD and not for scalability and it does not encourage good decoupling of business logic from UI logic.  Certainly, there are a number of frameworks which aim to alleviate this (the Web Client Software Factory, for example), but I like to take it to another level all together.

Some would argue that I take the separation of UI and application logic to the extreme: my preferred methodology relies almost purely on client side scripts to render UI and using only web services to supply data using ASP.NET AJAX.  Certainly, I lose design time support, but I gain in pure speed (all of the UI logic is in Javascript files which are cached by the client), data transfer sizes (since the only traffic is data, no presentation whatsoever), and the ultimate decoupling of UI development and server component development (the UI developer only needs to know the data model exposed by the web services).

The way I look at it, you'll only write the code a few times, but it could be in use for months (and if you're lucky in this Web 2.0 age, even a year or two).  Sure, you lose some productivity for a single developer with the loss of design time support, but you gain tremendously over time with each request serviced in terms of performance and bytes saved (a particularly important point for high traffic/high data volume applications).  As a bonus, I find it generally easier to think about application design in these terms.

Admittedly, this model seems to work better for "business applications" as opposed to "content applications".

In any case, I was interested to see if this methodology could be applied to SharePoint development as I've been working with SharePoint for quite a while now, but not at the UI level.  SharePoint allows you to deploy "application pages" which can be seemlessly integrated (kind of) into a SharePoint deployment.  This seemed like the perfect starting point to try to integrate ASP.NET AJAX and prototype, one of my favorite Javascript libraries.

The general steps are:

  1. Create an ASP.NET AJAX web application
    1. Add a reference to the Microsoft.SharePoint assembly
    2. Add the prototype.js script file to the project
    3. Add a strong name key file and sign the project
    4. Build a simple page
    5. Create a simple service
  2. Copy the content files (.js, .aspx, .asmx) over to the server to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\ into a new directory.
  3. Test by visiting the URL: http://myserver/_layouts/mynewdirectory/default.aspx

The base page should be simple.  Use the default page created by the ASP.NET AJAX web application project template and change the base class for the _Default.aspx.cs file to LayoutsPageBase instead of of the default of Page.  If you're not using ReSharper ;-), you'll need to add a using statement to your file:

using System;
using Microsoft.SharePoint.WebControls;

namespace WssAjaxApplicationTest {
    public partial class _Default : LayoutsPageBase {
        protected void Page_Load(
            object sender, EventArgs e) {}
    }
}

Next, you will need to modify the Default.aspx file.  The gist of the modifications comes from an MSDN article by Ted Pattison:

<%@ Page Language="C#" 
    AutoEventWireup="true" 
    CodeBehind="Default.aspx.cs" 
    Inherits="WssAjaxApplicationTest._Default" 
    MasterPageFile="~/_layouts/application.master"%>

<asp:Content ID="Main" runat="server" ContentPlaceHolderID="PlaceHolderMain">
    <script type="text/javascript" src="_scr/prototype.js"></script>
    <script type="text/javascript" src="_scr/WssAjaxApplication.js"></script>
    <script type="text/javascript"> 
        var application;
           
        function Init() {
            application = new WssAjaxApplication();
        }
        
        Event.observe(window, "load", Init, false);
    </script>
    <asp:ScriptManager ID="ScriptManager1" runat="server" >
        <Services>
            <asp:ServiceReference Path="~/Services/EchoService.asmx" />
        </Services>
    </asp:ScriptManager>    
    <div>
        <input type="text" id="message-input" />
        <input type="button" id="action-button" value="Go!" />
        <br />
        <div id="message-output"></div>        
    </div>                
</asp:Content>

<asp:Content ID="PageTitle" 
    runat="server" 
    contentplaceholderid="PlaceHolderPageTitle" >
    Echo Page
</asp:Content>

<asp:Content ID="PageTitleInTitleArea" 
    runat="server" 
    contentplaceholderid="PlaceHolderPageTitleInTitleArea" >
    The Echo Page Test
</asp:Content>

I've bolded the key part above, which is linking to the master page for SharePoint layout application pages.  In addition, you can see that I've created three placeholder content sections with the key section being the PlaceHolderMain.  I've placed my Javascript references and my ScriptManager into this section, pointing to our simple service, EchoService.asmx.  Notice the use of the root squiggly "~" :-D and the lack of squiggly on the script references to prototype.js and WssAjaxApplication.js.

The service I'm going to be using for this demo is a simple "echo service" which just echoes the input string with the server timestamp attached.  The following is my simple implementation of this web service:

using System;
using System.ComponentModel;
using System.Web.Script.Services;
using System.Web.Services;

namespace WssAjaxApplicationTest.Services {
    /// <summary>
    /// Summary description for EchoService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    [ScriptService]
    public class EchoService : WebService {
        [WebMethod]
        [ScriptMethod]
        public string Echo(string message) {
            message = string.Format("You said: \"{0}\" at {1}", 
                message, DateTime.Now);

            return message;
        }
    }
}

As you can see by the .aspx page above, I've organized my service in a sub-folder called "Services".  Now just make sure that you've added a copy of prototype.js under the _scr directory and my application script:

WssAjaxApplication = Class.create();

Object.extend(WssAjaxApplication.prototype, {
    initialize:function() {
        this.MessageInput = $("message-input");
        this.ActionButton = $("action-button");
        this.MessageOutput = $("message-output");
        
        Event.observe($('action-button'), "click", 
            this.OnClickActionButton.bindAsEventListener(this), false);
    },
    
    OnClickActionButton:function(e) {
        if(e) { Event.stop(e); } // Stop the event       
        
        // Perform the echo.
        WssAjaxApplicationTest.Services.EchoService.Echo(
            this.MessageInput.value,
            this.OnClickActionButtonSuccess.bindAsEventListener(this),
            this.OnClickActionButtonError.bindAsEventListener(this)
        );          
    },
    
    OnClickActionButtonSuccess:function(result) {
        this.MessageOutput.innerHTML = result;
    },
    
    OnClickActionButtonError:function(error, userContext, methodName) {
        window.alert(methodName + 
            " failed with the message: " + error.get_message());
    }
});

The script simply attachs an event listener to the "Go" button and handles the click event.  Notice how clean and simple the HTML portion of the page is and how clean the Javascript is as well (admittedly, this is a very simple example).  The client rendering is completely decoupled from the UI logic except for the data and operations contract. 

You should be good to go so far as code goes.  Now compile your project with a strong named key file. 

Hopefully, the project was compiled successfully.  The next step is to copy the output dll to the GAC of the SharePoint server.  Be sure to note the public key token value.

This is probably the trickiest part: now you need to carefully merge the configuration files (is there a better tool to do this with?) generated by the project template with the web.config file located at the virtual directory root of your SharePoint application.  For example, if you have an application deployed at port 8080, the web.config file should be located at C:\Inetpub\wwwroot\wss\VirtualDirectories\8080.  Be sure to save a backup copy of the configuration file first before you attempt to merge it!

Once merged, you will need to add one more element to the configuration file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration> 
    <system.web>    
        <compilation batch="false" debug="false">
            <assemblies>
                <add assembly="Microsoft.SharePoint, 
                    Version=12.0.0.0, Culture=neutral, 
                    PublicKeyToken=71e9bce111e9429c" />
                <add assembly="System.Web.Extensions, 
                    Version=1.0.61025.0, Culture=neutral, 
                    PublicKeyToken=31bf3856ad364e35"/>
                <add assembly="WssAjaxApplicationTest,
                    Version=1.0.0.0, Culture=neutral, 
                    PublicKeyToken=97d3f1fd9f5212b9"/>            
            </assemblies>
        </compilation>
    </system.web>
</configuration>

I've highlighted the key line (the line above it should have been merged into the file previously).  The bolded entry above is for the web application binary.

To test whether you've succeeded, you can simply point your browser to the URL: http://myserver/_layouts/mywebapp/default.aspx and you will have a fully AJAX enabled application using ASP.NET AJAX to connect to a .NET web service with prototype as a general purpose Javascript utility library (and you can even add scriptaculous on top of that for more awesome).

I've included a self extracting 7z file of the solution (see link below) if you'd like a quick start.  Note that the Microsoft SharePoint binaries are not included and you will have to add them back manually before the project will build.

Happy coding!

WssAjaxApplicationTest.exe (162.02 KB)
# Sunday, January 13, 2008

Confucius On Programming

Sunday, January 13, 2008 9:18:02 PM UTC

One of the favorite classes that I took in college was an introductory course to Chinese philosophy. 

From time to time, I found one or two passages from The Analects that I could apply to my computer science major.

One of my favorites is passage 13:3:

Tzu-lu said, "The ruler of Wei is waiting for you to serve in his administration.  What will be your first measure?"  Confucius said, "It will certainly be the rectification of names."  Tzu-lu said, "Is that so?  You are wide of the mark.  Why should there be such a rectification?"  Confucius said, "Yu! How uncultivated you are!  With regard to what he does not know, the superior man should maintain an attitude of reserve.  If names are not rectified, then language will not be in accord with truth, then things cannot be accomplished.  If things cannot be accomplished, then ceremonies and music will not flourish...."

"Therefore, the superior man will give only names that can be described in speech and say only what can be carried out in practice."

To me, this applies to software engineering in the naming of classes, methods, properties, variables, and so on.  As McConnell writes in Code Complete,

The smaller part of the job of programming is writing a program so that the computer can read it; the larger part is writing it so that other humans can read it.  let [the reader] use their brain cells to understand the larger question of how your code works rather than the syntactic details of a specific expression.  You write readable code because it helps other people to read your code.

Indeed, sensible naming is a big part of this idea of legibility.  What I dig about Visual Studio 2008 is that the installed documentation includes excerpts from Framework Design Guidelines by Cwalina and Abrams which aims to include some of the key naming and design best practices into the core literature on the .NET Framework.  It's a necessary and needed move to help forward the education of the legion of .NET developers who continue to perpetrate terrible naming practices carried over from VB.

I mean seriously: if I have to read one more method name as a noun (or a property as a verb or a class as a verb), I'll just have to start researching a way to let me reach across the Internet and punch someone in the face -- nothing ruins my morning quite like finding a new class in source control named as a verb.  I'm also midly irritated when developers choose unconventional names for object types.  For example, the use of "Checker" as opposed to "Validator" -- ugh!

Admittedly, some artifacts are just really hard to name.  But in such cases, proper naming is probably even more important since if it's hard for the writer of the code to come up with a proper name, the wrong name will make the artifact even harder to understand for secondary readers.  There have been times where I've spent days trying to come up with a suitable name for a class (I'll name it, but I'll continue to mull it over through restless nights (true story) and refactor it once I do come up with a suitable name) since the last thing I want to do is to give something a cryptic, hard to understand name.

One of the easiest ways around this is to spend some time digging around the SDK and look for similar patterns in naming and see how the .NET framework designers structured their class and member names.  I also think that Cwalina and Abrams' Framework Design Guideline is a stalwart component of any .NET developer's library.

So the next time you're about to write a class name or create a new member, just remember,  "If names are not rectified, then language will not be in accord with truth, then things cannot be accomplished.  If things cannot be accomplished, then ceremonies and music will not flourish". I mean, who doesn't want their project to end with ceremonies and music :-D

# Tuesday, October 09, 2007

How Did I Miss This?!?

Tuesday, October 09, 2007 11:34:55 PM UTC

With the release of .NET 3.5 and Visual Studio 2008, Microsoft will also release selected bits of the .NET Framework source code!  With comments intact no less!kermitdancing_4.gif

To me, this is good news; very good news I mean, there are a variety of reasons, but mostly because I know that most people don't have the time, motivation, or energy to work through a book like Framework Design Guidelines.

My hope is that the Microsoft team, in doing so, will spur a movement within development teams to adopt better programming standards which are more aligned with the Base Class Libraries in naming, design, and architecture.  It should, hopefully, serve as a model to how things should be done in the post VBScript/VB6 days.

I just cringe sometimes when I dig into our codebase and find crazy things like methods not named as verb phrases, partial classes because a single file was getting too big (total abuse of partial classes instead of considering an object oriented approach to break down a large class), weird class names, catch blocks which have no code, and so on.

So for me, this is certainly good news and I hope to continue to form better practices as I get the opportunity to dive into the code.

# Thursday, October 04, 2007

Serializing Inheritance Chains With WCF

Thursday, October 04, 2007 5:42:26 PM UTC

During a recent code review, I noticed that a colleague was sending me service entities from his WCF service with flags for the data type.  This itself wasn't so bothersome to me, but what did bother me was that the model he was sending back was violating one of the basic rules of object oriented programming: encapsulation (well, inheritence and abstraction, too) by mashing all of the data types into one type differentiated by a property.

Having worked extensively with XML serializers and XSD.exe generated code, I suggested that instead of mashing all of the objects into one definition -- with all of the different properties -- build one abstract definition and define a hierarchy of classes that inherit from the abstract class.

This worked out great since the family of objects all had a very obvious common base, but now the question turned to how to notify the runtime serialization engine to include the concrete types when returning abstract types from an operation.

I had imagined that the .NET 3.0 team would have made the process more "automagic" and use reflection to find inheriting classes instead of requiring the explicit declaration of inheriting classes.  As I soon found out, such is not the case as my proxy classes didn't include any of the inheriting classes; the proxy definition only contained the definition for the base class.

The answer is the KnownTypeAttribute which must be used to decorate the class definition of the base class (in my case, an abstract class).  One attribute must be added for each inheriting type which must be serialized across the wire.  For example:

[DataContract]
[KnownType(typeof(Invertebrates))]
[KnownType(typeof(Vertebrates))]
[KnownType(typeof(Mammal))]
[KnownType(typeof(Reptile))]
[KnownType(typeof(Human))]
public abstract class Animal {
	// Base class definition
}

Notice that the entire hierarchy has to be "flattened" and included in the declaration for the root base type. The DataMemberAttribute only has to be applied once on any property in the base class.

# Tuesday, August 21, 2007

Working With SQL Server Compact Edition 2005

Tuesday, August 21, 2007 10:05:02 PM UTC

One interesting issue that I just solved involved how to specify the location of the database file for a SQL Server Compact Edition 2005 connection string in a .Net add-in for Microsoft Office.

You see, when the add-in starts, it sets the context directory as the user's documents directory, which of course, makes it impossible to enter a configuration string for the data source of the connection string.

It works fine if the directory is hard coded - which is what I did for testing purposes initially, but of course, when I switched over to XP64, this broke as on XP64, the program is installed to "Program Files (x86)".

The solution lies buried in Microsoft's SQL CE documentation: there's a note that you should use a special token with the connection string like so:

<connectionStrings>
	<add name="ClientDatabase" 
		connectionString="Data Source=|DataDirectory|\data-file.sdf"
		providerName="Microsoft.SqlServerCe.Client" />
</connectionStrings>

The token needs to be included exactly as entered "|DataDirectory|". So how is this token replaced? In the static constructor of my Connect class that was autogenerated by Visual Studio, I added the following code:

/// <summary>
/// Initializes the logging subsystem for the <see cref="Connect"/> class.
/// </summary>
static Connect() {
	string path = Assembly.GetExecutingAssembly().Location;
	path = path.Substring(0, path.LastIndexOf('\\'));

	// Set the DataDirectory for the SQL Server CE connection string.
	AppDomain domain = AppDomain.CurrentDomain;
	domain.SetData("DataDirectory", path);
}
# Tuesday, August 14, 2007

Normalizing And Denormalizing SharePoint Field Names

Tuesday, August 14, 2007 3:45:29 PM UTC

Frequently, when working with Office, SharePoint, and SharePoint web services, it is necessary to convert between the "normalized" (hex escaped string) version of a field name.

To that end, I found a useful JavaScript tool for normalizing strings into SharePoint's "static name" format.

In .Net, we can simplify this using Regex and Uri.

    private static readonly Regex specialCharactersPattern
        = new Regex("[\\[*($%&)<>!?\\/\"{}\\s+-='@~`#\\\\:;^\\]]", 
            RegexOptions.Compiled);

    private static readonly Regex encodedCharactersPattern
        = new Regex("_x00(\\d{2})_", RegexOptions.Compiled);

    /// <summary>
    /// Normalizes the name of the SharePoint property name.
    /// </summary>
    /// <param name="key">The "human readable" key/property name.</param>
    /// <returns>
    /// The string with hex representation in place of special ASCII
    /// characters.
    /// </returns>
    private static string NormalizeSharePointPropertyName(string key) {
        return specialCharactersPattern.Replace(key, ReplaceSpecialCharacter);
    }

    /// <summary>
    /// Custom match evaluator to replace special characters within the input
    /// string.
    /// </summary>
    /// <param name="match">The pattern match.</param>
    /// <returns>The formatted version of the string.</returns>
    private static string ReplaceSpecialCharacter(Match match) {
        string replacement = string.Format("_x00{0}_",
            Uri.HexEscape(match.Value[0]).TrimStart('%'));

        return replacement;
    }

    /// <summary>
    /// Denormalizes the name of the SharePoint property.
    /// </summary>
    /// <param name="key">The normalized key/property name (static name).</param>
    /// <returns>
    /// The denormalized form of the input string ("human readable"
    /// with hex patterns replaced).
    /// </returns>
    private static string DenormalizeSharePointPropertyName(string key) {
        return encodedCharactersPattern.Replace(key, DecodeSpecialCharacter);
    }

    /// <summary>
    /// Custom match evaluator to replace the hex characters with special characters.
    /// </summary>
    /// <param name="match">The pattern match.</param>
    /// <returns>The ASCII format of the special character encoded in hex.</returns>
    private static string DecodeSpecialCharacter(Match match) {
        int start = 0;

        string replacement =
            Convert.ToString(
                Uri.HexUnescape(Convert.ToString(match.Value[0]), ref start)
            );

        return replacement;
    }

Download the sample console project to test it out.

SharePointNormalizationConsole.zip (4.35 KB)

# Tuesday, July 17, 2007

Tuesday Morning Thoughts

Tuesday, July 17, 2007 2:50:01 PM UTC

Some random stuff and some not so random stuff.

First, the Oral-B CrossAction Vitalizer is possibly the best damn (non-electric) toothbrush ever made.  It's comfy on the gums, it gets to the back teeth, and the handle is just right for control of pressure and angle.  The "soft" bristle isn't very soft at all, but I've found that it doesn't cause any pain or damage to my gums...it's just right.

Second, in reorganizing some of our code, I jumped headfirst into Microsoft's Smart Client Software Factory (SCSF).  While the verdict is far from conclusive, I have to say: I like it.  It implements several ideas I was tossing around in my head for a Windows Forms client but is obviously much, much more well developed and thought out.

I do find it annoying that it is somewhat difficult to visualize the relationships.  That is the one advantage to using an XML based object configuration system as opposed to the attribute based system used by the Composite Application UI Block that SCSF is built on: it's quite easy to wrap your head around the relationships and see how the pieces fit simply by reading the XML.  To be honest, it wouldn't be too terribly difficult to build similar (but certainly much less refined, given the amount of time I have) facilities with Spring utilizing the dependency injection, loosely coupled events, expression evaluation, and other components of Spring.

However, I think that the entire package, including the GAX pieces make this too compelling of a package to pass up.  There is surely a huge learning curve for the framework and library itself, but I think it will be made up for with the gain in development and deployment speed.

It's kind of cool that it also supports WPF modules.  I spent quite some time last night (up until 2 AM) trying to replicate some of the existing UI components that we have into WPF UIs.  I think I'm starting to "get it".  Not in the sense of why XAML is great for UI developers (I've always preferred declarative markup), but in the sense that I've kind of aligned myself with some of principles of XAML (i.e. layout, grids/tables, applying styles, backgrounds, etc. - which are of course slightly different than HTML) and I can now really appreciate how much easier it will be to create snazzy UIs in the future.

cab-hosted-wpf-UI.jpg

While I have Expresison Blend, I found it much more constructive to actually go into the raw XAML and write it by hand (well, not to mention that I find the UI hideous and unusable or perhaps I'm just way too Adobe-ized).  It was quite slow going at first, but once it clicked, it picked up very quickly.

Ultimately, however, I don't think that I can use WPF for our next release.  There seems to be some runtime instability with the current Visual Studio 2005 extensions (the November 2006 CTPs) to support WPF and WCF...I was only able to run my application once last night; subsequently, it would crash immediately.  The problem was only fixed by rebooting my machine.

But in any case, there are some great SCSF resources out there.  I would start from Cabpedia.com as CAB itself is really what presents the challenge in the Smart Client.  Cabpedia has a list of great resources which helped me at least grasp some of the conceptual ideas behind CAB.  In particular, a series of articles by Szymon Kobalczyk.

# Friday, July 06, 2007

WCF Configuration Intellisense

Friday, July 06, 2007 8:06:38 PM UTC

Hmm...I thought it was kind of odd that Visual Studio didn't support intellisense for WCF configuration elements (but then again, I've kind of become intimately familiar with the core elements without having the schema).

Turns out that you have to take care of it manually by updating the schema file for configuration.

Blogger Govind has a post with the necessary file and instructions.

Helps configuration go much more smoothly until Orcas arrives.

I'm surprised that this hasn't been posted across more blogs since it seems like a big, big bonus to have this for developing WCF applications.  Is it common knowledge?  Was there an SP that updated the schema files?  I know that installing .Net 3.0 didn't change the configuration files on my system at least.

# Tuesday, July 03, 2007

Enterprise Library vs. Log4Net

Tuesday, July 03, 2007 9:35:18 PM UTC

If there's one thing that really irks me is allegiance for the sake of allegiance.

Don't get me wrong, I have nothing against Microsoft Enterprise Library and in fact, in absense of any better alternatives, EL is indeed the best option for a whole slew of development tasks and better than rolling one's own solution.  But of course, the question is then: are there better alternatives.

Take logging for example.  There has been a movement in our team to use EL instead of log4net.  In all honesty, it's not a battle that I want to wage...it's simply not worth it for logging, but I think that for anyone considering one or the other, some serious evaluation is in order.  EL logging simply cannot hold a candle to log4net.

As I commented on James Newton Kings' blog:

James,

About 2 years ago, I started to seriously integrate logging into my applications.  During that time, I went through several rounds of testing both log4net and EL and I am currently in a discussion with other developers in my group on whether we should use the best available tool (log4net 1.2.11) or the do it the Microsoft way (EL 3.0/3.1).

In my opinion, the lack of hierarchical loggers is a significant weakness of EL as it requires much more thought and planning to make sure that you can isolate components down the line.  While flexibility is good, I think that having the free form category, priority ID, and event ID make it far more confusing than it has to be...18 overloads?  Do you expect people to remember or use the right category every time?  What about misspellings?  Of course, one could always write a layer to abstract these weaknesses of EL such as add a layer to translate Log.Debug() to some internal EL call, but then you have to ask if you've gained anything in the process.

Aside from this, I'm not sure if you are aware, but log4net utilizes buffered appenders for certain classes of appenders with the ADO.Net appender being one of those.  What does this mean?  I think you will see significant performance increases with buffered appenders (say buffer 250 messages in one flush versus making 250 individual inserts).

In addition, the procedures that are used by EL (although they can certainly be modified) add overhead out of the box.  For example, if WriteLog is called it *always* makes a second call to AddCategory, regardless of whether the category exists).  This is a round trip call from SQL Server to the calling client since there are no triggers on insert to the Log table and there is no call to AddCategory from WriteLog.  In addition, in the scenario that you end up with a category name that isn't in the log (yet another lookup), *another* lookup and insert is performed via InsertCategoryLog.  Since there are FK constraints on the tables, each insert also incurs an additional lookup behind the scenes to validate the foreign key.

Aside from this, I've found that log4net tends to fail gracefully whereas EL...not so much.  For example, if you try to use logging, but fail to include the correct configuration, the exception will bubble up to your application.  On the other hand, log4net will always trap the exception and not let it bubble up to your application and thus not raising an error where you would not expect.  Sure, you could put try-catch around all of your logging statements if you're using EL...but then, you have to ask yourself WHY?

I also forgot to mention that log4net, out of the box, allows loading of configuration files from any XML string (in application code without recompile of the source code).  This means that if one were so inclined, logging configuration would be stored on a central server, downloaded, and loaded on the fly.  If one were so inclined, it could be stored as embedded content with the assembly.  This flexibility allows for a great variety of design scenarios out of the box.

James also has two incorrect interpretations of the facts:

  1. log4net is not being developed actively.  Indeed, there was a looong period of inactivity on the realease side while the log4net project was going through integration with the Apache Software Foundation, but during that whole time, the mailing lists were active and so were the developers in helping users, answering questions, and certainly making todo lists for the release after incubation.  I would also offer the opinion that log4net should have less releases as it is the more mature, tested, and stable of the two libraries.
  2. EL is somehow more extensible than log4net.  This simply insn't true as both provide the source and both provide extensive SDK documentation, samples, and examples.

Commentor Smitha Mangalore also raises an interesting point: log4net supports logging across more platforms than does EL at this point (not to mention supporting more database targets out of the box than EL).

Just my take.  I think both have their place.  For application event logging and tracing, nothing beats log4net in terms of performance, ease of use, ease of configuration (yes, I find the configuration to be much more concise and understandable with log4net), and overall usability.

Update

So my interest was piqued: this whole discussion made me want to check the performance difference for myself.

So here are the test conditions:

  1. Machine:
    1. CPU: E6400 Core 2 Duo (2.13GHz @ 3.2GHz),
    2. Memory 4 GB RAM,
    3. Disk 1: 36GB @ 10,000 RPM
    4. Disk 2: 36GB @ 10,000 RPM
    5. Disk 3: 250GB @ 7200 RPM
    6. Disk 4: 74GB @ 10,000 RPM
  2. Test Scenario:
    1. The database will be dropped each before each test run.
    2. For EL, the default procedures and tables will be used.
    3. For log4net, the sample configuration and table definition will be used.
    4. A Stopwatch instance is created and started before the code enters a loop with 100,000 iterations.  The instance is stopped as soon as it exits the loop and the result is written to the console.
    5. For each pass, different sets of logging commands will be commented out (in retrospect, I should have used conditional compliation symbols).
    6. The only listener/appender is a database listener/appender.
  3. Results:
    1. EL: 138s
    2. log4net w/buffer = 1: 116s
    3. log4net w/buffer = 100: 78s
    4. log4net w/buffer = 250: 76s
    5. log4net w/buffer = 500: 78s
  4. Constant Work Time: 18s

So there you have it: with buffering enabled, log4net is up to nearly 2x as fast as EL.

# Thursday, May 31, 2007

SharePoint SoapServerException When Using Lists Service

Thursday, May 31, 2007 8:19:43 PM UTC

When using the lists service to query the "User Information List" (the SharePoint list where the users and groups is located), you may encounter the exception:

System.Web.Services.Protocols.SoapException:
    Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException'
    was thrown.
  at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(
      SoapClientMessage message,
      WebResponse response,
      Stream responseStream,
      Boolean asyncCall)
  at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(
      String methodName,
      Object[] parameters)
  at ListsDataServiceSample.SharePoint.Lists.Lists.GetList(String listName) in
      F:\Projects\Sandbox\SharePointWebServicesSample\ListsDataServiceSample\
          Web References\SharePoint.Lists\Reference.cs:line 213
  at ListsDataServiceSample.Program.Run() in
      F:\Projects\Sandbox\SharePointWebServicesSample\ListsDataServiceSample\
          Program.cs:line 28

This error will occur if you are not using the "Administrator" account, which of course, is not always ideal, especially if you are writing a client side app.

The solution to fix this is to grant the account permissions on the "User Information List":

And then give the user "Read" permissions on the list:

# Wednesday, May 30, 2007

Correlation Across Workflow Instances

Wednesday, May 30, 2007 7:15:58 PM UTC

One of the problems that I've been working on solving recently centered around correlation in workflows.  In simple terms, where a workflow may produce parallel execution paths, correlation allows the runtime to route events to the right workflow execution path.

In every example that I came across on MSDN and online, the sample cases all assumed intra-workflow correlation as opposed to inter-workflow correlation involving "parent-child" workflow instances.

I posted the initial query - and the solution I used - on this subject over at the MSDN forums:

The trick, as it turns out, is that the CorrelationToken must be initialized in the parent workflow.  To accomplish this in the sample, I made a frivolous call to an InitializeCorrelation method on my service interface using a CallExternalMethodActivity, which was marked with the CorrelationInitializer attribute.  This activity executes right before the InvokeWorkflowActivity.


[Serializable]
public class WorkflowCommunicationServiceArgs : ExternalDataEventArgs {
private string key;

public string Key {
get { return key; }
set { key = value; }
}

public WorkflowCommunicationServiceArgs(Guid instanceId, string key)
:
base(instanceId) {
this.key = key;
}
}

[ExternalDataExchange]
[CorrelationParameter("key")]
public interface IWorkflowCommunicationService {
[CorrelationAlias("key", "e.Key")]
event EventHandler<WorkflowCommunicationServiceArgs> ChildCompleted;

[CorrelationInitializer]
void InitializeCorrelation(string key);

[CorrelationInitializer]
void OnChildCompleted(string key);
}

public class WorkflowCommunicationService : IWorkflowCommunicationService {
#region IWorkflowCommunicationService Members

public event EventHandler<WorkflowCommunicationServiceArgs> ChildCompleted;

public void InitializeCorrelation(string key) {
Console.Out.WriteLine("Key -> [{0}]", key);
}

public void OnChildCompleted(string key) {
MessageBox.Show(string.Format("Completed child; Key = [{0}]", key));

RaiseChildCompletedEvent(key);
}

public void RaiseChildCompletedEvent(string key) {
if (ChildCompleted != null) {
ChildCompleted(
null
,
new WorkflowCommunicationServiceArgs(
new
Guid("5D1667BF-61F6-4bf3-81C0-E70CBE15D2EF"),
key
)
);

}
}

#endregion
}

In essence, the idea is to have two correlation initializers: one utilized by the parent/outer workflow and one utilized by the child/inner workflow when signaling back to the parent.  It seems kind of counterintuitive to require two initializations...I'm still not sure how this is working under the covers, but it works :-)

The working example can be downloaded from: http://www.charliedigital.com/junk/CorrelationTest.Working.zip

# Friday, May 11, 2007

Office Add-In Development "Gotcha"

Friday, May 11, 2007 8:07:18 PM UTC

Because of the nature of how Office add-ins are loaded, it's an easy enough mistake to try to name your configuration file as:

<library-name-with-extension>.config or in my case, <executable-name-with-extension>.config.

In fact, the configuration file actually needs to be named WINWORD.exe.config and it should be located in the same location as the as the Word runtime.  It's kinda of baffling though, since as far as I understand, Word is not a native .Net application. 

Of course, I didn't notice this since the application was designed to run as a standalone executable and as an add-in, so the configuration file worked fine when launched as a standalone, but not so well when launched as an add-in.

# Thursday, April 19, 2007

Enterprise Library 3.0 Released

Thursday, April 19, 2007 6:25:04 PM UTC

I just noticed moments ago that the final release of Enterprise Library 3.0 released recently.

Unfortunately, after a quick glance at the documentation, it seems like ObjectBuilder has been left off the table (link goes to online documentation for ObjectBuilder, which at the time of this post, is "under construction")...again.  I'm gonna have to dig a bit deeper and see if there's more info to be found.

# Sunday, March 25, 2007

Automatic Properties in C# 3.0...Why?

Sunday, March 25, 2007 7:09:52 AM UTC

One of the new features in C# 3.0 makes absolutely no sense to me: automatic properties.

I have two issues with this approach. First, Wouldn't it make more sense to just have VS ask: "Do you want to generate a public property" when a user creates a field (like when VS detects the user adding an event handler)? From the description, it seems like the private field doesn't get generated until compile time, meaning the class writer is working against the public property as well. This seems odd since one of the main scenarios for using public properties and private fields is so that the class writer can manipulate the internal data representation without affecting the external interface. Scott himself mentions:

The benefit of this is that from a type-contract perspective, the class looks exactly like it did with our first (more verbose) implementation above. This means that -- unlike public fields -- I can in the future add validation logic within my property setter implementation without having to change any external component that references my class.

Which leads me to wonder why the developer would not just write the private field declaration and auto-generate the get/set methods instead, a much more logical approach to class design which leads to more legible code.

I can appreciate that it saves space in the code view by omitting otherwise "useless" lines, but don't code regions already accomplish the same thing?

Seems like a pretty useless feature to me that ultimately leads to more abstract code (less readable, in my opinion).

Aside from that, the code usage itself looks suprisingly similar to an abstract class.  From a design standpoint, if it's not clear what the validation logic or some other property masked logic is at the moment, if it's not clear how the internals of the class should function, wouldn't it make sense to program against an abstract class and put the actual logic into concrete classes at a later time when that logic is available?  It seems to me that what the automatic property is saying about the class is that: "I know what my external interface looks like, but I don't know what my internal representation and logic should be", which is one of the reasons we have abstract classes, right?  So that we can substitute the actual representation of the internal logic of the class at any time down the line while maintaining the external interface contract.  I dunno, just seems like a useless and otherwise bad feature to me.

One of the other main features, LINQ, already has me shuddering in anticipation of the nasty code that I'll inevitably have to face down the line.  Can you imagine the horror of code mixed with complex data queries in any application of significance?  For the same reasons that one would put a public property as a facade to a private field, it only makes sense to use a stored procedure, view, or table valued function as a facade to the underlying data (now I could see a case being made for it with a framework that allowed the queries to be loaded and cached dynamically at runtime from external files with a cache refresh callback on file change).

# Thursday, March 22, 2007

NHibernate Or Bust!

Thursday, March 22, 2007 9:23:35 PM UTC

So my interest in NHibernate is picking back up again.  The 1.2 beta release that's circulating now (the candidate release has been out since February of this year) addresses various issues with NHibernate in my previous time with it.

Specifically, the biggest issue was native support for generic types.  In addition, it seems like there are various other goodies in the 1.2 release such as stored procedure support.

And to think, I just got the team to standardize on Microsoft Enterprise Library 3.0.  I'm wondering how to break this to the team.

I guess in a sense, they are not completely incompatible.  Roll your own queries and data access routines are still the way to go for more complex queries (does NHibernate handle FOR XML EXPLICIT?) and anywhere high performance is critical.

The beauty of this whole thing is that as NHibernate has gained traction since the first time I used it like 2 years ago, the tool support has evolved tremendously.  Combined with MyGeneration and user templates, I was up and running (although the generated output had some minor errors in the XML mapping file) in minutes.  Not only has the tool support improved, the documentation has improved as well.

There is still some conflict, internally, as I was just ragging on LINQ last week with another group of developers for the simple fact that it creates a tight coupling between code and the raw data.  Whereas with stored procedures, you can have dedicated DBAs write highly performant code and you can modify the underlying data retrieval and layout so long as you maintain the same resultset, with dynamic queries, you lose a lot of that flexibility.  In addition, you lose a bit of testability as well since many times, it's just really helpful to be able to test the SPROC independently of any code (or perhaps breakdown subqueries in the SPROC to test small subsets of data).

In actuality, I think that having the mappings as XML is probably better than using LINQ since the XML mapping files can be loaded at runtime, meaning that the deployed mappings can still be manually updated whereas LINQ would necessitate a recompile of the source (my understanding of it).

So if you haven't checked out NHibernate for a while, now's a good time to get a refresher and re-evaluate the library.  I think it will still stick around even after LINQ is released.

# Tuesday, March 20, 2007

Combating Namespace Bloat With .Net XML Serialization

Tuesday, March 20, 2007 2:37:00 PM UTC

Anyone who has used the .Net XmlSerializers have surely encountered the dreaded namespace bloat which makes the serialized objects grow to ridiculous sizes.

There's a nice little article over at TopXML on how to deal with this bloat.

If you're using WSCF, on the client stub, I've gotten into the habit of writing custom serialization overrides in partial classes which ensure that if the client needs to serialize objects into XML, I'm doing so in an efficient manner.  It'd be nice to see it added to the server side class constructors as well.  Add your vote for this feature over at the WSCF dicussion boards.

# Wednesday, February 28, 2007

WF Passivation Services Issues

Wednesday, February 28, 2007 11:16:29 PM UTC

If you're expecting the WF (Windows Workflow) passivation services to work out of the box, well, you're half right. 

From one of my workflows, I've been able to trap that an error was being thrown at some point during execution, but it wasn't clear what the actual error was or what was causing it.  I knew it had to do with passivation services since everything was just fine and dandy once I removed the passivation services from the equation.

From the runtime level, I received the following not-so-helpful error message:

System.InvalidOperationException: Workflow with id "[some-guid]" not found in state persistence store.

Just on a whim, I attached SQL Server Profiler to the database instance where the persistence store is attached to track the queries and lo-and-behold, the mystery culprit surfaced:

declare @p10 int
set @p10=0
declare @p11 uniqueidentifier
set @p11=NULL
exec InsertInstanceState @uidInstanceID='2686AB8F-35A4-49C3-AED8-9F239D00D3AC',@state=0x,@status=3,@unlocked=1,@blocked=0,@info=N'Type
''Zorch.Alta.EastCastle.Workflows.DataProviders.Implementation.MockStepProvider'' in Assembly ''Zorch.Alta.EastCastle.Workflows, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null'' is not marked as serializable. Type ''Zorch.Alta.EastCastle.Workflows.DataProviders.Implementation.MockStepProvider'' in
Assembly ''Zorch.Alta.EastCastle.Workflows, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'' is not marked as serializable.',@ownedUntil=''9999-12-31
23:59:59:997'',@ownerID=default,@nextTimer=''9999-12-31 23:59:59:997'',@result=@p10 output,@currentOwnerID=@p11 output
select @p10, @p11

Well, yeah, duh!  It seems so obvious after the fact.  So the moral of the story is to make sure that all of your classes are marked with serializable :P I'm just not sure why they decided to place the error message in the procedure call to insert the instance state.  Why not actually raise an error to the workflow runtime that a class was not serializable?

# Monday, February 19, 2007

Setting Links in Word Programmatically

Monday, February 19, 2007 6:58:10 PM UTC

Since I didn't find anything on this topic via Google...

Just a quick "how to" on setting links in Microsoft Word programmatically (in this case, C#):

public void CheckRuntime() {
    object reference = null;

    try {
        reference = Marshal.GetActiveObject("Word.Application");
    }
    catch (COMException) {
        System.Console.Out.WriteLine("No instances found...");
    }

    if (reference != null) {
        try {
            System.Console.Out.WriteLine("Found running instance!");

            ApplicationClass wordRuntime = (ApplicationClass)reference;

            System.Text.StringBuilder buffer = new StringBuilder();
            foreach (Document document in wordRuntime.Documents) {
                buffer.AppendFormat("{0}|", document.Name);

                if (wordRuntime.Selection != null) {
                    System.Console.Out.WriteLine("Selected text: \"{0}\"",
                        wordRuntime.Selection.Text);

                    object optional = Missing.Value;
                    object url = "http://www.google.com/";

                    if(wordRuntime.Selection.Hyperlinks.Count == 0) {
                        wordRuntime.Selection.Hyperlinks._Add(
                            wordRuntime.Selection.Range,
                            ref url,
                            ref optional
                        );
                    }
                }
            }

            System.Console.Out.WriteLine(
                string.Format("Currently open documents are: {0}",
                buffer.ToString().Trim('|'))
            );
        }
        finally {
            Marshal.ReleaseComObject(reference);
        }
    }
}

The code is wrapped in a function call I'm using for testing. The key part of this is detecting the currently selected text and using the ApplicationClass.Selection and then invoking _Add. The method takes three parameters. Make sure that your first parameter is a Range class instance, your second parameter is passed by reference, and your third parameter (the SubAddress) is set to System.Reflection.Missing.Value.

This should set the text point to any input URL.

# Thursday, February 08, 2007

Revisiting Spring.Net

Thursday, February 08, 2007 4:25:51 PM UTC

Spring.Net is an application framework which has its roots in the Spring Framework for Java.

Now first of all, I know many developers have an averse reaction to the use of the phrase "application framework" and immediately reject such things without second consideration.  I always hear tales that begin like so: "Well, on this one project, we used an application framework and it ended up not doing anything exactly the way we wanted and we had to modify it anyways..."

Four thoughts on this:

  1. No two applications are exactly alike.  If that were so, we'd all be out of jobs as software engineers because it'd probably have already been done before.  As well, no two application frameworks are alike (although on some level, Spring is interchangeable with Castle).
  2. Spring, I have found, does not restrict me in anyway in terms of my solution design.  If anything, it frees me to use more flexible designs and allows me to create much cleaner and better designs.  Inversion of Control is your friend.
  3. Spring includes the source.  Dude, if it doesn't do exactly what you want it to, you are 100% free to modify and reuse it (and maybe even resubmit it to the project if it's well written and useful).
  4. The documentation and development team on Spring (and Castle to a lesser degree) are great.  The documentation is very thorough and well organized and the developers are constantly monitoring the discussion forums and reaching out to users.  Many times, with any sort of large library, you may be under the impression that it doesn't do something (thus leading you to believe that you have to write it anyways and believing that it was pointless to use the framework), but it may actually be the case that you simply haven't found the facilities in the library to accomplish your task.

On top of this, the support forums and developers working on the framework are great resources for hashing out design ideas (outside of one's normal circle of peers).

Yes, it's true, Spring requires the use of what can become massive XML configuration file(s).  Yes, it can be difficult for first timers to grasp inversion of control, understand what exactly it is that Spring offers, and in general, find anything in Spring that would significantly make one's life easier as a developer without a learning curve.  Yes, Spring is huge; it encapsulates a lot of "stuff" that can be confusing and seem like bloat one's first time encountering it (I myself only ever use a small subset of the features of Spring).

However, in the end, I think Spring brings so much to the table (too much for me to list here), it's hard to discount it without at least giving it a real evaluation.  For any sort of non-trivial application, Spring allows the designer to add much more flexibility and decrease the complexity of the codebase by encapsulating a lot of the dirty work.  (I would agree that there is a complexity cutoff where if your application sits below this cutoff, it's simply not worth it to include Spring in the discussion, as the time it takes to understand and find its usages in your scenario would not be worth it).

I've been using Spring for almost a year now and I simply can't imagine writing an application without it.  With the latest release, the introduction of the data access library, Spring becomes even more compelling by removing a lot of the boilerplate code that one would write when performing data access.  Admittedly, in a sense, it is a replacement of one set of boilderplate code for another, but it is a much more elegant design than using raw ADO or even Enterprise Library for that matter.  Spring introduces the usage of a delegate/callback pattern for "rendering" the returned data rows and sets into domain objects and sets.

I use the term rendering because this is the same exact pattern that I've been using with regards to the JavaScript that I've been writing for my AJAX enabled applications.  It's an elegant pattern that, in JavaScript, allows for decoupling of the code to retrieve that data from a web service and the code that renders the data.  In a sense, Spring does the same, except, instead of rendering a UI, it renders a domain object (or set) using the delegate, which decouples the data access plumbing from the building of the domain object.

Having used NHibernate previously, I have to say that in many cases, I still prefer performing my own data access code and domain object rendering as it allows me much more flexibility and control.  There is less processing overhead and not to mention (when I last checked) NHibernate still does not natively support generic types.

I've mostly been sticking with Enterprise Library, which is basically just a step above raw ADO, but I'm gonna give this a shot since it's yet another step or two above Enterprise Library.

On another note, it seems like Microsoft's Patterns and Practices Group is finally releasing the next version of Enterprise Library.  In a sense, EL is a "necessary evil".  As far as 2.0 goes, I cannot say that it does anything particularly better than other libraries that fill the same purpose as any given block, but what it does do is it encapsulates multiple functional spaces (logging, data access, exception handling, configuration) into one.  In addition, having the Microsoft Seal of Approval also helps with acceptance.  As an example, the rolling flat file trace listener has had a counter part in log4net since I've been using it (over 1.5 years now).  The data access application block, while it does clean up data access code, is still pretty close to raw ADO.Net usage patterns; in other words, it brings almost nothing to the table (almost; I still endorse it over raw ADO.Net to be sure).

It'll be interesting to see what this Object Policy Application Block actually does.  It seems like it's conceptually similar to Spring's IApplicationContext or Castle's Windsor Container.  I'm not one to latch onto a product simply because it's from Microsoft's P&PG, so I'm hoping they can actually bring something new to the table to make their library more compelling than Spring or Castle (both of which are much more mature by now and encapsulate a far greater set of features).

As for the any concern over the longevity of Spring and Castle, I feel pretty confident that what happened to NDoc, will not be happening to Spring or Castle.

# Friday, February 02, 2007

Most Annoying Error Ever.

Friday, February 02, 2007 3:06:12 PM UTC

So I've been working on this Windows Forms app for the past month and recently, it started developing this very odd error that occurs only after a successful build, just as I fire up the window.  Behold:

Super annoying error that makes no sense...

Argh!  What's worse is that it pops up not once, not twice, but three times each time I show the form with that super annoying Windows XP "Critical Stop" sound clip each time.  BUT it only happens if I launch the form from VS! These things...they infuriate me because it's virtually impossible to track down.  Throw me a bone, Microsoft, at least tell me what line it's on (which brings me to another point: NullReferenceException - at least when deployed in debug mode, can't you guys just tell me what reference was null?).

I mean, it would be easy if it said something like "Unable to cast object of type 'X' to type 'Y'" - that would make perfect sense, duh! - but this is just baffling.  It's not like I'm getting complier errors either.  I dunno...I just can't figure out why it would only throw up this modal dialog only when I launch the app (without debugging) from VS.

:: grumble :: grumble ::

# Thursday, February 01, 2007

My Thoughts on WF

Thursday, February 01, 2007 1:03:25 AM UTC

As I commented in a post on Paul Andrew's blog regarding what WF is and what it is not:

As I've been working with WF these last few weeks, I've come to form another view of WF and what it means for developers: in a way, it *forces* developers away from some bad design practices since a WF itself has no GUI and no visual user interface. 

To expand on that, it forces developers who would otherwise readily hash their ASP.Net and WinForms GUI code in with the business logic to think in  a manner that separates the core business logic from the visual interface code.

The number of developers that still write monolithic projects that contain the UI and business logic is still all too high.  In studying from simplified working examples in text books, in MSDN documentation, and various articles one finds online, many developers do not gain a good understanding of how to separate the concerns of their code.

The downsides of this approach are immediately apparent after a little exposure to alternative design methods, yet for many developers, they simply don't see the light and continue to write their data access code right into the Click event of a Button.

I see WF as a way of moving developers away from this model by encouraging developers to encapsulate code in a WF program (a unit of business logic) or an activity

I would like to add to that, that in the end, WF is still "just code" (maybe my perspective is skewed after having written my own workflow engine). Don't be fooled by the drag and drop UI, the fancy terms (for example, tracking is nothing more than glorified logging that any learned developer could have easily implemented with log4net, a database appender, and a well defined logging policy), and the hype train in general.  When it comes down to it, for any significantly complex application or architecture, it still requires writing of much of the same code that you had to write before (and in some cases, you may end up writing more code to build a functionally equivalent solution) not to mention that whenever you adopt such a framework, you must learn the little nuiances and how the product architects intended for you to complete a certain task within the guidelines of the framework.

Just to share my take on it :-)

Certainly, it is no "silver bullet", as Brooks would say, but it's definitely a step in the right direction. I am quite curious as to the actual adoption rate that we will see with WF in the coming months as it offers no immediate benefit (until perhaps we see a market for custom activities much like we have today for custom controls for the UI).  To most, it simply won't offer anything compelling and to top it off, it will require additional training to implement a solution using WF.

For me, personally, it's been fun picking it apart and seeing how the minds at Microsoft implemented the same functionality I implemented in my own workflow engine that I wrote for our project at Zorch (while certainly less polished, I like to think I was heading in the same direction...and in some cases, I wish WF offered the same features as I had implemented myself (that was my ego speaking ;-))).

# Sunday, January 07, 2007

A Note On Copying Files In WSS3

Sunday, January 07, 2007 7:52:33 PM UTC

I dunno if this was supported in WSS2 or not, but in WSS3, when a file is copied to a new destination, a link is stored which indicates where the new document is copied from.

In the database, you can see this by running the query:

SELECT
    tp_dirname,
    tp_leafname,
    tp_copysource,
    tp_hascopydestinations,
    tp_guid,
    *
FROM ALLUSERDATA

The tp_CopySource column holds the URL of the source document from which the given file is copied from.  If you simply change the URL here, you can point it to any file you want.  If the file is a copy, then the following information bar will be displayed on top of the file properties in the properties page:

copy-indicator.jpg

However, it's not so obvious how to do this programmtically.  First, I tried using the CopyTo() method of SPFile.  Aside from not having the desired effect, this method does not seem to allow copying files across site boundaries (for example, from a root site to a document workspace -- for that, you have to use the Add() method on the Files property of the target SPWeb).

On my second attempt, I tried to set the "Copy Source" property of the file.

foreach (object key in file.Properties.Keys) {
    Console.Out.WriteLine("{0} : {1}", key, file.Properties[key]);
}

Iterating through the properties of an SPFile instance, I found that one of the properties, was "Copy Source" (internal name of "_CopySource") and in fact, held the URL of the source document.  I tried to set this value and update the file, but this was unsuccessful yet again.

On my third attempt, I came across the CopyTo() method on the SPListItem class and this did it for me :-) Conveniently, it also allows you to copy an item across site boundaries.

I felt so stupid afterwards because it should have been obvious that I had to use the CopyTo() method on the SPItem because the SPItem is also where the UnlinkFromCopySource() method is located.

# Monday, October 16, 2006

.Net On The Up And Up

Monday, October 16, 2006 4:26:12 AM UTC

I guess it's kind of like rooting for the home team.  I don't really know how it came about, though.  I started programming back in high school starting from BASIC to C and eventually, at the college level, I worked with Java for 4 years.  It's a wonder that I'd end up--and I'll admit it--in the Microsoft camp.

It seems like many Fortune 1000 companies are catching the same bug:

A recent survey of the Fortune 1000 websites by Port80 Software shows that Microsoft's Internet Information Services (IIS) usage has doubled over the last year as it is being used by 54.9 percent of companies. In contrast, Apache usage has dropped to 23.3 percent placing it 4 percentage points lower than IIS6 alone. While the results could very well be accurate, it should be noted that Port80 Software has a bias toward Microsoft as it is one of their partners, not to mention the company specializes in developing tools and solutions for IIS.

I think C#, in particular, is making converts at the grass roots level; it's an efficient and well designed general purpose programming language that, in my opinion, trumps Java.  I think C# 3.0 (not to be confused with the oddly named .Net Framework 3.0) will once again up the ante and bring a whole host of new language features to C# (and to other MSIL languages, I suppose) that show once again why Java is becoming...archaic.

I will admit, though, one of the biggest knocks against the MS development direction is valid: they've really dumbed down development for the masses.  They've made the platform so accessible that it's kind of lowered the standards of what passes as a .Net developer.

A rant for another day, I suppose ;-)

# Monday, September 18, 2006

Workflow and SharePoint

Monday, September 18, 2006 7:01:58 PM UTC

Good stuff.  Good freaking stuff.

If you haven't done so already, there's an excellent high level white paper by David Chappell that you should download (if you work with such things like Office and SharePoint) which provides important information so far as system architecture is concerned with regards to integrating workflow and Office.

(Via Paul Andrew).

Small footnote: it's been a year since this blog has been up! :-)

# Wednesday, July 26, 2006

NDoc 2 is Officially Dead

Wednesday, July 26, 2006 6:29:36 PM UTC

So this afternoon, I received an email from Kevin Downs (as I'm on his mailing list), the developer of NDoc with the following:

I have decided to discontinue work on NDoc 2.0 and no longer participate in any open-source development work.

The development and release of NDoc 1.3 was a huge amount of work, and by all accounts widely appreciated. Unfortunately, despite the almost ubiquitous use of NDoc, there has been no support for the project from the .Net developer community either financially or by development contributions. Since 1.3 was released, there have been the grand total of eleven donations to the project. In fact, were it not for Oleg Tkachenko’s kind donation of a MS MVP MSDN subscription, I would not even have a copy of VS2005 to work with!

To put this into perspective, if only roughly 1-in-10 of the those who downloaded NDoc had donated the minimum allowable amount of $5 then I could have worked on NDoc 2.0 full-time and it could have been released months ago! Now, I am not suggesting that this should have occurred, or that anyone owes me anything for the work I have done, rather I am trying to demonstrate that if the community values open-source projects then it should do *something* to support them. MS has for years acknowledged community contributions via the MVP program but there is absolutely no support for community projects.

Once ‘Sandcastle’ is released, it is my belief that it will become the de-facto standard and that NDoc will slowly become a stagnant side-water. This will happen regardless of technical considerations, even if Sandcastle were to be less feature-complete. It's just an inevitable result of MS's 'not-invented-here' mentality, one only has to look at Nant and NUnit to see the effects of MS 'competition'.

This is not, however, my only reason for stopping development work - I have a big enough ego to think I could still produce a better product than them :-)

As some of you are aware, there are some in the community who believe that a .Net 2.0 compatible release was theirs by-right and that I should be moving faster – despite the fact that I am but one man working in his spare time...

This came to head in the last week; I have been subjected to an automated mail-bomb attack on both my public mail addresses and the ndoc2 mailing list address. These mails have been extremely offensive and resulted in my ISP temporarily suspending my account because of the traffic volume. This incident has been reported to the local authorities, although I am highly doubtful they will be able to do anything about it.

This has was the ‘last-straw’ and has convinced me that I should withdraw from the community; I’m not prepared to have myself and my family threatened by some lunatic!

Kevin

P.S. If anyone wants to take over as admin on the SourceForge NDoc project - contact me. If not, I'll be removing myself in 14 days.

It's kind of upsetting how this has panned out as I can certainly understand Kevin's displeasure at how he was treated by a few members of the community.  But at the same time, I'm curious as to why the project, while surely utilized by many .Net developers world wide, never picked up more developers to help share the load.

While it is quite disappointing as I really liked NDoc's simplicity and ease of use, I had felt that this would be the likely end once I started reading about Microsoft's Sandcastle project.

As for the individual(s) who perpetrated the email bombs, all I can say is WTF?  That's a terrible and childish way to get what you want.

# Thursday, July 06, 2006

Big Changes Around the Corner

Thursday, July 06, 2006 6:59:39 PM UTC

C# 2.0 has barely been with us and already, the 3.0 spec is shaping up.  While the change from 1.0 to 2.0 was dramatic in the way that it simplified what used to be quite laborious tasks in C#, the change to 3.0 is perhaps too bold of a jump, bringing the C# language close to the territory usually reserved to academia and research divisions.

Perhaps at the heart of this is the introduction of LINQ (Language INtegrated Query) to the C# specification.  Several changes and additions to the C# language were necessary to make this possible and make it "user friendly".  One of these is the introduction of Lambda Expressions to the C# language, giving C# a feel closer to that of....JavaScript.  Yup, good ol' JavaScript (one of my favorate languages).

Daniel Cazzulino touches upon some of the interesting "side effects" of this change in the language while Abhinaba believes that while the new language features are certainly welcome and useful to a set of users, for most, it will only add to the "surface area" of the C# language and frustrate/confuse users.

C# has originally developed from C++ /Java and is (was :^) ) a strongly typed object-oriented language. The new features being introduced like closure, continuation (yes, yes very limited continuation) in C#2.0 and now type inference, lambda expressions are de-generating the language. Even though there are people go gaga about continuation and lexical closures these are fundamentally functional language features and should be left to that. Introduction of bits and pieces of functional language features are not going to add value to C# and at the same time the surface area of C# is growing beyond what most developer can grasp.

I tend to agree with this view.  Having spent most of my career as a consultant and dealing with many developers who did not come from a math, engineering, or computer science background, I can say with 50.01% accuracy that 87.96% of .Net developers will a) be confused and befuddled by the new language features, b) never use the features and never even know that they are there, or c) change professions :P

Okay, maybe option c is more of a pipe dream.  But regardless, the surface area of C# is becoming quite large and perhaps even a bit, how shall I put it, unwieldy?  Whereas developers used to have disagreements over implementation and architecture details, will we now see disagreement over language feature usage and constructs?  One thing is for sure, I'm certain that a lot of developers will be left in the dust.

Most of the mid-career Microsoft developers I've met got their start doing VB6 and VBScript with ASP.  In the transition to .Net, I've discovered that many have not really transitioned so much as adapted; kind of like they're still writing VBScript...except it's called VB.Net now.  This isn't the territory of VB developers only, however; I've met many C# developers who just have no clue and continue to do silly things like concatenating huge (I mean HUGE) strings.

Well, in any case, enough ranting I guess.  If you're interested, take a look at the language specs over at MSDN (already got 'em printed and stapled).

# Monday, May 08, 2006

Started Working with the NDoc 2 Alpha Build...

Monday, May 08, 2006 9:17:06 PM UTC

Just started.

Turns out that it requires "HTML Help 2 Compiler" or "VSHIK".

Having used the previous version of NDoc, I first turned to my VS2005 install CD to see if the help utilities were included but not installed by default (but I swear I looked through that thing when I installed it specifically for help utilities).

Not there :-S

Googling led me to this sie: http://www.helpware.net/mshelp2/h20.htm, which has info on how to obtain VSHIK and how to set it up.  The site also has a good primer on MSHelp2.

Will report on how NDoc 2 is coming along...

Update: First run looks good.  The HxS output format is still a bit confusing to me...will have to dig into that.

# Saturday, May 06, 2006

I've Done It....

Saturday, May 06, 2006 6:16:55 AM UTC

I was tired of working with tools that used XmlSchemaImporter and XmlCodeExporter (XSD.exe and WSCF) to generate code from XSD files.  I'm sure I'm not the only one, as there are other developers that are awaiting a .Net 2.0 version of the tool as well.

Unfortunately, the execellent XsdObjectGen.exe tool hasn't been updated to take advantage of .Net 2.0 features like generics and partial classes (the most significant change).

After looking at Dingo a bit (already open source and using a templating method as well) and searching for other options, I came to the conclusion that the only sensible thing to do would be to fix the codebase for XsdObjectGen.exe and rewrite the code generation logic.  Dingo was a bit too dense for its own good and there really weren't any other alternatives that I could find.

Took me about 45 minutes to get it up and running with generic lists.  I emailed Dan Rogers to see if it would be acceptable to post this code and/or the compiled binaries and executable (same exact command line parameters).  I know that the generated code refers to an EULA.doc, but I checked the installation directory and found no such document.  So we'll see how that turns out...

# Wednesday, May 03, 2006

Enterprise Library 2.0 Logging Quirks

Wednesday, May 03, 2006 10:35:51 PM UTC

So I've been working with Enterprise Library 2.0 (EL2) Logging Application Block recently and I've come across some quirks that are puzzling me.

First, I've been using log4net for most of my logging in the past.  Recently, I've taken a look at NLog due to the fact that log4net is currently under "incubation" and has been inactive for a loooong time.  The developers are still active as shown by the activity in the the mailing lists, but otherwise, the codebase has been kinda sitting there for quite some time (until recently) with no date on when it'll exit incubation.

Anyways, after checking out some performance numbers on EL2 vs. log4net, I was sold.  Easy configuration via the configuration GUI, easy to understand, tons of documentation, and it's first party Microsoft (easy to get team members and managers to buy into it).

So here I am working with it today and setting up my test code to automatically regenerate the database before each run and my application code crashes when the logging fails (exception).  I had mis-typed the path for one of my SQL files and the database wasn't created for the logging block, but still, I don't think that the right thing for EL2 to do is to allow that logging error to bubble up to the application code.  With log4net, if the connection to the log database is broken, the AdoNetAppender will simply fail but not cause the rest of the application code to fail. [Update: can't reproduce it, but I know this is what cause the error since as soon as the database was there, it was happy, but it's running fine now even without a database. Ugh, totally puzzling...]

Weird design choice.  I guess it's useful to know that your logging block is failing.  But what the heck, isn't that why there are multiple listeners so that if one fails, you have a fallback (i.e. log all critical errors to database, event log, and flat file)?

Secondly, as I'm looking at the database scripts for creating the procedures and database tables for logging included with the EL2 source code, I'm puzzled by the design choice.

Take a look at the code for adding a category:

First of all, why are the categories stored in a seperate table?  My guess is that the designers wanted to save some space in the log entry row by taking out the category from the log entry???  I can't seem to come up with another good reason for it since it's not like the categories in the category table are associated with an application identifier (and they must all be unique category names).  Profiler tells me that it requires at least 14 reads to write one entry into the log.

Not only that, the code to execute adding the category and adding the log entry are two seperate calls from the client since the WriteLog procedure doesn't receive category information.  I'm going to go out on a limb and say that the only reason that EL2 logging is able to outperform log4net is due to .Net 2.0 related optimizations.

So I think it's back to log4net for me.  I don't know how the rest of the team will take it, but it seems to be a better choice.

# Thursday, April 20, 2006

Random DevTools Entry: #010

Thursday, April 20, 2006 5:15:27 PM UTC

Today's entry is Windows Installer XML (WiX for short), an open source project (the first?) from Microsoft that is used internally by Microsoft development teams for building installers for many of their products.

I first used it more than a year ago when I was at Merrill Lynch.  I had to build an installer for a Windows Serivce and I wanted the service to auto-start after installation.  I was totally baffled by how to do this in the VS installer projects (is it even possible?) and somehow ended up stumbling across WiX.  It worked great :-) It was a little rough going because there was so little documentation and Net knowledge regarding usage.

Since then, I haven't really had a reason to look beyond the built in VS installer projects, but I'm working on another complex installer scenario now and decided to check in on WiX again.  To my surprise, there still doesn't seem to exist a UI to design WiX installation packages (at least none that I came across via googling).

However, I did find a very well done tutorial.

Of course, Rob Mensching's blog is full of news and developments on WiX.

Rob mentions in his first post on the subject of WiX that:

Internally, teams such as Office, SQL Server, BizTalk, Virtual PC, Instant Messenger, several msn.com properties, and many others use WiX to build their MSI and MSM files today.  When someone encounters a bug, the community tracks the issue down and fixes it.  Now, via SourceForge.net, you have an opportunity to be a part of the community as well.

I guess it's also good to note that WiX just celebrated it's 2-year OSS status recently.

# Thursday, April 13, 2006

Random DevTools Entry: #009

Thursday, April 13, 2006 2:39:31 PM UTC

Oh yeah, we're kicking it up with the DevTool entries.

That's typically what happens as I ramp up on a project; I'll end up coming across a whole slew of awesome tools that I end up aggregating in my C:\Program Files directory (my application menu is about to go past the second page...I had to uninstall a lot of stuff previously to get it back down to two pages).

Today's entries are tools to help you think "contract first".  I hadn't really thought of XsdObjectGen.exe as a tool that helped you work in a contract first fashion, but Peter Bromberg seems to think so and so does David Truxall.

Unfortunately, XsdObjectGen.exe, as great as it was, is ill suited for .Net 2.0 and the introduction of generic types and lists.  I briefly contemplated using it for my .Net 2.0 project that I'm on now, but couldn't bring myself to it; there must be a better way, right?  Well, up until now, the only other .Net solution that I had come across was Matias Wozloski's GAT implementation (with slight modification?) of Daniel Cazzulino's (kzu) version of XsdObjectGen.  Having looked at that and the new xsd.exe that ships with VS2005, I have to say that I'm sorely disappointed in both since they rely on the XmlSchemaImporter and XmlCodeExporter classes to do their dirty work.  The resultant markup is not nearly as nice as the output from XsdObjectGen.exe.  As I've mentioned in the past (see the end of my workshop on XsdObjectGen.exe), while kzu's implementation is obviously much more flexibile since you can create new extensions and what not, it is ultimately somewhat clunky and not as easy to work with.

I briefly contemplated extracting the source from XsdObjectGen.exe and rewriting the codebase (it uses sort of an "intelligent templating" approach) to utilize some of the .Net 2.0 code features and generate better code, but after digging through it with Reflector, I realized I didn't have enough time (and I probably didn't have the rights) to extract and rewrite the codebase.

Enter dingo and thinktecture's WSCF.  While dingo is still strictly a .Net 1.1 tool, the project leader has a recent news item that claims forward development will continue this summer after some more work on a rules engine (anyone know of .Net APIs for working with RuleML?).  WSCF, on the other hand, looks like it's good to go with respect to .Net 2.0.

So have a look at WSCF.  I'll be downloading and evaluating it today and keep this updated with my take on it.

Update: See comments.

# Wednesday, April 12, 2006

Random DevTools Entry: #008

Wednesday, April 12, 2006 1:44:00 AM UTC

I installed an updated version of the NUnit VS add-in (aka: TestDriven.Net) today and discovered this little tool called NCoverExplorer.  Curious, I started to dig into it and that lead me to NCover.  NCoverExplorer is a GUI interface to NCover output files. 

What is NCover?  It generates code coverage information when it runs your NUnit tests so that you can see how much of your code base your tests are really touching (I perfer the output from Cenqua's Clover.Net, but I guess that's just a matter of using a better XSL transform?).

Both are great tools and should work their way into your development cycle!

It helps to have a simple batch file to run it:

"C:\Program Files\NCover\NCover.Console" "C:\Program Files\NUnit-Net-2.0 2.2.7\bin\nunit-console.exe" "..\bin\debug\SomeProject.Tests.dll"

PAUSE

In an automated environment, you'll want to take out the PAUSE.  It's only there so that if you're running it manually, you can watch the result of the run.

# Monday, April 10, 2006

ObjectBuilder and Dependency Injection

Monday, April 10, 2006 9:12:37 PM UTC

Man, this thing is dense.

I was able to get a very snazzy sample up and running with Castle.Windsor in under an hour, but it'll take quite a bit of time to get the same demo working with ObjectBuilder.  Admittedly, the PAG team states that it wasn't designed for prime time (yet), but what I would be interested in is seeing Microsoft integrate some open source projects into their own OSS projects.  Why reinvent the wheel? 

From my brief review of ObjectBuilder, it seems like it requires way too much work to use at this point.  It uses a mixture of configuration and compile time attributes to make the magic happen.  Why not have the option of doing it all in the configuration file?  It seems to require a lot of custom code to utilize ObjectBuilder whereas the Windsor container requires almost no custom code for wiring; it can be done in one line of code.

On a tangent, I found out that contrary to lack of activity on NDoc, a 2.0 version is in the works and has been mostly underground due to the fact that it's, from what I gather, a complete rewrite.  I tracked down a post by Kevin Downs, the project leader for NDoc over at Fabrice Marguerie's blog dated 2/23/2006:

Originally I had planned to do a simple upgrade of NDoc 1.3, but this proved almost impossible. NDoc2 is, to all intents and purposes, a complete rewrite (a huge undertaking) and has taken far longer than I originally anticipated due to illness. I was forced to 'go dark' on this development because I was getting some fairly offensive emails *demanding* a new release, and I could not give a firm time-line due to the above mentioned illness.

So if you're interested in being a tester, track down Kevin and get on the mailing list.

# Saturday, April 01, 2006

So I've Started the Journey...

Saturday, April 01, 2006 6:05:12 AM UTC

A journey of a thousand miles begins with a single step.

Man, I can remember just a few months ago when NHibernate had almost no documentation (and what little it had was terrible).

Now it's a 145-page beast.  Okay, not quite as dramatic as 1000 miles, but still, damn thing took me like 15 minutes to print all of it.  And no way in hell I'm getting a staple through all of the pages.  I kinda liked reading the DLINQ documentation, so I figured it's probably a good idea to reacquaint myself with NHibernate on a more intimate level.

I'm going to try and finish it on the plane trip in and out of Utah next week.  Yah, I'm bringing my camera this time; missed some beautiful scenary last time :-S  I think this week, it'll really feel like I'm working at a new company.  It's been slow going as the company's CEO has been working onsite with a client and the engagement is just ending now.  This means that hopefully, the fun's only starting to begin.

It's 1:04 AM...what am I doing up reading about NHibernate?

# Tuesday, March 28, 2006

NHibernate Back on My Radar

Tuesday, March 28, 2006 1:17:17 AM UTC

A little more than a year ago, I did my first sample project with NHibernate during some extended down time at Immedient.

At the time, the project was still in the .x releases (I believe I started with .8).  The one thing that really turned me off was the lack of good samples and starting points to learn from (although I did eventually dig up enough info to get my sample project up and running) and, in particular, the lack of strongly typed lists and collections. 

This is a legacy of the Java implementation of Hibernate, which was addressed some time last year with the release of .Net 2.0 and Generics, actually, but I never got a chance to look into it more as the end of the year was a busy quarter for me.

Over the last few days, I've been doing a little bit of studying regarding DLINQ for object persistence (incidentally, I also learned how to do duplex printing with my printer, which was far too confusing).  I recall being quite excited about ObjectSpaces when I was working at Factiva, but I was never able to get my hands on the preview bits.  From what I understand, it was actually very similar to NHibernate in that it required the use of intermediate XML mapping files (although DLINQ also needs those, but only for generating class files since it relies on the use of attributes).

DLINQ is the heir apparent to ObjectSpaces and is superior in every way...it's just that it's still in very early alpha stages and won't be ready for primetime until the release of C# 3.0.  While I love the technology, I'm just not ready to put time into something that's so open to change at the moment.

So, while I would love to implement DLINQ, it just seemed safer to take a second look at NHibernate, at least for the time being.  The last time that I took a look at it was probably around summer of last year, when I implemented a "toy" site for my sister using Cuyahoga CMS (which uses NHibernate).

With that in mind, I came across a very good CodeProject article on best practices for using NHibernate in a web environment.  As soon as I saw the bit about Generics, my interest was piqued again.  I downloaded the source and followed along and, to my surprise, it seems that my earlier frustration with good examples and usage has slowly been counterbalanced by increased usage of NHibernate.

As a bonus, I came across a great set of links and finally took some time to read about Martin Fowler's article on Inversion of Control.  This lead me to two frameworks for implementing IoC in .Net: Spring.Net and Castle/Windsor.  To be honest, I didn't quite "get" IoC and Castle the first time I looked at it (again, when I first started playing with NHibernate).  But I think I'm finally starting to understand it (I won't say I do fully until I use the framework and really "get" it).  I implemented something similar in a small project that I worked on last year at INS/Immedient (probably would have been much easier to use this instead).

The thing is, I've begun to become more and more obsessed with building loosely coupled systems.  So this is just the fix that my brain needed to start thinking about better designs.  Both Spring and Castle seek to address the same issue by utilizing IoC to remove dependencies (see here and here for a comparison of the two, although note that these were written over a year ago and were written by the project leader of Castle).

BONUS: I also came across a blog posting on how to simulate an HttpContext for testing written by the guy that's leading the Subtext project.  This is actually something I had been curious about (but too lazy to do anything about :-D) for quite a while.

# Monday, March 20, 2006

.Net Blogging Engines?

Monday, March 20, 2006 9:56:28 PM UTC

So far as I can tell, there are only three free, "lightweight", open source .Net blogging engines out there:

  • dasBlog.  This is what my blog is using.  It's okay, but definitely lacking in some respects like proper XHTML markup, database post storage, and available plug-ins.  But it's completely free!
  • Vine Type.  Looks good.  XHTML compliant (very much so that the source is almost not recognizable as ASP.Net source).  Unlike dasBlog, however, Vine Type isn't completely free; it's free for non-commercial use only (which is a very loose term nowadays in the blogging world with the explosion of AdSense supported blogs).
  • SubtextLooks to be the least "feature rich" of the three (but I say this without having actually tried it).  Oddly, it's the only blogging engine whose site is not running off of the engine itself, which is somewhat disheartening.  Also lacking screenshots and examples, which makes it tough to get a feel for the features.

So are there other options available out there in the .Net space?  I dunno...looks incredibly lacking in all directions.

Random link (just because I feel like it, k?): A good discussion on Ruby on Rails and  .Net with some inspired commentary (don't skip the comments!).

# Tuesday, March 14, 2006

Custom POP3/SMTP Mail Client

Tuesday, March 14, 2006 2:21:39 PM UTC

Think you can write a better web mail interface?  I know I do :-D.  I'll have to take a look at it a bit more when I get a chance.

If you're interested, here are a few good starting points for ya:

  • A small introduction for a C# client implementation.  Looks like a good starting point to get your code going.
  • RFC1939 and subsequent extension, RFC2449.   The official specification for the POP3 protocol; a good reference to clear up any ambiguities when writing your implementation.
  • RFC2821.  The official specification for SMTP (used for sending email messages).  I dealt quite heavily with this RFC when I was at Factiva.  Quite an interesting spec, but probably better to use CDOSYS instead if you have that available and you don't need full control over the SMTP implementation.
  • An article by Duncan Mackenzie on writing a custom client.  Duncan also has a neat little ballon popup implemented.
  • A .Net 2.0 library for POP3 communication.  Looks full featured and documented...good starting point if you're not interested in the intricacies of POP3.
  • A good sample POP3 session "conversation" example.  It helps to understand how the messages are typically used in a session.

Will be interesting, I'm looking forward to getting some free time to work on this.

I'm debating whether it makes sense, from a performance perspective, to use a sort of POP3-SQL Server synchronizer to move messages from one or multiple accounts into one repository for fast indexing and lookup.

# Thursday, February 23, 2006

WinFX February CTP

Thursday, February 23, 2006 3:23:55 PM UTC

This is definitely something I'm going to have to download and play around with in the next few weeks.

# Saturday, February 11, 2006

Workshop : XML Schemas + Object Models

Saturday, February 11, 2006 11:30:58 PM UTC

Actually, very few .Net developers that I've worked with know what a typed DataSet is let alone how to create one. It's one of those perplexing things that always baffles me as typed DataSets are not a bad way to make the best of the flexibility of DataSets while still offering design time support and comiple time error checking (to some degree, of course).

At the core of the typed DataSet is an XML schema that describes the types and structure of the DataSet. While typed DataSets are great, if you ever look at the code, it's quite heavy and not necessarily the most optimized structure for over the wire transport. As even the discussion of typed DataSets narrows down the audience of developers that know how to work with schemas to generate a typed DataSet, the concept of generating entire object models using XML schemas is even less understood. Yes, indeed, the XSD.exe tool that ships with Visual Studio.Net can also be used to generate object classes from the same schemas (although they are a bit clumsy to work with).

You may be asking yourself why bother with schemas when you can just create the classes by hand or some other sort of visual code generation tool. Well, for some people (myself included), schemas seem a very natural way to express object models and classes. I mean, after all, the purpose of a schema is to define what an object (typically an XML document) looks like. But certainly, if that was it, it wouldn't really be worth the effort, now would it? For me, there is an added benefit in that it's very easy to define typed collections in schemas. On top of that, the generated classes come with various XML attributes already marked up for you, which is handy if you plan on using the classes as data transfer objects for your web service.

If you're interested, check out the workshop.

Leave comments, questions, and criticisms in the thread.

# Tuesday, February 07, 2006

Random DevTools Entry: #004

Tuesday, February 07, 2006 1:30:55 PM UTC

I've been doing some WinForms work lately (I'm primarily a WebForms developer) and had a lot of trouble working with the WinForms DataGrid.  Primarily, the DG just seemed very difficult to customize in terms of behavior and look & feel.  Whereas with the WebForms version of the DG, the declarative model and the power of CSS makes it a snap to do these things, the WinForms version just took way too much work.

So after looking around and trying a few open source controls, I finally stumbled on DevAge's SourceGrid3.  I really like it.  It allowed me to do things with a grid that simply were waaaaay too time consuming/difficult with the out of the box WinForms DG, which is just too tied into the DataSet model and doesn't work very well with custom business objects and typed collections.

It does take some time to pick it up, but the MVC design of the library makes the code very clean and extremely flexible.

The Source Pack also comes with a variety of other controls for WinForms development.  Definitely worth a look for any WinForms developers looking for more flexibility in grids.

# Wednesday, January 25, 2006

Yet Another Bookmark

Wednesday, January 25, 2006 1:49:09 PM UTC

I going to have to take a look at this Composite UI Application Block from Microsoft's patterns and practices group.

It actually looks very similar (at least from a 10k foot view) to the architecture/design implemented by Omar Al Zabir in a writeup over at CodeProject.

I admit, I've never been much of a WinForms guy, as development of Windows clients has never really interested me (partially because of what a pain in the ass it is to work with WinForms compared to WebForms (XHTML markup just makes more sense for UI layout and presentation, at least in my opinion)), but I think it's probably worth my time to take a good look.

# Friday, December 16, 2005

Asynchronous Callbacks with AJAX

Friday, December 16, 2005 2:01:51 PM UTC

A blog post I came across should be of interest to anyone working with AJAX:

I've explained before why XmlHttpRequest should always be used asynchronously. In a nutshell, JavaScript is not multi-threaded, so the only way to keep your application and browser reasonably responsive is to use some kind of asynchronous pattern. This way, the multitasking is left to the hosting browser and the JavaScript developer can enjoy a relatively easier programming environment where he only needs to care about events and not about summoning threads and managing locks.

Add this small script to your page (preferably in the <head> section) and all your XmlHttp requests will be done synchronously no matter what the framework you're using is doing. This works with ASP.NET 2.0 callbacks in both IE and Firefox but breaks callbacks for Opera. I suspect that it would also work with other Ajax frameworks such as Atlas.

Supposedly, this will work with any AJAX framework.  I've been running into just this issue with AJAX.Net.  Having used both  AJAX.Net and Atlas somewhat extensively, I'll have to give the edge to Atlas for pure ease of use.

# Saturday, November 12, 2005

SQL, VS.Net, and BizTalk 2005 Release Event

Saturday, November 12, 2005 3:38:11 PM UTC

I'll be in Philly next week for the Microsoft release event for SQL Server 2005, Visual Studio.Net 2005, and BizTalk 2006 next week (11/17).

I'm not only going as a participant, but a small group of us will be there representing EMC, one of Microsoft's partners for the event.  Rich Millman, my current MC, will be on some speaking panel and a couple of us will be manning a booth on the floor.

As there were only 4 of us in the group at INS Piscataway that have played around with and read up on SQL Server 2005, I was invited into a brainstorming session on what type of demo that we could put together that would draw people in and hopefully get some new contacts.

My first thought was to create a failover cluster using 4 spare PCs that we had.  Not that it's a great demo of the new features of SQL Server 2005, but I figured that it would draw people's attention and since most developers probably very rarely interact with failover clusters.  It would have been cool to let people walk up and plug/unplug indivitual nodes and watch it failover automatically.  Alas, we didn't have any spare hardware sitting around to build the disk array and it was probably too late to borrow anything from EMC.

My second idea was a little better.  Even though database mirroring isn't officially supported in this release of SQL Server 2005, I figured it would be cool to demonstrate it as it's much more likely to be used than failover clustering due to the low cost of implementation.  And so, myself and Igor went about building a demo setup for database mirroring.

One of the first challenges we had to overcome was to figure out why it's not officially supported in this release.  Obviously, it would have sucked to spend hours working on the architecture and UI only to realize that mirroring was buggy and unstable.  After some research, it turns out that the primary reason for not supporting it in this release is because of the fact that Microsoft couldn't find enough beta testers to fully test the new feature.  With that in mind, we decided we could probably pull it off and Igor and I started to dig in.

It's actually fairly cool and takes advantage of a lot of the new features of the 2005 suite.  The UI is an ASP.Net application that utilizes Atlas to retrieve data from a web service.  Another web service was written to interact with the host machine services to stop and start the individual SQL Server instances.  Very cool.  I'm hoping I can talk them into letting me post the code and walkthrough here for anyone that wants to try to set up mirroing.

demo_screencap_t.jpg

So if you're going to be in Philly at the launch event, look for INS there!  The demo is very cool.

# Wednesday, October 12, 2005

Workshop : CDOSYS + .Net

Wednesday, October 12, 2005 8:46:29 PM UTC

As anyone who has used the .Net System.Web.Mail namespace can attest, the default .Net mail classes are woefully lacking in functionality.  It's really a shame too, considering that they're based off of the very powerful CDONTS/CDOSYS libraries, which allow a lot more functionality.

In this first investigation into unleashing the full power .Net web mail, we will create a simple web interface to send email messages with a user uploaded attachment without saving the uploaded attachment to disk first.

Some of this functionality is likely built into many third party mail packages, but why pay for it if you have time and you can build it for free?

So if you're still interested, hop on over to the workshop article.

As always, please leave comments, questions and criticism in the post.

» On This Page
FluentNHibernate And NHibernate.Linq
Paging With SPListItemCollectionPosition
Simple (?) AJAX Upload For ASP.NET
SharePoint Design Patterns: Entry 2.5
Chain Of Command And Passing Parameters
SharePoint? Is That You?
Yet Another .NET Interview Questions List
MbUnit CsvDataAttribute
Automatic Properties (And Why You Should Avoid Them)
Why ASP.NET (webforms) Sucks.
XMPP SASL Challenge-Response Using DIGEST-MD5 In C#
Leveraging The Windows Forms WebBrowser Control (For The Win)
Discovering System.Linq.Expressions
I Like Jeffrey Palermo's Prediction...
Visitor Pattern In C# 4.0
WCF Load Balancing : An End To End Example For NetTcpBinding
The Follies of C# 4.0
Fatal Execution Engine Failure(0x7927e03e) and WCF
What Working With Python Has Taught Me...
WCF, Prototype, And Awesome-sauce
WSS And DateTime Error
SharePoint Layout Pages With CodeBehind And Prototype
Confucius On Programming
How Did I Miss This?!?
Serializing Inheritance Chains With WCF
Working With SQL Server Compact Edition 2005
Normalizing And Denormalizing SharePoint Field Names
Tuesday Morning Thoughts
WCF Configuration Intellisense
Enterprise Library vs. Log4Net
SharePoint SoapServerException When Using Lists Service
Correlation Across Workflow Instances
Office Add-In Development "Gotcha"
Enterprise Library 3.0 Released
Automatic Properties in C# 3.0...Why?
NHibernate Or Bust!
Combating Namespace Bloat With .Net XML Serialization
WF Passivation Services Issues
Setting Links in Word Programmatically
Revisiting Spring.Net
Most Annoying Error Ever.
My Thoughts on WF
A Note On Copying Files In WSS3
.Net On The Up And Up
Workflow and SharePoint
NDoc 2 is Officially Dead
Big Changes Around the Corner
Started Working with the NDoc 2 Alpha Build...
I've Done It....
Enterprise Library 2.0 Logging Quirks
Random DevTools Entry: #010
Random DevTools Entry: #009
Random DevTools Entry: #008
ObjectBuilder and Dependency Injection
So I've Started the Journey...
NHibernate Back on My Radar
.Net Blogging Engines?
Custom POP3/SMTP Mail Client
WinFX February CTP
Workshop : XML Schemas + Object Models
Random DevTools Entry: #004
Yet Another Bookmark
Asynchronous Callbacks with AJAX
SQL, VS.Net, and BizTalk 2005 Release Event
Workshop : CDOSYS + .Net
RSS 2.0 Atom 1.0 CDF