Serialização
Observação
Este conteúdo é reimpresso com permissão da Pearson Education, Inc. 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 revisado 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 possa ser prontamente persistido ou transportado. Por exemplo, você pode serializar um objeto, transportá-lo pela Internet usando HTTP e desserializá-lo no computador de destino.
O .NET Framework oferece três tecnologias de serialização principais otimizadas para vários cenários de serialização. A tabela a seguir lista essas tecnologias e os principais tipos de estrutura relacionados a elas.
Nome da Tecnologia | Tipos principais | Cenários |
---|---|---|
Serialização do contrato de dados | DataContractAttribute DataMemberAttribute DataContractSerializer NetDataContractSerializer DataContractJsonSerializer ISerializable |
Persistência geral Serviços Web JSON |
Serialização XML | XmlSerializer | Formato XML com controle total sobre a forma do XML |
Serialização de runtime (binário e SOAP) | SerializableAttribute ISerializable BinaryFormatter SoapFormatter |
Comunicação remota .NET |
✔️ PENSE sobre a serialização ao criar tipos.
Escolhendo a tecnologia de serialização correta que receberá suporte
✔️ CONSIDERE dar suporte à Serialização de Contrato de Dados se houver possibilidade de que as instâncias do seu tipo precisem ser persistentes ou usadas nos Serviços Web.
✔️ CONSIDERE dar suporte à serialização XML em vez ou além da Serialização do Contrato de Dados se você precisar ter mais controle sobre o formato XML gerado quando o tipo for serializado.
Isso talvez seja necessário em alguns cenários de interoperabilidade no qual você precise usar um constructo XML para o qual não haja suporte na Serialização do Contrato de Dados, por exemplo, para gerar atributos XML.
✔️ CONSIDERE dar suporte à Serialização em Runtime se as instâncias do tipo precisarem ultrapassar os limites da comunicação remota .NET.
❌ EVITE dar suporte à Serialização em Runtime ou à serialização XML apenas por motivos gerais de persistência. Prefira a Serialização do Contrato de Dados em vez disso.
Oferecendo suporte à serialização do contrato de dados
Os tipos podem dar suporte à Serialização do 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 tipo público se o tipo puder ser usado na confiança parcial.
Na confiança total, os serializadores do Contrato de Dados podem serializar e desserializar tipos e membros não públicos, mas somente os membros públicos podem ser serializados e desserializados na confiança parcial.
✔️ IMPLEMENTE um getter e um setter em todas as propriedades que têm DataMemberAttribute. Os serializadores do Contrato de Dados exigem o getter e o setter para o tipo sejam considerados serializáveis. (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 poderão ser não públicos.
✔️ CONSIDERE usar retornos de chamada de serialização para a inicialização de instâncias desserializadas.
Os construtores não são chamados quando os objetos são desserializados. (Há exceções à regra. Construtores de coleções marcadas com CollectionDataContractAttribute são chamados durante a desserialização.) Portanto, qualquer lógica 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 da família são OnDeserializingAttribute, OnSerializingAttribute e OnSerializedAttribute. Eles podem ser usados para marcar os retornos de chamada que são executados antes de desserialização, antes da serialização e, por fim, após a serialização, respectivamente.
✔️ CONSIDERE usar o KnownTypeAttribute para indicar os tipos concretos que devem ser usados ao desserializar um grafo de objetos complexos.
Considere a compatibilidade com versões anteriores e posteriores ao criar ou modificar tipos serializáveis.
Tenha em mente que os fluxos serializados de versões futuras do tipo podem ser desserializados na versão atual de tipo e vice-versa.
Verifique se compreendeu que os membros de dados, até mesmo os privados e internos, não podem alterar seus nomes, tipos ou mesmo sua ordem nas versões futuras do tipo, a menos que se tome um 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 a tipos serializáveis. Tente desserializar a nova versão em uma versão antiga e vice-versa.
✔️ CONSIDERE implementar IExtensibleDataObject para permitir o ciclo completo entre diferentes versões do tipo.
A interface permite que o serializador assegure de que nenhum dado sejam perdido durante o ciclo completo. A propriedade IExtensibleDataObject.ExtensionData é usada para armazenar 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 for serializada e desserializada subsequentemente em uma versão futura, os dados adicionais estarão disponíveis no fluxo serializado.
Suporte à serialização XML
A Serialização do Contrato de Dados é a tecnologia de serialização principal (padrão) do .NET Framework, mas há situações de serialização para as quais a Serialização do Contrato de Dados não oferece suporte. Por exemplo, ela não fornece controle total sobre o formato XML gerado ou consumido pelo serializador. Se esse controle fino for necessário, a Serialização XML precisará ser usada e você precisará criar seus tipos para oferecer suporte essa tecnologia de serialização.
❌ EVITE criar os tipos especificamente para a Serialização XML, a menos que você tenha um motivo muito forte para controlar a forma do XML gerado. Essa tecnologia de serialização foi substituída pela serialização do contrato de dados abordada na seção anterior.
✔️ CONSIDERE implementar a interface IXmlSerializable se quiser ainda mais controle sobre a forma do XML serializado do que o que é oferecido aplicando os atributos de Serialização XML. Dois métodos da interface, ReadXml e WriteXml, permitem que você controle totalmente o fluxo XML serializável. Você também pode controlar o esquema XML gerado para o tipo aplicando XmlSchemaProviderAttribute
.
Suporte à serialização em runtime
A seSialização em Runtime é uma tecnologia usada pelo .NET Remoting. Se você considerar que os tipos serão transportados por meio da comunicação remota .NET, será necessário verificar se eles oferecem suporte à Serialização em Runtime.
O suporte básico da Serialização em Runtime pode ser fornecido aplicando SerializableAttribute, e os cenários mais avançados envolvem a implementação de um Padrão Serializável em Runtime simples (implemente ISerializable e forneça um construtor de serialização).
✔️ CONSIDERE o suporte à Serialização em Runtime se os tipos forem usados com a comunicação remota .NET. Por exemplo, o namespace System.AddIn usa a comunicação remota .NET e, portanto, todos os tipos trocados entre os suplementos System.AddIn
precisam oferecer suporte à Serialização em Runtime.
✔️ CONSIDERE implementar o Padrão Serializável em Runtime se quiser controle completo sobre o processo de serialização. Por exemplo, se você quiser transformar os dados à medida que eles forem serializados ou desserializados.
O padrão é muito simples. Tudo o que você precisa fazer é implementar a interface ISerializable e fornecer um construtor especial que é usado quando o objeto é desserializado.
✔️ PROTEJA o construtor de serialização e forneça dois parâmetros tipados e nomeados exatamente conforme mostrado no exemplo aqui.
[Serializable]
public class Person : ISerializable
{
protected Person(SerializationInfo info, StreamingContext context)
{
// ...
}
}
✔️ IMPLEMENTE os membros ISerializable explicitamente.
✔️ APLIQUE uma demanda de link para a implementação de ISerializable.GetObjectData. Isso garantirá que o somente núcleo totalmente confiável e o Serializador em Runtime tenham acesso ao membro.
Portions © 2005, 2009 Microsoft Corporation. Todos os direitos reservados.
Reimpresso com permissão da Pearson Education, Inc. das Diretrizes de Design do Framework: convenções, linguagens e padrões para bibliotecas do .NET reutilizável, 2ª edição por Krzysztof Cwalina e Brad Abrams, publicado em 22 de outubro de 2008 por Addison-Wesley Professional como parte da série de desenvolvimento do Microsoft Windows.