Search code examples
c#wcfdatacontractserializerdatacontract

Change location of a type in knowntypes with Backward compatibility


I want to change the assembly of a type but still be backward compatible with old clients for which the type is located in a different assembly

My old known types is

<add type="Messages.GetImageRoutingRulesResponseMessage, Feeder.Data">
      <knownType type="Rules.DicomPushRule, Feeder.Logic" />
</add>

and I changed the location of the DicomPushRule to Feeder.Data , so my new knowntypes will look like this :

<add type="Messages.GetImageRoutingRulesResponseMessage, Feeder.Data">
          <knownType type="Rules.DicomPushRule, Feeder.Data" />
</add>

Will this be backward compatible?


Solution

  • It depend on you contracts.

    Let's consider two options:

    1. You have two the same class, but in different namespaces:

      DataContract:

      namespace Feeder.Contract
      {
          [DataContract]
          public class DividendBase
          {
              [DataMember]
              public DateTime AnnouncementDate { get; set; }
          }
      }
      
      namespace Feeder.Logic
      {
          [DataContract]
          public class Dividend : DividendBase
          {
              [DataMember]
              public float Amount { get; set; }
              [DataMember]
              public DateTime ExDate { get; set; }
          }
      }
      
      namespace Feeder.Data
      {
          [DataContract]
          public class Dividend : DividendBase
          {
              [DataMember]
              public float Amount { get; set; }
              [DataMember]
              public DateTime ExDate { get; set; }
          }
      }
      

      For this case classes are not compatible, as they have different namespaces and will look differently in xml.

      Serialized in xml:

      <DividendBase i:type="a:Dividend"
                    xmlns="http://schemas.datacontract.org/2004/07/Feeder.Contract"
                    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:a="http://schemas.datacontract.org/2004/07/Feeder.Logic">
        <AnnouncementDate>0001-01-01T00:00:00</AnnouncementDate>
        <a:Amount>1.2</a:Amount>
        <a:ExDate>2014-05-20T12:21:42.3608838+03:00</a:ExDate>
      </DividendBase>
      
      <DividendBase i:type="a:Dividend" 
                    xmlns="http://schemas.datacontract.org/2004/07/Feeder.Contract" 
                    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:a="http://schemas.datacontract.org/2004/07/Feeder.Data">
        <AnnouncementDate>0001-01-01T00:00:00</AnnouncementDate>
        <a:Amount>1.2</a:Amount>
        <a:ExDate>2014-05-20T12:23:21.2888838+03:00</a:ExDate>
      </DividendBase>
      
    2. But if you apply NameSpace attribute for both classes, they will be compatible.

      Data contract with NameSpace in attribute:

      namespace Feeder.Contract
      {
          [DataContract]
          public class DividendBase
          {
              [DataMember]
              public DateTime AnnouncementDate { get; set; }
          }
      }
      
      namespace Feeder.Logic
      {
          [DataContract(Namespace = "Feeder.Contracts")]
          public class Dividend : DividendBase
          {
              [DataMember]
              public float Amount { get; set; }
              [DataMember]
              public DateTime ExDate { get; set; }
          }
      }
      
      namespace Feeder.Data
      {
          [DataContract(Namespace = "Feeder.Contracts")]
          public class Dividend : DividendBase
          {
              [DataMember]
              public float Amount { get; set; }
              [DataMember]
              public DateTime ExDate { get; set; }
          }
      }
      

      And XML for both:

      <DividendBase i:type="a:Dividend" 
                    xmlns="http://schemas.datacontract.org/2004/07/Feeder.Contract"
                    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:a="Feeder.Contracts">
        <AnnouncementDate>0001-01-01T00:00:00</AnnouncementDate>
        <a:Amount>1.2</a:Amount>
        <a:ExDate>2014-05-20T12:25:54.7178838+03:00</a:ExDate>
      </DividendBase>
      
      <DividendBase i:type="a:Dividend"
                    xmlns="http://schemas.datacontract.org/2004/07/Feeder.Contract"
                    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:a="Feeder.Contracts">
        <AnnouncementDate>0001-01-01T00:00:00</AnnouncementDate>
        <a:Amount>1.2</a:Amount>
        <a:ExDate>2014-05-20T12:26:41.1278838+03:00</a:ExDate>
      </DividendBase>
      

      As you can see, xml's are the same, thus the classes are compatible.

    If you have first variant, then, I am afraid, you have incompatible classes.