Tuesday, April 13, 2010

Silverlight Serialization – Avoiding having public setters in Properties

In Silverlight you cannot use Reflection to call a non-public setter on a class unless you are in the scope of the class. This has a side-effect in serialization because it requires having public setters for all properties that must be serialized. Well that is not really the case. You can make them internal and use the InternalsVisibleTo attribute to expose those internals to the Microsoft serialization assemblies like this:

   1: [assembly: InternalsVisibleTo("System.Runtime.Serialization, PublicKey="
   2:     + "00240000048000009400000006020000002400005253413100040000010001008D56C76F9E86493"
   3:     + "83049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E"
   4:     + "9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4"
   5:     + "BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B"
   6:     + "37AB", AllInternalsVisible = true)]
   7:  
   8: [assembly: InternalsVisibleTo("System.ServiceModel.Web, PublicKey="
   9:     + "00240000048000009400000006020000002400005253413100040000010001008D56C76F9E86493"
  10:     + "83049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E"
  11:     + "9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4"
  12:     + "BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B"
  13:     + "37AB", AllInternalsVisible = true)]
  14:  
  15: [assembly: InternalsVisibleTo("System.Runtime.Serialization.Json, PublicKey="
  16:     + "00240000048000009400000006020000002400005253413100040000010001008D56C76F9E86493"
  17:     + "83049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E"
  18:     + "9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4"
  19:     + "BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B"
  20:     + "37AB", AllInternalsVisible = true)]

Once this is done you can make your setters internal and prevent outside code from calling them.

Have fun,