Derik Whittaker

Syndication

News


Code Contracts Primer – Part 2: Handling Legacy Code

If you are not familiar with the Code Contracts library which is coming out of Microsoft R&D labs, you need to check this pretty cool little library out.  As of Vs2010/.Net 4.0 this library will be making the jump out of the R&D labs. 

Over the next few blog posts we will be taking a look at the topics below.

So the one of the first questions that many people ask when talking about using the Code Contracts library is ‘what do I do about my legacy code?’.  Asking this is a very valid question.  If your team has already subscripted to the design-by-contract or fail-fast concepts then maybe you have already added in your own checks.  If this is the case the contracts team has thought of you and has already provided a simple answer.

Lets assume you have the following code:

public ReportCard GetDailyReportCard(Int32 employeeId, DateTime dateForReportCard )
{
    if ( employeeId <= 0 ){ throw new ArgumentOutOfRangeException("employeeId", "The provided employee ID was out of range");}
    if (dateForReportCard.Date >= DateTime.Now.AddDays(1).Date) { throw new ArgumentOutOfRangeException("dateForReportCard", "The provided date was in the future"); }

    // do something meaning
    var reportCard = new ReportCard(employeeId);

    return reportCard;
}

As you can see, we are already doing a contract check, but we want to be able to take advantage of what the contracts library has to offer, so what do we do?  Simple, we add in the usage of the Contract.EndContractBlock.  When you put this call AFTER the last if-then-throw check in your method the contracts library assumes that all those calls are ‘legacy-requires’ and will weave the correct code in their place.

Here is the code with the correct contracts call added:

public ReportCard GetDailyReportCard(Int32 employeeId, DateTime dateForReportCard )
{
    if ( employeeId <= 0 ){ throw new ArgumentOutOfRangeException("employeeId", "The provided employee ID was out of range");}
    if (dateForReportCard.Date >= DateTime.Now.AddDays(1).Date) { throw new ArgumentOutOfRangeException("dateForReportCard", "The provided date was in the future"); }
    Contract.EndContractBlock(); // marks this as legacy

    // do something meaning
    var reportCard = new ReportCard(employeeId);

    return reportCard;
}

Now that we have added the call to EndContractBlock we should take a look at what the code weaver for the library did to our assembly post compilation.

public ReportCard GetDailyReportCard(int employeeId, DateTime dateForReportCard)
{
    if (__ContractsRuntime.insideContractEvaluation <= 4)
    {
        try
        {
            bool _preConditionHolds;
            __ContractsRuntime.insideContractEvaluation++;
            if (employeeId <= 0)
            {
                _preConditionHolds = false;
            }
            else
            {
                _preConditionHolds = true;
            }
            __ContractsRuntime.Requires(_preConditionHolds, null, "employeeId > 0");
            if (dateForReportCard.Date >= DateTime.Now.AddDays(1.0).Date)
            {
                _preConditionHolds = false;
            }
            else
            {
                _preConditionHolds = true;
            }
            __ContractsRuntime.Requires(_preConditionHolds, null, "!(dateForReportCard.Date >= DateTime.Now.AddDays(1).Date)");
        }
        finally
        {
            __ContractsRuntime.insideContractEvaluation--;
        }
    }
    return new ReportCard(employeeId);
}

As you can see, the newly created code looks a little like our original code, but the weaver has done its magic and added in all the correct logic for you to turn your legacy contracts into ‘usable’ contracts by the library.  So long story short, if you have legacy code and you want to take advantage of the contracts library you simply need to add a single line of code AFTER your last if-then-throw statement.

Till next time,


Posted 06-09-2009 6:51 AM by Derik Whittaker

[Advertisement]

Comments

on 06-09-2009 10:41 AM

BizTalk/Oslo/Windows Azure Announcing the Availability of the BizTalk ESB 2.0 Toolkit MGraph Object Model - This paper describes the newly revised object model for dynamic (programmatic) parsing of MGraph output as it exists in the "Oslo" May

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)