Showing posts with label contracts. Show all posts
Showing posts with label contracts. Show all posts

Sunday, 7 November 2010

Combing Code Contracts with DataContracts for better contract expressiveness and quality

I'm going to write some more about Code Contracts (http://research.microsoft.com/en-us/projects/contracts/) soon, but wanted to show you a neat example of using in combination with DataContracts.

This shows the power of CodeContracts in enforcing more semantic information about a DataContract than is currently expressible in WSDL or DataContracts.

For example take a look at this DataContract:

   [DataContract]
   public class Address
   {
       [DataMember(IsRequired=false)]
       public int? HouseNumber { get; set; }
       [DataMember(IsRequired = false)]
       public string HouseName { get; set; }
       [DataMember(IsRequired = true)]
       public string Street { get; set; }
       [DataMember(IsRequired = true)]
       public string City { get; set; }
       [DataMember(IsRequired = true)]
       public stringRegion { get; set; }
       [DataMember(IsRequired = true)]
       public string Country { get; set; }
       [DataMember(IsRequired = false)]
       public string PostCode { get; set; }
   }

Then we can see that there are several attributes which indicate that they are optional, for example the House Number and House Name. In the UK then many houses will have either one or the other or both. However no address should be missing both, the problem with this contract is that this isn't clear or enforceable.

If we enhance this DataContract with CodeContracts:

   [DataContract]
   public class Address
   {
       [DataMember(IsRequired=false)]
       public int? HouseNumber { get; set; }
       [DataMember(IsRequired = false)]
       public string HouseName { get; set; }
       [DataMember(IsRequired = true)]
       public string Street { get; set; }
       [DataMember(IsRequired = true)]
       public string City { get; set; }
       [DataMember(IsRequired = true)]
       public stringRegion { get; set; }
       [DataMember(IsRequired = true)]
       public string Country { get; set; }
       [DataMember(IsRequired = false)]
       public string PostCode { get; set; }
       [ContractInvariantMethod]
       private void EnforceInvariant()
       {
           Contract.Invariant(HouseNumber > 0);
           Contract.Invariant(!(HouseNumber == null && string.IsNullOrWhiteSpace(HouseName)));
           Contract.Invariant(!string.IsNullOrWhiteSpace(Street));
           Contract.Invariant(!string.IsNullOrWhiteSpace(City));
           Contract.Invariant(!string.IsNullOrWhiteSpace(Region));
           Contract.Invariant(!string.IsNullOrWhiteSpace(Country));
       }
   }

Here you can see I have added a method that is decorated with a ContractInvariantMethod attribute. When you run the code through the Code Contract post compiler then this will ensure that at each point that the class changes that these invariants remain true. I've also added some invariants that ensure that the values are not null, empty or whitespace strings and that the house number is greater than 0. This can be analysed with a static analysis tool, with PEX and CHESS tools for testing and runtime checks.

When I am working with WSDL produced from .NET WCF services then I like to get the DataContract assemblies so that these checks are possible. It is also better to go to the source rather than generating these from the WSDL - as long as the people that wrote the contracts have done the decent thing and put their DataContracts in a separate assembly to isolate it from the other layers and behaviours.

What do you think of this approach - do you think it enhances the data contract? Leave some comments below.

Friday, 1 October 2010

Do WCF Data Contracts have relevance outside of WCF

In working with WCF you will come across DataContract attributes which decorate DTOs. DataContracts are great because they allow you to specify the WCF contract and are much more flexible than the XML serializer used by the original web services in .NET in that you can specify the attributes on prvate fields so you don't need to break encapsulation. It also supports versioning, optional parameters and a much fuller XSD model

However, can we take this feature which appears to have been created for WCF and use it more generically?

My view and way that I use this is for any sort of data contracts between layers of an application, so between the UI and the business tier, between services, between service layers and even into serialized persistent stores (e.g. XML datatype in the database).

Why?

  • It is flexible in terms of versioning, optionality and data encapsulation
  • It is faster than Binary or XML Serialization (in my testing)
  • It creates compact, concise output
