Sunday, January 27, 2008
I've written about Model View Presenter (MVP) several times before, once after hearing a talk and learning about the pattern, and again when I learned about extension methods.

Today I bring you a screencast on Model View Presenter using Visual Studio 2008 and extension methods.  This is my second screencast, and I've upgraded my microphone to a professional rig thanks to my father to improve the audio.

Click here to watch the screencast.

Sunday, January 27, 2008 10:55:25 AM (Central Standard Time, UTC-06:00)
 Friday, October 19, 2007

Mocking frameworks are growing more and more in popularity these days, because to some degree Unit Testing, via TDD or otherwise, has been growing in popularity.  This week at the Heartland Developer Conference I gave a talk on what I call "practical" TDD.  The talk goes over the basics of TDD quickly, but is really targeted at those who have tried to do TDD but found it difficult because they are not working on a team that has adopted the practice, or they are not working a project that was built to be testable.  I spent a good bit of time working no what is the easiest path to help such people adopt TDD, because adoption of such good practices is far more important to me than perfection in them.  As has been said many times, Good Enough is by definition, Good Enough.

After a good bit of research on the subject of mocking frameworks, I have come to the simple conclusion that:

  1. This is an area that is growing still, as nearly every major framework differs on the coding approach.  This is in stark contrast to testing frameworks which, to a one in .NET, all have settled on the NUnit 2.0 model of using attributes.
  2. That if you're not using TypeMock then you're just working to damned hard.

Now, I'm sure my friends (and there are many) who use Rhino Mocks will believe that I must be over-stating the issue, but I tell you clearly I am not.  TypeMock is not built like any other mocking framework currently available, it uses the profiling APIs and not polymorphism or encapsulation in order to intercept calls and provide return values.  Let me give you just a few examples of things which TypeMock can do in a few short lines of code which Rhino Mocks simply cannot do at all.

Mocking Static Methods

Take the following code, and assume that we wish to mock MessageBox.Show which is a static method:

        private void MyCoolMethod(string msg)
        {
            if (MessageBox.Show(msg) == DialogResult.OK)
                Console.WriteLine("OK");
            else
                Console.WriteLine("Not OK! Not OK!");
        }

The following test will work perfectly to mock this call.  No other hidden setup, nothing more than a reference to TypeMock.dll and the following code:

        [Test]
        public void MockMessageBoxShow()
        {
            MockManager.Init();

            Mock mbMock = MockManager.Mock(typeof(MessageBox));
            mbMock.ExpectAndReturn("Show", DialogResult.OK);

            MyCoolMethod("Here we go again.");

            // Ensure that all expectations were met.
            MockManager.Verify();
        }

And with just that little code, just 4 lines dedicated to the mock, 2 of which should be refactored to Setup and TearDown methods, we can mock a static method.

Not cool enough for you? Ok, fine.

Mocking Events

So you have something which expects an object to return certain events.  This example does require a professional license of TypeMock, it will not work under the Community Edition, but if you need this functionality then really pay the nice folks their money.

    public class GUI
    {
        public string LovingCSharp { get; set; }

        public void Initialize()
        {
            this.LovingCSharp = string.Empty;
            Button button = new Button();
            button.Click += new EventHandler(button_Click);
        }

        private void button_Click(object sender, EventArgs e)
        {
            this.LovingCSharp += "LOVE!";
        }
    }

Now let's mock this up, call that event three times, and assert that our property is set correctly. 

        [Test]
        public void MockFormWithEvents()
        {
            MockManager.Init();

            // Mock button so that we can...
            Mock btnMock = MockManager.MockAll(typeof(Button));

            // Handle all calls to add an event handler.
            MockedEvent evntMock = btnMock.ExpectAddEventAlways("Click");

            GUI frm = new GUI();
            frm.Initialize();
            evntMock.Fire(this, EventArgs.Empty);
            evntMock.Fire(this, EventArgs.Empty);
            evntMock.Fire(this, EventArgs.Empty);

            Assert.AreEqual("LOVE!LOVE!LOVE!", frm.LovingCSharp);

            // Ensure that all expectations were met.
            MockManager.Verify();
        }
    }

