Propriedade IsReference

by Israel Aece 8. January 2009 08:23

É 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.

Tags: ,

CSD | WCF

Comments

2/2/2010 9:30:17 PM #

trackback

Usando LINQ To SQL com WCF

Usando LINQ To SQL com WCF

Israel Aece

Comments are closed

Powered by BlogEngine.NET 1.5.0.0
Theme by Mads Kristensen

Sobre

Meu nome é Israel Aece e sou especialista em tecnologias de desenvolvimento Microsoft, atuando como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. [ Mais ]

Twitter

Host