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



LearnNow


XAMALOT
 


SSWUG

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.)

Advanced Concepts

Now I’ll introduce advanced programming techniques. You don’t have to master these concepts in order to use Code Contracts, but if you want to take them to another level and improve your software development skills, don’t overlook this section.

Object Validation

As a supplier, the Customer entity now implements contracts for its properties and any client will benefits from and be forced to abide by the rules you have set. Now what? Should you be content with that? Not yet. How can a client of the Customer entity knows that it can safely start using an instance of the class? All you have provided are safeguards against misuses of the entity properties. Because an ADO.NET entity must supply a parameterless constructor, nothing prevents an instance of Customer to be created and passed around without having its properties properly initialized. Sure, a contract violation will be detected at some point, but not necessarily at the best of times. Now that you have contracts in place, however, you can do better: you can provide an implicit overall contract stating that a Customer instance is valid as a whole.

The idea is not a new one. Again, I bring an Enterprise Library concept to Code Contracts. The Validation Application Block comes with an ObjectValidator whose purpose is to validate the instance of a class based on validation attributes applied to its properties or fields. If all specified validations are satisfied, an object is said to be valid. Now, you don’t need the VAB anymore, you’ve got contracts!

You could think first of using invariants to make sure that an object is in a valid state, but since invariants apply at all times, even on parameterless constructors, they’re not the best fit for a solution. Also, they don’t apply on property getters. Furthermore, you wouldn’t want to specify invariants to validate all Customer properties, since the properties themselves already provide their contracts.

To introduce in Code Contracts the concept of object validation in an Enterprise Library-like fashion, you have to agree to this principle: If all the properties of an object have valid contracts, then the instance itself is considered in a valid state. To enforce that, you simply have to invoke all the getters to trigger the validation of their contract clauses.

I provide the object validation feature for Code Contracts with the extension method IsValid, which you can use to validate an instance anywhere in your code, including as part of a contract clause. The IsValid method works with the ContractValidation attribute, which you can apply to a class, interface, or property. When you use the ContractValidation attribute on a class or interface, the IsValid method verifies all the properties of that class or interface. When not set to such a level, you can apply the ContractValidation attribute to specific properties to limit validation to those properties. Furthermore, the IsValid method also processes non-public properties.

Thus, to make the Customer entity support object validation, you just add the ContractValidation attribute to the ICustomer interface of Listing 5:

[ContractValidation]
[ContractClass(typeof(ICustomerContract))]
public interface ICustomer

Now, whenever a client invokes the IsValid method on a Customer instance, each contract clause in the getters of the ICustomer entity properties will be checked. The IsValid method will return true only if all contracts are verified successfully:

Contract.Requires(customer.IsValid());

When a contract clause using the IsValid method fails, you don’t get the information about which property is in error, but you can take advantage of the debugger and explore your object properties to find out, as shown in Figure 5.

Click for a larger version of this image.

Figure 5: Exploring customer properties and contract failures while debugging.

As an alternative, you can call the method ContractValidationAttribute.Validate, which coldly throws a ContractValidationException if a contract clause is violated. This exception exposes a PropertyInfo instance describing the property that failed.

As you can presume, the IsValid method indirectly uses reflection and its evaluation can be a costly operation. Choose wisely the places in your code where you invoke it. Note also that the validations work only if you’ve set the contract run-time behavior to throw exceptions on contract failures.

You’ll find the IsValid method, the ContractValidation attribute and ContractValidationException as part of the Code Contracts Extensions project on CodePlex.

Self Validation

The Enterprise Library Validation Application Block also has the concept of self validating objects, whereas one class can supply a method whose role is to validate an instance state. Although the Code Contracts Extensions don’t provide anything specific for that feature, you can implement self validation by extending the object validation technique presented in the previous section and using a dedicated property to do your validations:

[ContractValidation]
private bool SelfValidates
{
  get
  {
    Contract.Requires(
      !this._FirstName.IsNullOrEmpty());
    
    Contract.Requires(
      !this._LastName.IsNullOrEmpty());

    return true
  }
}

Only apply the ContractValidation attribute to your property if you want self validation to be evaluated in the IsValid method calls alongside other object validations. Otherwise, invoke the self validation property directly.

Lazy Initialization

Sometimes, having strong contracts can become a burden. When you define very strict clauses in an entity, you may trigger exceptions when you don’t want to.

Let’s say you have the following contract for the Address entity, which ensures it’s never null and is within a given length:

string IAddress.CountryRegion
{
  get
  {
    Contract.Ensures(
      !Contract.Result<string>().IsNull() &&
      Contract.Result<string>().Length.IsInRange(
      1, 50));
    return default(string);
  }
  // Setter skipped
}

Then, assume that you’re getting an Address instance from a simple factory (which doesn’t set any property value):