Summary

These are just two examples, and don't even delve into the whole "Natural Mocks" portion of TypeMock.  Do yourself a favor, download the evaluation, they'll give you 30 days of all the features (which you can make any individual 30 days you'd like BTW) and ask yourself why you're jumping through all those hoops just to  be able to mock dependencies.  With this project, you don't have to create dependency injection constructors just to make your classes testable.

Friday, October 19, 2007 10:25:41 PM (Central Standard Time, UTC-06:00)
 Tuesday, October 02, 2007

Today I was taught an immensely important lesson by WCF.  It actually has nothing to do with WCF except that because of the size of the schema I'm working with that is where I encountered it.

I do a lot of work in the healthcare industry, and that industry, by government mandate, works with a message format called the 837 (properly the X12 4010A1 837 either I, P or D).  The 837 has three flavors, and is absolutely huge.  I was crafting a service which had to accept an XML representation of this data. How did I create the XML?  BizTalk Server 2006 R2's new HIPAA support of course.  When I made the call to service from my unit tests I first received a Fault indicating that exception details could not be returned because of configuration.  No problem, obviously I've seen this before and so I added the following to my app.Config for the Host executable:

 

<behaviors>
  <serviceBehaviors>
    <behavior name="EnableDebugging">
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

Now that I've enabled debugging, surely now I'll see some sort of clear reason by this occurred. Nope!  I was presented with the following:

TheCompany.Services.Tests.ClaimsService.GetListOfClaimsByStatus : System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail] : Error in deserializing body of request message for operation 'GetClaimListByStatus'.

Well isn't that terribly useful.  Fortunately, this did give me the single most important piece of information "deserializing".  So off I go to Google my brain, because I'd written a post before on how to debug the XmlSerializer (and I was using the XmlSerializer in this case because the DataContractSerializer could not work with my schema).  As that post will tell you, there is a switch that can be set in the app.Config which will enable you to debug the code generated by the XmlSerializer.  So now we add the following to my app.Config:

<system.diagnostics>
  <switches>
    <add name="XmlSerialization.Compilation" value="1" />
  </switches>
</system.diagnostics>

And we follow that by running the unit tests again, that results in something that is actively useful:

image

For those reading along at home and wanting the full text that says:

The maximum nametable character count quota (10000) has been exceeded while reading XML data. The nametable is a data structure used to store strings encountered during XML processing - long XML documents with non-repeating element names, attribute names and attribute values may trigger this quota. This quota may be increased by changing the MaxNameTableCharCount property on the XmlDictionaryReaderQuotas object used when creating the XML reader.

Now that is useful, it tells me exactly how to correct the problem and the size of the quota currently.  The only problem is that I didn't create this XmlReader object, I didn't even create the XmlSerializer which created this XmlReader.  The only thing which I create was a ServiceHost, how can I change that setting?  Enter Google again.

