Propriedade IsReference


É muito comum haver situações onde retornamos um array de objetos para o cliente. Cada elemento deste array poderá conter instancias de objetos que possuem propriedades que referenciam outros objetos ou até mesmo referencia circulares. Imagine a seguinte situação:

[DataContract]
public class Gerente
{
    [DataMember]
    public string Nome { get; set; }
}

[DataContract]
public class Empregado
{
    [DataMember]
    public string Nome { get; set; }
    [DataMember]
    public Gerente Gerente { get; set; }
}

Note que a classe Empregado possui uma propriedade que aceita uma instancia da classe Gerente. Na implementação do serviço, é perfeitamente possível que exista um mesmo gerente para vários empregados, fazendo com que uma mesma instancia da classe Gerente seja reutilizada por várias instancias da classe Empregado. O código abaixo ilustra isso:

List<Empregado> list = new List<Empregado>();
Gerente g = new Gerente() { Nome = “Bill Buchanan” };

list.Add(new Empregado() { Gerente = g, Nome = “Jack Bauer” });
list.Add(new Empregado() { Gerente = g, Nome = “Chloe O’brien” });
list.Add(new Empregado() { Gerente = g, Nome = “Michelle Dessler” });

Utilizando a configuração padrão do WCF, a instancia da classe Gerente será serializada para cada instancia da classe Empregado, aumentando consideravelmente o tamanho, ainda mais se o objeto conter várias propriedades. Esse comportamento é semelhante ao que conhecemos como by-value e, podemos notar isso a partir do resultado desta serialização:

<ArrayOfEmpregado …=””>
  <Empregado>
    <Gerente>
      <Nome>Bill Buchanan</Nome>
    </Gerente>

    <Nome>Jack Bauer</Nome>
  </Empregado>
  <Empregado>
    <Gerente>
      <Nome>Bill Buchanan</Nome>
    </Gerente>

    <Nome>Chloe O’brien</Nome>
  </Empregado>
  <Empregado>
    <Gerente>
      <Nome>Bill Buchanan</Nome>
    </Gerente>

    <Nome>Michele</Nome>
  </Empregado>
</ArrayOfEmpregado>

A versão 3.5 do .NET Framework trouxe uma nova propriedade para a classe DataContractAttribute: IsReference. Essa propriedade recebe um valor boleano que, por padrão é False, indicando se possíveis referencias de objetos devem ser mantidas na geração do envelope SOAP. Com isso, podemos configurar a classe Gerente como:

[DataContract(IsReference = true)]
public class Gerente
{
    [DataMember]
    public string Nome { get; set; }
}

Ao executar o mesmo código acima, o resultado passa a ser o seguinte:

<ArrayOfEmpregado
  xmlns=”…”
  xmlns:i=”…”>
  <Empregado>
    <Gerente z:Id=”i1″ xmlns:z=”…”>
      <Nome>Bill Buchanan</Nome>
    </Gerente>

    <Nome>Jack Bauer</Nome>
  </Empregado>
  <Empregado>
    <Gerente z:Ref=”i1″ xmlns:z=”…”/>
    <Nome>Chloe O’brien</Nome>
  </Empregado>
  <Empregado>
    <Gerente z:Ref=”i1″ xmlns:z=”…”/>
    <Nome>Michele</Nome>
  </Empregado>
</ArrayOfEmpregado>

Note que não há mais replicação do objeto Gerente. A instancia da classe Gerente será serializada no primeiro empregado e, a partir daí, todos os empregados que utilizarem a mesma instancia apenas a referenciam.

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s