public class AddressFactory
{
  public static Address GetNewAddress()
  {
    Contract.Ensures(
     !Contract.Result<Address>().IsNull());
    return new Address();
  }
}

You now need to initialize the Address properties, but may have to perform some logic on them to do that. In the code snippet below, I check the value of the CountryRegion property before initializing it, but because its getter contract states that its return value can’t be null-and that its value is effectively null (not initialized by the factory), I’ll get a contract exception when calling the getter:

Address address = AddressFactory.GetNewAddress();
if (address.CountryRegion == null// Throws
  address.CountryRegion = GetCountry(address);

This is a situation where you perform lazy initialization (or delayed construction) of your object. This scenario occurs frequently when you have a default parameterless constructor or when proper initialization is not enforced by a constructor. This is the case here with an ADO.NET entity, but the same issue could also arise with an Inversion of Control Container or Data Transfer Objects exposed by Web Services, among others.

To fix the problem, you need some kind of lazy contract evaluation. You want the CountryRegion getter contract to be effective, but not while you’re initializing your Address entity. The solution comes in two parts: managing the initialization state and defining better contracts.

In order to manage the initialization, you can use the IInitializable interface. This interface defines a single property, IsInitialized. The contract for the IsInitialized property stipulates that once you set the property to true, the implementing object must have a valid state. So, it makes sure that you can’t set an object as initialized if it’s not properly constructed. Listing 8 presents IInitializable and its contract. Naturally, since the object validation technique is used here with a call to the IsValid method, the implementing class must support it.

Now that you have the IInitializable interface, you can use its IsInitialized property value in other contracts to implement laziness. If you go back to the CountryRegion getter presented earlier, you can rewrite it like this:

string IAddress.CountryRegion
{
  get
  {
    Contract.Ensures(
      // Laziness
      (this is IInitializable &&
       !((IInitializable)this).IsInitialized) ||
      // Contract
      (!Contract.Result<string>().IsNull() &&
       Contract.Result<string>().Length.
         IsInRange(1, 50)));

    return default(string);
  }
  // Setter skipped
}

The first part of the statement checks if the Address object is initialized; if not, it doesn’t enforce the contract clauses. However, if the Address is set as initialized, the contract kicks-in.

Invariants can also benefit from laziness; they just have to check the IsInitialized property before deciding whether to apply their contract. Invariants are automatically validated when you set the value of the IsInitialized property to true, because they are injected in the setters by the Contract Rewriter. Listing 9 shows the Address entity with full lazy contract evaluation. You can now perform lazy initialization without a problem:

Address address = AddressFactory.GetNewAddress();
if (address.CountryRegion == null// Safe
  address.CountryRegion = GetCountry(address);
// Other initiatizations skipped...
address.IsInitialized = true// Auto-validated

You may have noticed earlier on that the Ensures clause in the new CountryRegion getter contract verifies with the is operator that the current instance (this) implements IInitializable. This is a very powerful condition to add to your lazy contracts. IAddress and IInitializable are two distinct interfaces; you have no guarantee whatsoever that an Address class would implement both. By adding the is statement check, laziness is only enabled in the postcondition if the implementing class also implements IInitializable. Otherwise, the contract clause behaves exactly like the strong one introduced at the beginning of this section. If you download the companion code of this article, see how the Address contract behavior changes just by removing IInitializable from the list of interfaces it implements!

Note that IInitializable and its contract are also among the things you’ll get from the Code Contracts Extensions project on CodePlex.

Error Handling

The importance of an adequate error handling mechanism in a software system is often underestimated. The Code Contracts team has worked hard to provide you with many interception points to manage contract violations.

The first thing to understand is that, while Code Contracts supports exceptions, the overall design of the run-time error handling subsystem is not necessarily exception-based. It instead allows any type of error management you deem appropriate.

Another thing to note about throwing exceptions is that while Requires<> gives you the ability to throw a specific exception, it only allows you to specify a string message for it. If your exception needs additional arguments, you must resort to what is called legacy requires, which use the old if/throw pattern. Such code behaves similarly to Requires<>, but provides better exception support:

void SampleLegacyRequires(Customer customer)
{
  if (!customer.IsValid())
    throw new CustomerException(customer);
  Contract.EndContractBlock();

  // Implementation skipped...
}

While that feature is available to emulate Requires, it isn’t available for Ensures and the other contract clauses.

You can also alter the default run-time contract behavior by defining a class implementing specific handlers. Listing 10 presents the CustomContractsRuntime class, which I created to illustrate error handling customization. CustomContractsRuntime mostly simulates the default run-time contract behavior. Notice the TriggerFailure method: this is where you specify how errors should be handled.

Remember the code injection of the Contract Rewriter introduced in Listing 3? Take a good look at it again and you’ll see that it involves __ContractsRuntime and CustomContractsRuntime calls. This is because the Contract Rewriter injected calls to my custom run-time contract behavior class. I enabled this by configuring the Custom Rewriter Methods in the Code Contracts property panel (Figure 1). For the Assembly I specified CodeContractsExceptions and for the Class I specified CoDeMagazine.CodeContracts.CustomContractsRuntime.

Be aware that you must specify the run-time contract behavior in all the projects you want to customize: keep in mind that this alters the way the target assembly is rewritten and that these specialized methods are not global handlers. In the companion solution, I configured the custom behavior only for the Client application; the other projects still throw standard ContractException exceptions.

When I first experimented with run-time contract behavior, I was a bit puzzled by the fact that there are differences in the methods called by the contracts clauses. To help you demystify their workflow, I present it in Figure 6.

Click for a larger version of this image.

Figure 6: Run-time contract behavior.

Run-time contract checking also provides a global event, Contract.ContractFailed, which is raised when contracts are violated. That event is system-wide and works across assemblies. This is the preferred way of intercepting contract clause errors in your application:

Contract.ContractFailed += (sender, e) =>
  Console.WriteLine(e.Message);

The ContractFailed event argument is ContractFailedEventArgs. You can use it in your handler to mark the error as handled and continue with the normal execution path by calling the SetHandled method, or to force the triggering of the failure after all handlers have executed by invoking the SetUnwind method.

Although ContractFailedEventArgs contains information about the state and nature of the current error, it doesn’t provide you with the exceptions raised by a legacy requires or Requires<>, because those exceptions aren’t thrown yet when the ContractFailed event fires.

&


Listing 8: IInitializable
public interface IInitializable
[ContractClass(typeof(IInitializableContract))]
{
  bool IsInitialized { getset; }
}

public class IInitializableContract : IInitializable
[ContractClassFor(typeof(IInitializable))]
{
  bool IInitializable.IsInitialized
  {
    get
    {
      return default(bool);
    }
    set
    {
      Contract.Ensures(
        ((IInitializable)this).IsInitialized == value);
      Contract.Ensures(
        !((IInitializable)this).IsInitialized || this.IsValid());
      
      // Invariants using IsInitialized will automatically 
      // kick-in when value is true.
    }
  }
}


Listing 9: Address entity with lazy contract evaluation
public partial class Address : IAddress, IInitializable
{
  // Simulates lazy-init property invariant at run time.
  public Coordinate Coordinate { getset; }

  [ContractInvariantMethod]
  protected void ObjectInvariant()
  {
    Contract.Invariant(!IsInitialized ||
                       !Coordinate.IsNull());
  }

  private bool isInitialized;
  public bool IsInitialized
  {
    get
    {
      return EntityState != System.Data.EntityState.Detached || 
             this.isInitialized;
    }
    set
    {
      this.isInitialized = value;
    }
  }
}


Listing 10: Custom run-time contract behavior
public class CustomContractsRuntime
{
  [DebuggerStepThrough]
  public static void Requires(
    bool condition, string message, string conditionText)
  {
    // Simulates default behavior.
    if (!condition)
      ReportFailure(ContractFailureKind.Precondition, 
                    message, conditionText, null);
  }

  // Code skipped...

  [DebuggerStepThrough]
  public static void ReportFailure(
    ContractFailureKind kind, string message, 
    string conditionText, Exception innerException)
  {
    // Simulates default behavior.
    string displayMessage = RaiseContractFailedEvent(
      kind, message, conditionText, innerException);
    if (displayMessage != null)
      TriggerFailure(kind, displayMessage, message, 
                     conditionText, innerException);
  }

  [DebuggerStepThrough]
  public static string RaiseContractFailedEvent(
    ContractFailureKind kind, string message, 
    string conditionText, Exception innerException)
  {
    // Simulates default behavior.
    return ContractHelper.RaiseContractFailedEvent(
      kind, message, conditionText, innerException);
  }

  [DebuggerStepThrough]
  public static void TriggerFailure(
    ContractFailureKind kind, string displayMessage, 
    string message, string conditionText, 
    Exception innerException)
  {
    // Don't have access to private ContractException: 
    // we provide our own custom exception class. 
    throw new CustomContractException(
      kind, displayMessage, message, conditionText, 
      innerException);
  }
}


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

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.

Instantly Search Terabytes Of Text
“Lightning Fast”
– Redmond Mag
“Covers all data
sources” – eWeek
25+ fielded & full-text search options
dtSearch’s own document filters highlight hits in popular file types
Web Spider supports static & dynamic data
APIs for .NET, Java, C++, SQL, etc.
Win / Linux (64-bit & 32-bit)
www.dtSearch.com
 

      LearnNow

 

SSWUG