Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET 4.5
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Amazon Web Services
Analysis Services
Android
Architecture
Arduino
ASP .NET Web API
ASP.NET
ASP.NET MVC
ASP.NET WebForms
Azure
B2B (Business Integration)
BDD
Big Data
Bing
BizTalk
Book Excerpts
Build and Deploy
Business Intelligence
C#
C++
ClickOnce
Cloud Computing
Code Contracts
CODE Framework Info - non Technical
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Debugger
Design Patterns
Development Process
Display Technologies
Distributed Computing
Document Database
DotNetNuke
DSL
Dynamic Languages
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Git
Graphics
HTML 5
Internet Explorer 8.0
Interviews
IOS
iPhone
Iron Ruby
Java
Java Script
JavaScript
jQuery
JSON
Lightswitch
LINQ
Linux
LUA
Mac OS X
MDX
Messaging
Metro
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Dynamics
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
MsBuild
MVVM
MySQL
Network
NHibernate
node.js
NOSQL
Nuget
Object Oriented Development
Objective C
Odata
OLAP
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
PHP
Podcasts
Post Mortem
PowerPoint
Print/Output
Prism
Product News
Product Reviews
Project Management
Prolog
Python
Q&A
Rails
Rake
Razor
Reporting Services
REST
RIA Services
Ruby
Ruby on Rails
Scheme
Search
Security
Services
SharePoint
SignalR
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server 2012
SQL Server CE/AnyWhere/Mobile/Compact
SSIS
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
TFS
Tips
TypeScript
UI Design
UML
User Groups
VB Script
VB.NET
Version Control
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 11
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2011
Visual Studio 2012
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WebMatrix
WF
Whitepapers
Windows 7
Windows 8
Windows Azure
Windows Live
Windows Phone 7
Windows Phone SDK
Windows Server
Windows Vista
WinForms
WinRT
Workflow
WPF
XAML
Xiine Documentation
XML
XNA
XSLT



Learn Now


rssbus
 


Component One

Reader rating:
Click here to read 4 comments about this article.
Article source: CoDe (2010 Jan/Feb)


Article Pages: < Previous - 1 2  3  4 5 - Next >


Introducing Advanced Code Contracts with the Entity Framework and Pex (Cont.)

Add Contracts to Your Entities

As promised at last, I will now explain how to add contracts to model-generated ADO.NET entities. The goals of this demonstration are not only to show you how to define real-world contracts for the Entity Framework, but also to present advanced integration techniques and strategies made possible by the design of Code Contracts. You will see how powerful contract injection can get and why Code Contracts is not just shipped as a simple class library.

"
You can even add contracts to third-party assemblies.
"

For the purpose of this exercise, I will add contracts to Customer, Address, and Product entities generated from the AdventureWorksLT2008 database. As you’ll discover, you have some options before you to do that. The choice of the technique to use depends on the type of contract you need and of the availability of the entities source code. As I’ll demonstrate, you can even add contracts to third-party assemblies, within certain limits. Figure 2 shows the related table schemas of the entities, which I’ll use as a reference to define matching contract clauses.

Click for a larger version of this image.

Figure 2: The Address, Customer, and Product entities related-database table schemas.

The Visual Studio companion solution for this article consists of a few C# projects, and is presented in Figure 3. The Client project is a console application with full runtime checking enabled. You can run it to see the numerous samples presented here in action. I will cover the other projects in the next sections.

Click for a larger version of this image.

Figure 3: The Visual Studio companion solution for this article.

Before starting, please note that you can apply the strategies I’ll be unveiling to any type of project. They are not restricted to ADO.NET entities or the Entity Framework.

Code Contracts Conditions

