So by now, you have probably heard a lot about “code contracts”, a new feature in .NET 4.0 that allows you to decorate your methods and properties with things like pre- and post conditions. I’ve seen them mentioned a lot and I’ve seen quite a few basic demos that explain the different types of contracts how to add them to your methods.
A simple example usually starts off looking something like this:
public IEnumerable<Employee> FindEmployees(string firstName) { var employees = from e in _employees where e.FirstName.StartsWith(firstName) select e; return employees.ToList(); }
When decorated with some code contracts, it might look more like this instead
public IEnumerable<Employee> FindEmployees(string firstName) { Contract.Requires(firstName != null); Contract.Requires(firstName.Length > 3); Contract.Ensures(Contract.Result<IEnumerable<Employee>>() != null); var employees = from e in _employees where e.FirstName.StartsWith(firstName) select e; return employees.ToList(); }
However, I’ve had a hard time getting around the fact that I just don’t like the look of this code. My biggest gripe; the contracts always seem to be put in the implementation of a class and not where you’d think they belong, on the interface (or, with an other word “contract”).
Most likely, the method above is an implementation of some kind of interface, perhaps something like this:
public interface IEmployeeService { IEnumerable<Employee> FindEmployees(string firstName); }
But since code contracts use methods for setting your conditions, you cannot put them directly on the interface. Then what do you do if you want to separate the contract from the implementation? Well, there’s an attribute for that! (or actually, there are a couple of attributes for that..)
The process is quite simple; create an abstract class that implements your interface1) and add the ContractClass attribute to your interface and the ContractClassFor attribute to the abstract “buddy” class:
[ContractClass(typeof(EmployeeServiceContracts))] public interface IEmployeeService { IEnumerable<Employee> FindEmployees(string firstName); } [ContractClassFor(typeof(IEmployeeService))] internal abstract class EmployeeServiceContracts : IEmployeeService { public IEnumerable<Employee> FindEmployees(string firstName) { Contract.Requires(firstName != null); Contract.Requires(firstName.Length > 3); Contract.Ensures(Contract.Result<IEnumerable<Employee>>() != null); return default(IEnumerable<Employee>); } }
This way your implementation can stay simple and the contract is placed where it belongs. And if you’re anything like me, you’ll also be happy that it’s now possible to separate the interface and contract into their own assembly – far away from any implementations!
1) Note that it is completely optional to add contracts to all methods of the interface since the class is abstract. Also, it may be worth to mention that what you do after the Contract-calls doesn’t really matter. The “return default(…)” is there only to satisfy the compiler. If you want, you can replace it with a throw NotImplementedException() or something similar. Neither the static checker nor the runtime rewriter will actually run the code but only use it for reference.
Leave a Reply