views:

338

answers:

3

Here is the problem : our main class (say : Contract) change every year. Some properties are added, other are removed. We don't know how it will look next year. It may change a lot or not at all.

On the other hand, we now (new requirement...) have to keep an historic of every contracts. Each time the user update a contract, the whole object must be stored in a backup (e.g. - serialized in a table).

Of course, we must be able to read it back... One option (brutal) is to have a new Contract class every year (Contract2008, Contract2009, ...).

But it would be very cumbersome (and ugly) since a lot of classes depend on Contract - in facts, we would have to create a bunch of new classes every year.

Ever have this kind of problem ? Any suggestion ?

Thanks in advance !

(We're using C# 2.0.)

ADDED : Thank for your answers. We're now asking ourself how we could use a dictionary / an XML file to implement versioning without breaking all the code. Dictionary seems very sexy in this context :o)

+2  A: 

First thing I can think off the to of my head. Implement a sort of "Capabilities" document. A list (or an XML document) detailing the contact version and what properties it contains.

Each function that operates on Contract should check if particular properties ("capabilities") are supported.

For example:

Contract2008 Capabilities
-----
has Name
has Stipulations
can DoMagic
-----
>     
>     Contract2009 Capabilities
>     -----
>     has Name
>     has Stipulations
>     can DoMagic
>     -----

The contract class would store the capabilities document and some generic getters setters.

Contract
  GetCapabilities()
  Set(field, value)  
  Get(field, value)

The set and get would check if the field is supported in the capabilities before setting or getting the value.

(This must be a pattern or something, anyone?)

moogs
+2  A: 

Quite likely you don't have to implement properties as C# properties. You could actually store properties in some kind of dictionary and use Get and Set methods to read them/enumerate them. In that case, you can use the same class every year.

If the properties really have to be properties, then I'd recommend building a new assembly with the class every year, and loading the assembly dynamically. You can then use reflection to see what properties are supported by each Contract object. To make your life easier, I'd suggest you have an interface for properties that do not change, and to make it simpler to identify the Contract class in the assembly.

Danut Enachioiu
+3  A: 

Stop serializing the object. Store the data relationally. Serialization is intended for short durations, say like streaming across the wire; not permanent storage.

Instead of coding the fields into the class; it sounds like you might need more of dictionary sort of structure that can dynamically pull fields based on database configuration values stored by year. Then build a dynamic UI based on those values. Having to create a new class each year and test the code seems impossibly expensive to maintain.

DancesWithBamboo