Serialização
Nota
Este conteúdo é reimpresso com permissão da Pearson Education, Inc., a partir de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. Essa edição foi publicada em 2008 e, desde então, o livro foi totalmente revisto na terceira edição. Algumas das informações nesta página podem estar desatualizadas.
A serialização é o processo de conversão de um objeto em um formato que pode ser prontamente persistido ou transportado. Por exemplo, você pode serializar um objeto, transportá-lo pela Internet usando HTTP e desserializá-lo na máquina de destino.
O .NET Framework oferece três tecnologias principais de serialização otimizadas para vários cenários de serialização. A tabela a seguir lista essas tecnologias e os principais tipos de estrutura relacionados a essas tecnologias.
Nome da tecnologia | Principais Tipos | Cenários |
---|---|---|
Serialização de contrato de dados | DataContractAttribute DataMemberAttribute DataContractSerializer NetDataContractSerializer DataContractJsonSerializer ISerializable |
Persistência geral Serviços Web JSON |
Serialização XML | XmlSerializer | Formato XML com controlo total sobre a forma do XML |
Serialização em tempo de execução (binário e SOAP) | SerializableAttribute ISerializable BinaryFormatter SoapFormatter |
Comunicação remota .NET |
✔️ PENSE na serialização ao projetar novos tipos.
Escolhendo a tecnologia de serialização certa para oferecer suporte
✔️ CONSIDERE o suporte à serialização de contrato de dados se instâncias do seu tipo precisarem ser persistentes ou usadas em serviços da Web.
✔️ CONSIDERE oferecer suporte à serialização XML em vez de, ou além dela, à serialização de contrato de dados se precisar de mais controle sobre o formato XML que é produzido quando o tipo é serializado.
Isso pode ser necessário em alguns cenários de interoperabilidade em que você precisa usar uma construção XML que não é suportada pela serialização de contrato de dados, por exemplo, para produzir atributos XML.
✔️ CONSIDERE dar suporte à serialização de tempo de execução se instâncias do seu tipo precisarem atravessar os limites da comunicação remota do .NET.
❌ EVITE suportar Runtime Serialization ou XML Serialization apenas por motivos gerais de persistência. Em vez disso, prefira a serialização do contrato de dados.
Suporte à serialização de contrato de dados
Os tipos podem oferecer suporte à serialização de contrato de dados aplicando o DataContractAttribute ao tipo e o DataMemberAttribute aos membros (campos e propriedades) do tipo.
✔️ CONSIDERE marcar os membros de dados do seu tipo como públicos se o tipo puder ser usado em confiança parcial.
Na confiança total, os serializadores de Contrato de Dados podem serializar e desserializar tipos e membros não públicos, mas apenas membros públicos podem ser serializados e desserializados em confiança parcial.
✔️ DO implemente um getter e setter em todas as propriedades que têm DataMemberAttribute. Os serializadores de contrato de dados exigem o getter e o setter para que o tipo seja considerado serializável. (No .NET Framework 3.5 SP1, algumas propriedades de coleção podem ser somente get.) Se o tipo não for usado em confiança parcial, um ou ambos os acessadores de propriedade podem não ser públicos.
✔️ CONSIDERE o uso dos retornos de chamada de serialização para inicialização de instâncias desserializadas.
Os construtores não são chamados quando os objetos são desserializados. (Há exceções à regra. Os construtores de coleções marcadas com são chamados durante CollectionDataContractAttribute a desserialização.) Portanto, qualquer lógica que seja executada durante a construção normal precisa ser implementada como um dos retornos de chamada de serialização.
OnDeserializedAttribute
é o atributo de retorno de chamada mais usado. Os outros atributos na família são OnDeserializingAttribute, OnSerializingAttribute, e OnSerializedAttribute. Eles podem ser usados para marcar retornos de chamada que são executados antes da desserialização, antes da serialização e, finalmente, após a serialização, respectivamente.
✔️ CONSIDERE usar o KnownTypeAttribute para indicar tipos concretos que devem ser usados ao desserializar um gráfico de objeto complexo.
✔️ DO considere a compatibilidade com versões anteriores e posteriores ao criar ou alterar tipos serializáveis.
Lembre-se de que fluxos serializados de versões futuras do seu tipo podem ser desserializados para a versão atual do tipo e vice-versa.
Certifique-se de entender que os membros de dados, mesmo privados e internos, não podem alterar seus nomes, tipos ou até mesmo sua ordem em versões futuras do tipo, a menos que seja tomado cuidado especial para preservar o contrato usando parâmetros explícitos para os atributos do contrato de dados.
Teste a compatibilidade da serialização ao fazer alterações em tipos serializáveis. Tente desserializar a nova versão para uma versão antiga e vice-versa.
✔️ CONSIDERE a implementação IExtensibleDataObject para permitir a viagem de ida e volta entre diferentes versões do tipo.
A interface permite que o serializador assegure que nenhum dado seja perdido durante o round-tripping. A IExtensibleDataObject.ExtensionData propriedade é usada para armazenar quaisquer dados da versão futura do tipo que é desconhecido para a versão atual e, portanto, não pode armazená-los em seus membros de dados. Quando a versão atual é subsequentemente serializada e desserializada em uma versão futura, os dados adicionais estarão disponíveis no fluxo serializado.
Suporte à serialização XML
A Serialização de Contrato de Dados é a principal tecnologia de serialização (padrão) no .NET Framework, mas há cenários de serialização que a Serialização de Contrato de Dados não suporta. Por exemplo, ele não lhe dá controle total sobre a forma de XML produzido ou consumido pelo serializador. Se esse controle fino for necessário, a serialização XML deverá ser usada, e você precisará projetar seus tipos para dar suporte a essa tecnologia de serialização.
❌ EVITE projetar seus tipos especificamente para serialização XML, a menos que você tenha um motivo muito forte para controlar a forma do XML produzido. Essa tecnologia de serialização foi substituída pela serialização de contrato de dados discutida na seção anterior.
✔️ CONSIDERE implementar a IXmlSerializable interface se quiser ainda mais controle sobre a forma do XML serializado do que o que é oferecido pela aplicação dos atributos XML Serialization. Dois métodos da interface ReadXml e WriteXml, permitem que você controle totalmente o fluxo XML serializado. Você também pode controlar o esquema XML que é gerado para o tipo aplicando o XmlSchemaProviderAttribute
.
Suportando a serialização em tempo de execução
Runtime Serialization é uma tecnologia usada pelo .NET Remoting. Se você acha que seus tipos serão transportados usando a comunicação remota do .NET, você precisa ter certeza de que eles suportam a serialização em tempo de execução.
O suporte básico para Runtime Serialization pode ser fornecido aplicando o , e cenários mais avançados envolvem a SerializableAttributeimplementação de um Runtime Serializable Pattern simples (implementar ISerializable e fornecer construtor de serialização).
✔️ CONSIDERE o suporte à serialização em tempo de execução se seus tipos forem usados com a comunicação remota do .NET. Por exemplo, o System.AddIn namespace usa a comunicação remota .NET e, portanto, todos os tipos trocados entre System.AddIn
suplementos precisam oferecer suporte à serialização em tempo de execução.
✔️ CONSIDERE implementar o Runtime Serializable Pattern se quiser ter controle total sobre o processo de serialização. Por exemplo, se você quiser transformar dados à medida que eles são serializados ou desserializados.
O padrão é muito simples. Tudo o que você precisa fazer é implementar a ISerializable interface e fornecer um construtor especial que é usado quando o objeto é desserializado.
✔️ DO torna o construtor de serialização protegido e fornece dois parâmetros digitados e nomeados exatamente como mostrado no exemplo aqui.
[Serializable]
public class Person : ISerializable
{
protected Person(SerializationInfo info, StreamingContext context)
{
// ...
}
}
✔️ NÃO implemente os ISerializable membros explicitamente.
✔️ NÃO aplique uma demanda de link à ISerializable.GetObjectData implementação. Isso garante que apenas o núcleo totalmente confiável e o Runtime Serializer tenham acesso ao membro.
© Partes 2005, 2009 Microsoft Corporation. Todos os direitos reservados.
Reimpresso com permissão da Pearson Education, Inc., de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition por Krzysztof Cwalina e Brad Abrams, publicado em 22 de outubro de 2008 por Addison-Wesley Professional como parte da Microsoft Windows Development Series.