Archived

This forum has been archived. Please start a new discussion on GitHub.

Versioning on data contracts

I have a type

struct Message {
int intValue;
};

interface Server {
void Send(Message message};
};

The issue I would like to solve is similar to WCF where new parameters are optional and server code can deal with it. Hence I would like to alter message to be

struct Message {
int intValue;
string stringValue;
};

I would re-build the server however I would like it to work with all clients, old message or new. I have looked at facets however that seems more about interface changes.

I thought about changing struct Message to a class and then add operations such as

class Message {
int intValue;
string stringValue;
void SetInt(int value); ..... etc
};

Could this then be versioned such as later on if I needed to add another method, and data member I could, again using facets. Thought not sure how. This is mainly because anything to do with facets is about interfaces. I read that methods on class are called by using string naming rather than ordinals so if I added a new method then only clients using it would care, however would Ice be able to deserialise the data of stringValue on a client running with the old version of class? Would be good to know this even if not the correct way.

The more I think about this I may have solved it myself, what I need to do is create Message2 and new methods on the existing server (i.e. the interface) that take Message2 and then use facets as described. The server would host both facets and clients would pick and choose.

I would prefer versioning on the data contract though, with optionality if that were possible?

Comments

  • benoit
    benoit Rennes, France
    Hi,

    Yes, versioning the interface using facets is one option. You'll find more information on this in Michi's article Can a Leopard Change its Spots?. If you only want to version the data contract another option is to use class inheritance:
    class Message
    {
    int intValue;
    };
    
    class Message2 extends Message
    {
    string stringValue;
    };
    
    

    The server can then use Message2Ptr::dynamicCast(message) to figure out whether or not the received object is an instance of the Message or Message2 Slice class.

    Cheers,
    Benoit.