As it happens, Windows Communication Foundation does include an ability to override that value, it is stored in the Binding Configuration in your ... you guessed it ... app.Config!  Add the following snippet (assuming you're using Basic Http Binding (it exists for all bindings though) and you'll be good to go:

<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding">
      <readerQuotas maxNameTableCharCount="100000"/>
    </binding>
  </basicHttpBinding>
</bindings>

Now, surely I'm done, and things will work.  Actually, no it took me a few times to find a value that would work for that quota.  Once I did though I finally hit my breakpoint inside the service and was able to send back a response, where upon I got this message:

TheCompany.Services.Tests.ClaimsService.GetListOfClaimsByStatus : System.ServiceModel.CommunicationException : Error in deserializing body of reply message for operation 'GetClaimListByStatus'.
  ----> System.InvalidOperationException : There is an error in XML document (1, 252).
  ----> System.Xml.XmlException : The maximum nametable character count quota (10000) has been exceeded while reading XML data. The nametable is a data structure used to store strings encountered during XML processing - long XML documents with non-repeating element names, attribute names and attribute values may trigger this quota. This quota may be increased by changing the MaxNameTableCharCount property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 1, position 252.

At least when the error occurs on the client side you get the full details to start with!  Make the same modification above to your configuration on the client side and you're good to go.

Tuesday, October 02, 2007 2:38:44 PM (Central Standard Time, UTC-06:00)
 Thursday, September 27, 2007

image I've spent a lot of time this summer traveling to various events and presenting my talk "Introduction to C# 3.0" to people throughout the South Central area of the United States.  Well, it pains me to say I'm but one man, and there are way way way way to many of you to reach through this manual process.  Fortunately for me, there are technological solutions to this problem : The Internet!

I've spent some time today recording my first of what I hope to be several webcasts.  These webcasts are made possible through the generation gift of a Camtasia license from TechSmith.  I've been a fan of Camtasia for many years, and the latest versions are a joy to work with.

All of that said, following this link to the Land of Oz and an Introduction to C# 3.0.

Thursday, September 27, 2007 3:18:01 PM (Central Standard Time, UTC-06:00)
 Thursday, July 19, 2007

I've just had my first article ever published on ASP Alliance, it covers System.Diagnostics.Debug and methods within it which can improve your code today.  Please go check it out, great content here!

.NET | CSharp
Thursday, July 19, 2007 1:30:46 PM (Central Standard Time, UTC-06:00)
 Sunday, July 08, 2007

To complete my Arkansas trip, on July 3rd I spoke to the Northwest Arkansas .NET User Group and presented my talk "Introduction to C# 3.0".  While there are not any downloads I can offer for that talk, it is all code made up on the spot in reaction to questions about the features, I would like to take a moment to thank them for having me out to speak.  Jay Smith, President of the NWADNUG, was an excellent host and I enjoyed both speaking and hanging out with many of the members at Applebee's after the meeting. If you find yourself in Fayetteville AR, or are ever invited to come speak to this group, you should definitely visit them. 

Furthermore Fayetteville itself is a very pretty town, the trip in up I-540 reminds me what I miss about living somewhere that elevation happens, and there are plenty of great little shops in the area including one of the better board games shops I've run into in a long while.

Sunday, July 08, 2007 1:01:11 PM (Central Standard Time, UTC-06:00)
 Sunday, July 01, 2007

mvplogo.pngI've been visiting Arkansas this weekend, but while reviewing my spam folder I noticed something got caught that shouldn't have.  Specifically the email that informed me I've been selected as an MVP for BizTalk Server.  I'm honored, and appreciate the support of everyone who has made this possible by opening their groups to me to speak.

Sunday, July 01, 2007 9:04:52 PM (Central Standard Time, UTC-06:00)
 Saturday, June 30, 2007

Sonu Arora, who I had the pleasure of meeting at TechEd this year, has just posted on her blog that her team has released an RC (Release Candidate) of the WCF Line of Business Adapter SDK to Microsoft Connect.  In case you don't know, this is the framework upon which Microsoft is building their next generation adapters to systems such as Siebel, SAP, and Oracle Financials.  It is based around extracting meta-data from the LOB application, and works entirely consistently with the WCF channel extensibility model.

If you read my blog and do BizTalk, and even more relevantly do BizTalk and SAP, Siebel, Oracle Financials or other LOB applications, then you'll want to look at this.  Post R2 this would be the recommended route to take if you had a LOB application you needed to integrate with, rather than writing a Custom Adapter.  You'd simply write an LOB Adapter in .NET using this SDK, and then implement with the WCF Adapter for BizTalk.  The benefit there is that the work in the Adapter would be re-usable to other WCF .NET applications and not tied exclusively to the BizTalk object model.

Saturday, June 30, 2007 5:40:49 AM (Central Standard Time, UTC-06:00)

Sometimes the weirdest things come up when testing.  I was helping with some Integration Testing recently, and we needed to submit a new valid postal address with every request to this system.  That's a hefty load to bear, and certainly if I were doing Unit Testing I'd be mocking away that system just to not have to deal with that problem, but for Integration Tests there was no way around it.  My answer?  Public data my good friends.

The quest started with Google, as most do, and a search criteria like this :

City State Zip filetype:csv

Which after browsing for several pages I modified to:

City State Zip filetype:csv site:usps.com

That resulted in the CSV which is the source of the data we're using, a list of Post Offices across the nation.  The list is very long, a total of 19,931 addresses.  Now, it wouldn't be fair to just list the Google queries here, after all this is a technical blog.  I took the CSV apart, removed the irrelevant fields and parsed it into an object to hold address data, specifically this object.

[Serializable]
public class AddressData
{
    private string _Name;
    public string Name
    {
        get { return _Name; }
        set
        {
            _Name = value;
        }
    }
    private string _StreetLine1;
    public string StreetLine1
    {
        get { return _StreetLine1; }
        set
        {
            _StreetLine1 = value;
        }
    }
    private string _StreetLine2;
    public string StreetLine2
    {
        get { return _StreetLine2; }
        set
        {
            _StreetLine2 = value;
        }
    }
    private string _City;
    public string City
    {
        get { return _City; }
        set
        {
            _City = value;
        }
    }
    private string _State;
    public string State
    {
        get { return _State; }
        set
        {
            _State = value;
        }
    }
    private string _Zip;
    public string Zip
    {
        get { return _Zip; }
        set
        {
            _Zip = value;
        }
    }
}

Now if you compile your own version of that code, and create a List<AddressData> you should be able to Deserialize this file of all the addresses for your own use.

.NET | CSharp
Saturday, June 30, 2007 5:20:51 AM (Central Standard Time, UTC-06:00)
 Wednesday, June 20, 2007

I've had several occasions now where someone with Sogeti or someone at a client has had a "truly mysterious" problem where the XmlSerializer was throwing an error which the programmer simply couldn't understand.  When situations like this arise, I find myself reaching for a great post written by Scott Hanselman on this issue which I will repeat the meat of which here so that I've got a copy of my own.

If you find yourself needing to debug the code generated by the XmlSerializer to serialize or deserialize your type, here is what you need to do:

1. Modify your app.config or web.config to include the following:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:    <system.diagnostics>
   4:       <switches>
   5:          <add name="XmlSerialization.Compilation" value="1" />
   6:       </switches>
   7:    </system.diagnostics>
   8: </configuration>

2. Recompile your application and set a break point just after you create your XmlSerializer.

3. Open the directory "C:\Documents and Settings\[username]\Local Settings\Temp"

4. Find the .CS file with the most recent timestamp, it will have a random file name.

5. Open that file in the same Visual Studio you've got debugging, and set a break point.

6. Debug to your hearts content.

Important to remember at this point is that this code is generated by the system and is meant to be fast, not friendly.  You'll need to be very familiar with the XmlReader object or you won't understand how it is doing what it is doing.  Also realize that you can't control that code, you can only control the attributes on the Type you gave it, and from that it will generate the code as it sees fit.

Side Note : One of the classic performance mistakes I see people make when they start doing a lot of XML serialization is to create the XmlSerializer object every time they need one.  The constructor of the XmlSerializer is the most expensive part of it's operations.  It is there that the code is generated which you are debugging above, and so once you've created an XmlSerializer if you've got a reasonable expectation of needing it again then keep it around!

CSharp | XML
Wednesday, June 20, 2007 10:12:18 PM (Central Standard Time, UTC-06:00)
 Sunday, April 29, 2007

I spoke recently at Dallas Code Camp 2 about C# 3.0 and the new language features it contains.  Most of the buzz on the net has been about LINQ, understandably, but as I've mentioned here before I really, really, dig extension methods.  I've spent a good bit of time thinking about uses for them, and looking at how Microsoft has used them in .NET 3.5.

One of the things that didn't click the first time I played with extension methods which you might have missed to is that you do not have to extend classes, you can extend interfaces.  Think about that a moment, you can write methods, with functionality, that act upon interfaces.

For example I've previously spoken here about the Model View Presenter pattern, which is normally implemented with an Interface (The View), a Data Access Object (The Model), and a class to map between them (The Presenter).  "The Presenter" takes "The View" in it's constructor and simply acts upon "The View" in it's methods.  "The View" is implemented as an interface because you can have multiple interfaces, but this requires another class for "The Presenter" because interfaces can't contain any code.  Until Now.

With extension methods it becomes perfectly possible to forgo the need for a Presenter class in favor of a set of extension methods.  Does this save typing?  No, in all likelihood you've not save many keystrokes when writing your Presenter but you have gotten rid of the need to ever declare the Presenter on your pages/forms at all.  If you implement IDisplayBlogPost on your ASP.NET page, then if you extend that interface with a method called "public static GetBlogPostByTitle(this IDisplayBlogPost view, string title)" then your page now has that method itself, and a simple "this.GetBlogPostByTitle(blogTitle);" can result in population of your page.

This essentially brings to .NET the power of Multiple Inheritance without the problems with Multiple Inheritance that exist in certain other languages.

I'm still downloading Beta 1 of Orcas, but rest assured code samples for this are coming.

Sunday, April 29, 2007 12:16:13 AM (Central Standard Time, UTC-06:00)
 Tuesday, March 20, 2007

I've had a chance over the last few days to play some more with the March CTP of Visual Studio Codename "Orcas" and with the features being added as a part of C# 3.0.  Even while feeling utterly handicap in Visual Studio without CodeRush and Refactor! Pro, I've managed turn out an interesting little assembly that I intend to grow as time goes with the namespace TimRayburn.Extensions.  As you might guess this assembly contains Extension methods to classes within the Framework.

In case you don't know what extension methods are, they are static methods in static classes which use a special syntax to indicate that they extend an existing class or interface.  For instance you might write some code like:

   1: public static string ToStringNullSafe(this object inStr)
   2: {
   3:     if (inStr == null) return string.Empty;
   4:     else
   5:     {
   6:         string lStr = inStr.ToString();
   7:         if (lStr == null) return string.Empty;
   8:         else return lStr;
   9:     }
  10: }

Which extends the class System.Object to contain a new method called ToStringNullSafe which, as you can see, returns String.Empty instead of throwing Exceptions when a the object being called is null or it's ToString value is null.  The intellisense for this looks like the image to the right.

I intend to use TimRayburn.Extensions to contain extension methods which I've written and find useful.  Version 0.1 addresses very simple problems, but over time I'm sure more complex functions will be added.  For now there are two classes in the project FrameworkExtensions and EnsureExtensions.

Framework Extensions contains three methods today.  ToStringNullSafe (as seen above) extends System.Object to provide a ToString method which will not throw exceptions on null.  ToInt32 extends System.String to provide the ability to convert to a System.Int32 inline.  Likewise ToDouble extends System.String for conversion to System.Double.  These extensions are simple and without a unifying purpose other than that I thought they would come in handy.  Nothing being done here, or in EnsureExtensions, that can't be done without extension methods, just easier and more reader friendly code.

EnsureExtensions contains many methods which extend either System.Object, System.String or objects which implement IComparable<T>.  Every method in this class follows the naming convention EnsureX where X is something you would want to confirm about the datatype before using it in code.  The first of these is EnsureNotNull, an extension to System.Object, which checks if the object being used is null, and if it is throws an ArgumentException but if not it simply returns the object.  This allows for interesting pieces of code like:

   1: public void MyExampleMethod(string inputData)
   2: {
   3:     inputData.EnsureNotNull().EnsureGreaterThan("Bravo").EnsureLessThan("Charlie");
   4:  
   5:     // Real code here now that arguments have been checked.
   6: }