I’ve been enforcing preconditions in my everyday programming for years, either with homemade class libraries or existing frameworks, such as the Enterprise Library Validation Application Block (VAB) (http://entlib.codeplex.com). Some time ago, as part of the Enterprise Library Contrib project (http://entlibcontrib.codeplex.com), I provided an ArgumentValidation class, which enables you to validate method arguments using the VAB validators without the burden of the Policy Injection Application Block Validation Call Handler:

ArgumentValidation.Validate(
  "arrayIndex", arrayIndex,
  new RangeValidator(0, 9));

What I like about the VAB validators is that they look nice; just by seeing their names you understand what your code is doing. Besides that, they centralize comparison logic in one single unit of work.

With the Code Contracts Library, the previous statement would look like this:

Contract.Requires(arrayIndex >= 0 && 
                  arrayIndex <= 9); 

One of the first things I thought of when I started using Code Contracts was: Wouldn’t it be cool if the Code Contracts Library had something to make my conditions look as nice as the VAB validators? What about some helpers to make the code more readable?

So, here come the Code Contracts Conditions. They’re a small bunch of extension methods I created to provide centralized comparison logic for the contract clauses. The Conditions are available as part of the Code Contracts Extensions project on CodePlex (http://ccextensions.codeplex.com). Each of these methods is flagged with the Pure attribute, a Code Contracts attribute which indicates that the callee has no visible side-effect from the caller point of view:

[Pure]
public static bool IsInRange<T>(
  this T value, T lowerBound, T upperBound) 
  where T : IComparable<T>
{
  Contract.Requires(!value.IsNull());

  return value.CompareTo(lowerBound) >= 0 && 
         value.CompareTo(upperBound) <= 0;
}

Because extension methods are static, you can invoke them as extensions or call them directly:

Contract.Requires(arrayIndex.IsInRange(0, 9));
Contract.Requires(
  Condition.IsInRange(arrayIndex, 0, 9));

Feel free to visit CodePlex and propose your own extensions. The followings are some more examples of the Conditions in action:

Contract.Requires(!customer.IsNull());
Contract.Requires(!collection.IsNullOrEmpty());
Contract.Requires(value.IsMatch("^[a-z]*$"));
Contract.Requires(Contract.ForAll(
  positiveNumbers, 
  (int number) =number.IsGreaterThan(0)));

I don’t recommend using the Code Contracts Conditions with static checking. Although you can have the Static Contract Verifier understand some of the Conditions by providing the Ensures method to describe the return values, in general it lacks, for now, the ability to evaluate methods with undeterminable or complex contracts (such as Regex::IsMatch). Again, I choose to take full advantage of runtime checking versus static checking.

Since I’ll be using the Code Contracts Conditions while adding contract clauses to the ADO.NET entities, I included the CodeContractsExtensions project directly in the Visual Studio companion solution for the article, where it’s referenced by those of the other projects that need it.

Interface Preconditions and Postconditions

The C# project Entities in Figure 3 contains an ADO.NET Entity Data Model which was used to generate the Customer and Address entities in the EntitiesModel.Designer.cs file:

public partial class Customer : EntityObject //...
public partial class Address : EntityObject //...

I’ll start with the Customer entity. It comes with a bunch of properties like FirstName, LastName, Phone, and others that match the Customer table schema introduced in Figure 2. What you want to do is to add contracts to these properties and make sure that the value for each property behaves accordingly to the schema.

You could directly edit the generated code and insert your clauses there, but this is a very bad practice, as any regeneration of the Customer class from the model would erase all your changes. There’s a better way: Since Customer is a partial class, you can extend it in a separate file.

But how can you extend properties in one file if the code of these properties is in another file? The magic comes from the Contract Rewriter. Remember that it injects contracts in your assemblies after compilation. I also mentioned earlier that contracts can be inherited. All you have to do is to figure out a way to tell the Contract Rewriter that your Customer properties inherit the contracts you want them to enforce.

The solution turns out to be pretty simple: you’ll add to the Customer class an interface whose signature matches that of the Customer properties. Figure 4 demonstrates that by using the refactoring features of Visual Studio, you can select the Customer class and, thru the context menu, extract its interface. This way, you can create the ICustomer interface.

Click for a larger version of this image.

Figure 4: Extracting the ICustomer interface.

After that, you augment ICustomer with a special Code Contracts attribute, ContractClass. Then define a dedicated contract class for ICustomer, ICustomerContract, which you also decorate with an attribute, ContractClassFor. What is left to do is to have the ICustomerContract class inherit from the ICustomer interface and implement the interface explicitly. It is in that implementation that you can define your contracts for the ICustomer interface. Note that interface contracts are always provided by a concrete class.

Listing 5 presents the ICustomer interface, the ICustomerContract class, and a sample contract for the Phone property. As you can see, you can specify contracts to match the database schema requirements as well as strengthen them-here by refusing a null value and adding a regular expression that must be matched by the phone number.

To make the Customer class inherit your contracts, you simply indicate that it implements the ICustomer interface by using a separate Customer.cs file:

public partial class Customer : ICustomer
{
}

When the Contract Rewriter runs over the Entities assembly, it will automatically inject the contracts from the ICustomer interface into Customer’s properties. Since the rewriting occurs at the assembly level, your entity generated-code is left untouched.

As an example of the benefits you get from using Code Contracts, any attempt to make an invalid Phone assignment will now immediately trigger a contract failure:

Customer customer = new Customer();
customer.Phone = "0123xyz";
/* Precondition failed: value.IsMatch(@"^(\d{3}-
\d{3}-?\d{4}|1 \(\d{2}\) \d{3} \d{3}-\d{4})$") */

LINQ to Entities

If you use Linq to Entities, you can benefit from having contracts in place. However, keep in mind that you must manipulate the strongly typed entities containing the contract clauses:

Entities entities = new Entities();
IQueryable<Customercustomers =
  (from customer
   in entities.Customer
   select customer).Take(5);

foreach (Customer customer in customers)
  Console.WriteLine("{0}: {1}",   
    customer.FirstName, customer.EmailAddress); 

This means that if you create anonymous types, you must first convert them to full-blown entities to take advantage of your contracts, as shown in Listing 6. Remember that only the corresponding fields in the strongly typed entities are initialized. If you try to access uninitialized ones, you may trigger contract failures depending of the nature of your contract clauses.

Third-party Contract Reference Assembly

Previously, you altered the Customer partial class. Sometimes, you may not have access to your entity’s source code. One very cool feature of Code Contracts is that you can create contracts for assemblies even if you don’t have their source code.

The ThirdPartyEntities project of the companion solution contains an ADO.NET Entity Model that defines a Product entity. For the purpose of this demonstration, pretend that the project comes from a third party and that you can’t modify it. Instead of using a project reference when you need it, you’ll use a direct assembly reference.

So, how can you add contracts to the Product entity contained in the ThirdPartyEntities project without modifying it? The first thing to do is to create another project whose output assembly bears the same name (that is, ThirdPartyEntities). This is what I’ve done with the ThirdPartyEntities.Contracts project. Then, in its Code Contracts property pane (Figure 1), you must check the Build a Contract Reference Assembly option.

After that, you define the same Product class in the ThirdPartyEntities.Contracts project. The difference is that the implementation of the class will only contain the contract clauses you want to apply to the Product class. Listing 7 shows what this skinny Product class looks like.

When you compile the ThirdPartyEntities.Contracts project, it will create the ThirdPartyEntities.dll and ThirdPartyEntities.Contracts.dll assemblies. This latter assembly contains the contracts you have defined for the Product entity. To use it in the Client application, don’t reference the assembly; instead, go to the Client project’s Code Contracts property pane (Figure 1) and add the path to ThirdPartyEntities.Contracts.dll in the LibPaths box:

..\..\..\ThirdPartyEntities.Contracts\bin\Debug 

To make your Requires method kick-in in the Client project, you also must check the Call-site Requires Checking option.

When you build the Client project, the Contract Rewriter will pick up ThirdPartyEntities.Contracts and do its magic with the Product entity. But be warned! There are important differences between using a contract reference assembly in that fashion and implementing contracts directly in your entities. First, the Contract Rewriter creates proxies for the Product methods and properties; it doesn’t inject the contracts into the Product class itself. Calls from the Client application to the Product entity will use these proxies, which contain the contracts, when calling the original methods and properties. Also, keep in mind that since the third-party assembly isn’t instrumented with contracts, any internal calls it makes won’t benefit from your contracts.

Furthermore:

  • Only the Requires method is enforced by proxies.
  • If you derive a type from a third-party assembly class or interface, it will inherit contracts from a contract-reference assembly only for methods and properties it overrides.
  • Invariants are not inherited.
  • On the bright side, if you look again at Listing 7, you’ll see that I’ve done something that I couldn’t have done by using an interface while working with the Customer entity: provide a contract for a static method.

In the end, building a contract reference assembly is powerful, but it has its limitations. If you are curious about this feature, explore the standard Microsoft .NET contract assemblies that ship with Code Contracts; this is the implicit way you use them.

&


Blogs

Jonathan "Peli" de Halleux has an active Blog about Pex at http://blog.dotnetwiki.org.

You can also visit http://winsharp93.wordpress.com/tag/code-contracts for some blogging on Code Contracts.


Forums

Join the discussions about Code Contracts at http://social.msdn.microsoft.com/Forums/en-US/codecontracts or Pex at http://social.msdn.microsoft.com/Forums/en-US/pex.


CodePlex Code Contracts Extensions Project

The Visual Studio companion solution for this article, the Code Contracts Conditions, and the support classes for object validation, self validation, and lazy initialization are all available at http://ccextensions.codeplex.com.


Visual Studio Editions

As of this writing, both Code Contracts and Pex are pre-release software, but they come with commercial licenses and you can start using them today.

The Contract Rewriter is currently available with Visual Studio Standard Edition or higher and the Static Contract Verifier with Visual Studio Team System.

Pex only works with Visual Studio Team System Development Edition or Visual Studio Team System Test Edition.

Both projects are compatible with Visual Studio 2008 or 2010 and will mostly remain separate downloads after Visual Studio 2010 is released.



Listing 5: Customer interface contract
[ContractClass(typeof(ICustomerContract))]
public interface ICustomer
{
  int CustomerID { getset; }
  string FirstName { getset; }
  string LastName { getset; }
  string Phone { getset; }
  // Code skipped...
}

[ContractClassFor(typeof(ICustomer))]
public class ICustomerContract : ICustomer
{
  string ICustomer.Phone
  {
    get
    {
      Contract.Ensures(!Contract.Result<string>().IsNull());
      Contract.Ensures(
        Contract.Result<string>().Length.IsInRange(1, 25));
      Contract.Ensures(Contract.Result<string>().IsMatch(
        @"^(\d{3}-\d{3}-?\d{4}|1 \(\d{2}\) \d{3} \d{3}-\d{4})$"));
      return default(string);
    }
    set
    {
      Contract.Requires(!value.IsNull());
      Contract.Requires(value.Length.IsInRange(1, 25));
      Contract.Requires(value.IsMatch(
        @"^(\d{3}-\d{3}-?\d{4}|1 \(\d{2}\) \d{3} \d{3}-\d{4})$"));
      Contract.Ensures(((ICustomer)this).Phone == value);
    }
  }
  // Code skipped...
}


Listing 6: LINQ to Entities and anonymous type conversion
Entities entities = new Entities();
var anonymous =
  (from customer in entities.Customer
   select new
   {
     FirstName = customer.FirstName,
     EmailAddress = customer.EmailAddress
   }).Take(5);

List<Customercustomers = anonymous.AsEnumerable().Select(
  c => new Customer 
  { 
    FirstName = c.FirstName, 
    EmailAddress = c.EmailAddress 
  }).ToList();

foreach (Customer customer in customers)
  Console.WriteLine("{0}: {1}",
    customer.FirstName, customer.EmailAddress);


Listing 7: Product contract reference assembly class
public partial class Product : EntityObject
{
  public static Product CreateProduct(
   int productID, string name, string productNumber, 
   decimal standardCost, decimal listPrice, 
   DateTime sellStartDate, Guid rowguid, DateTime modifiedDate)
  {
    Contract.Requires(!name.IsNull() && 
      name.Length.IsInRange(1, 50));
    Contract.Requires(!productNumber.IsNull() && 
      productNumber.Length.IsInRange(1, 25));
    Contract.Requires(standardCost.IsGreaterThan(0m));
    Contract.Requires(listPrice.IsGreaterThan(0m));
    Contract.Requires(!sellStartDate.IsDefault());
    Contract.Requires(!rowguid.IsDefault());
    Contract.Requires(!modifiedDate.IsDefault());
    return default(Product);
  }

  public int ProductID
  {
    get return default(int); }
    set { Contract.Requires(value.IsGreaterThan(0)); }
  }
  // Code skipped...
}


Article Pages: < Previous - 1 2  3  4 5 - Next Page: 'Advanced Concepts' >>

Page 1: Introducing Advanced Code Contracts with the Entity Framework and Pex
Page 2: Behind the Scenes
Page 3: Add Contracts to Your Entities
Page 4: Advanced Concepts
Page 5: Multithreading
Page 6:
Page 7:
Page 8:

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
3.7 out of 5

26 people have rated this article.

Hacker Halted

      Sharepoint TechCon

 

RssBus