It seems Microsoft had this in mind when they created the class as it is placed in the System.Runtime.Serialization namespace.

So I would recommend that you use data contracts when passing data between any layer of an application and enforce that contract to ensure compatibility.

This relates to a number of upcoming articles, so stick with me while I evolve the story around DataContracts and how you might use them across the application from the data tier, to the UI and avoid writing lots of mappers between domain objects, DTOs and persistent entities.

Feel free to give your views on this, either positive or negative in the comments below

Wednesday, 29 September 2010

Loosly coupled systems

Ricco recently posted an article: Less Loosely Coupled Than Meets The Eye which talks about something I have been thinking about for a long time from another perspective. We all try to write loosly coupled systems, and to some extent this is possible, for example using interfaces in code or Web Services to de-couple things.

This works to some extent, and is getting better with features such as Code Contracts in .NET or Data Contracts in Web Services and WCF, however there are always unwritten or assumed behaviours of an API which create dependencies that the architect or developer are unaware of and could cause you to have to re-write and recompile parts or all of your application because of that implied behaviour.

Ways around this can be by using Unit Tests to assert various expectations on the behaviour of dependent code. Mocking frameworks are useful in this situation, but often don't help you to identify when a subtle behaviour in the upstream or downstream system or dependency has changed. Integration testing can certainly help, but it can't ever truely capture all of these complex behaviours in systems.

Ricco says:
"I don’t know that it is possible to write anything like a unitary software
system in a way that is truly loosely coupled. It’s not that you can’t make
boxes and lines that are cleanly separated in all sorts of pretty ways, though
that’s hard enough. The problem is that even if you manage to do that, what you
end up with is actually still pretty tightly coupled.


What do I mean?


Well, let me use Visual Studio as an example. It’s made up of all kinds of
extensions which communicate through formal interfaces. Putting aside the warts
and just looking at how it was intended to work it seems pretty good. You can
make and replace pieces independently, there is a story for how now features
light up; it’s all pretty good. Yes, it could be better but let’s for the moment
idealize what is there. But is it loosely coupled, really?



Well the answer is heck no."

He is correct in that unitary software (e.g. software hosted on the same machine or process or even on the same network) can not be isolated by impact from another part of the system becoming errant and impacting on your perfectly tested, perfectly working software.

The closest we can probably get at the moment with the tools, processes and software we have is to isolate key parts of the system or other systems behind a buffered queue and having data and operation contracts which provide isolation of data changes, to some extent behavioural changes, process memory requirements and CPU time as well as timing and race conditions by ensuring that we only depend on the behaviour of the messaging system (still we are relying on subtle behaviours of the message queue technology).

Does it matter?

In simple systems, probably not. Just ensure that your classes have low cohesion by using interfaces and dependency injection along with unit testing and a mocking framework to verify the state and behaviour of the system.

For medium sized projects you are going to have to do all of the above, plus ensure that you have low cohesion between the systems involved as well as defining your data, operation and version contracts.

For large systems, these are always going to require complex testing of end-to-end systems. However where I think we can make advances is in the testing of the Interface specification.

In interfaces today we go away and write a specification, then each end of the integration go away and write their part, each side will use a stub or driver to ensure that it works while the other side completes their work. Then comes the big-bang integration which costs lots of money and time and usually only results in a system which works for the tested scenario. This is why systems integration projects are so difficult.

Think of an analogy to this: HTML and CSS. This is a 20 year old spec which has gone through five versions and yet browser manufacturers still render the same HTML very differently. They are moving in the right direction with the ACID and the W3C test suites which allow the implementations to be tested.

So this presents a way forward. Write a spec for your interface; define the data and operation contracts as well as the versioning story. Then write a program which can sit between the sides of the interface and can provide a common set of behaviours between the two. At least then the systems will be dealing with the same "bugs" in the behaviour. Don't have each implementor write a stub or driver which will differ, but provide something they can actually run against.