Serialização de Classes

23/12/2008

Olá Consultores, Gostaria da ajuda de vocês para solucionar o seguinte problema:   Estou desenvolvendo um sistema em 3 camadas utilizando Delphi 7 + FB 2.0 + IBO + BSS.
  
  Preciso criar funções para Serializar/Deserializar em XML algumas classes que criei, para poder enviá-las ao servidor de aplicação para que este possa persistir os dados destas classe no banco de dados.
  
  Criei estas classes descendentes de TComponent, para assim poder tornar suas propriedades "Published", a fim de convertê-las em string (utilizando rotinas citadas no próprio help do Delphi). Não creio que esta seja a melhor maneira de fazer isto, por isso, gostaria da ajuda de vocês para seguir pelo melhor caminho. ////////// Minhas classes  
TContato = class(TComponent)
  private
    FID        : integer;
    FNOME      : string;
    FCNPJ      : string;
    FIE        : string;
    FIM        : string;
    FEXPEDICAO : TDateTime;
    FATIVO     : Boolean;
    FCADASTRO  : TDateTime;
    function GetATIVO: Boolean;
    function GetCADASTRO: TDateTime;
    function GetCNPJ: string;
    function GetEXPEDICAO: TDateTime;
    function GetID: integer;
    function GetIE: string;
    function GetIM: string;
    function GetNOME: string;
    procedure SetATIVO(const Value: Boolean);
    procedure SetCADASTRO(const Value: TDateTime);
    procedure SetCNPJ(const Value: string);
    procedure SetEXPEDICAO(const Value: TDateTime);
    procedure SetID(const Value: integer);
    procedure SetIE(const Value: string);
    procedure SetIM(const Value: string);
    procedure SetNOME(const Value: string);
  public
    constructor Create(AOwner: TComponent); reintroduce; virtual;
    destructor Destroy; override;
  published
    property ID        : integer   read GetID        write SetID;
    property NOME      : string    read GetNOME      write SetNOME;
    property CNPJ      : string    read GetCNPJ      write SetCNPJ;
    property IE        : string    read GetIE        write SetIE;
    property IM        : string    read GetIM        write SetIM;
    property EXPEDICAO : TDateTime read GetEXPEDICAO write SetEXPEDICAO;
    property ATIVO     : Boolean   read GetATIVO     write SetATIVO;
    property CADASTRO  : TDateTime read GetCADASTRO  write SetCADASTRO;
  end;  
 
  TContatoEndereco = class(TComponent)
  private
    FID            : integer;
    FENDERECO      : string;
    FCOMPLEMENTO   : string;
    FBAIRRO        : string;
    FCIDADE        : string;
    FUF            : string;
    FCEP           : string;
    FPT_REFERENCIA : string;
    function GetBAIRRO: string;
    function GetCEP: string;
    function GetCIDADE: string;
    function GetCOMPLEMENTO: string;
    function GetENDERECO: string;
    function GetPT_REFERENCIA: string;
    function GetUF: string;
    function GetID: integer;
    procedure SetID(const Value: integer);
    procedure SetBAIRRO(const Value: string);
    procedure SetCEP(const Value: string);
    procedure SetCIDADE(const Value: string);
    procedure SetCOMPLEMENTO(const Value: string);
    procedure SetENDERECO(const Value: string);
    procedure SetPT_REFERENCIA(const Value: string);
    procedure SetUF(const Value: string);
  public
    constructor Create(AOwner: TComponent); reintroduce; virtual;
    destructor Destroy; override;
  published
    property ID            : integer read GetID            write SetID;
    property ENDERECO      : string  read GetENDERECO      write SetENDERECO;
    property COMPLEMENTO   : string  read GetCOMPLEMENTO   write SetCOMPLEMENTO;
    property BAIRRO        : string  read GetBAIRRO        write SetBAIRRO;
    property CIDADE        : string  read GetCIDADE        write SetCIDADE;
    property UF            : string  read GetUF            write SetUF;
    property CEP           : string  read GetCEP           write SetCEP;
    property PT_REFERENCIA : string  read GetPT_REFERENCIA write SetPT_REFERENCIA;
  end;  
 
  TFone = class(TCollectionItem)
  private
    FID   : integer;
    FFONE : string;
    function GetFONE: string;
    procedure SetFONE(const Value: string);
    function GetID: integer;
    procedure SetID(const Value: integer);
  public
    constructor Create(Collection: TCollection); virtual;
    destructor Destroy; override;
  published
    property ID   : integer read GetID   write SetID;
    property FONE : string  read GetFONE write SetFONE;
  end;   TFones = class(TOwnedCollection)
  private
    function GetFones(index: integer): TFone;
    procedure SetFones(index: integer; const Value: TFone);
  public
    function Add: TFone;
    property Items[index: integer]: TFone read GetFones write SetFones;
  end;   TContatoFones = class(TComponent)
  private
    FFones : TFones;
  public
    constructor create(AOwner: TComponent); override;
    destructor destroy; override;
  published
    property Fones: TFones read FFones write FFones;
  end;
///////// funcoes usadas para converter as Classes em string 
///////// e string em classe novamente retiradas do help do Delphi
 
 
function ComponentToString(Component: TComponent): string;
var
  BinStream:TMemoryStream;
  StrStream: TStringStream;
  s: string;
begin
  BinStream := TMemoryStream.Create;
  try
    StrStream := TStringStream.Create(s);
    try
      BinStream.WriteComponent(Component);
      BinStream.Seek(0, soFromBeginning);
      ObjectBinaryToText(BinStream, StrStream);
      StrStream.Seek(0, soFromBeginning);
      Result:= StrStream.DataString;
    finally
      StrStream.Free;
    end;
  finally
    BinStream.Free
  end;
end;  function StringToComponent(Value: string): TComponent;
var
  StrStream:TStringStream;
  BinStream: TMemoryStream;
begin
  StrStream := TStringStream.Create(Value);
  try
    BinStream := TMemoryStream.Create;
    try
      ObjectTextToBinary(StrStream, BinStream);
      BinStream.Seek(0, soFromBeginning);
      Result := BinStream.ReadComponent(nil);     finally
      BinStream.Free;
    end;
  finally
    StrStream.Free;
  end;
end;   Natal/RN, 23 de Dezembro de 2008
Alexandre Amaral
Alexandre Neto

Alexandre Neto

Curtidas 0

Respostas

Ricardo Boaro

Ricardo Boaro

23/12/2008

           Olá Alexandre.

           Vamos trocar algumas idéia para que possamos responder sua questão da maneira correta. Você ja trabalhou com a biblioteca JVCL? Existe uma classe nessa blbilioteca que faz exatamente o que você precisa, eu mesmo ja utilizei em algumas situações e funciona muito bem, a classe chama-se TXMLSerialize.
           Abaixo esta a classe em questão
unit XMLSerializer;

interface

uses
SysUtils, Classes, JvgXMLSerializer;

type
TXMLSerializer = class(TJvgXMLSerializer)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
procedure Serialize(Component: TObject; var s: string); overload;
procedure DeSerialize(Component: TObject; s: string); overload;
published
{ Published declarations }
end;

TSerializable = class(TPersistent)
public
{ Public declarations }
function Serialize: string;
procedure DeSerialize(s: string);
end;

implementation

{ TXMLSerializer }

procedure TXMLSerializer.DeSerialize(Component: TObject; s: string);
var
Stream: TStringStream;
begin
Stream := TStringStream.Create(s);
try
DeSerialize(Component, Stream);
finally
Stream.Free;
end;
end;

procedure TXMLSerializer.Serialize(Component: TObject; var s: string);
var
Stream: TStringStream;
begin
Stream := TStringStream.Create();
try
Serialize(Component, Stream);
s := Stream.DataString;
finally
Stream.Free;
end;
end;

{ TSerializable }

procedure TSerializable.DeSerialize(s: string);
var
Serializer: TXMLSerializer;
begin
Serializer := TXMLSerializer.Create(nil);
try
Serializer.DeSerialize(Self, s);
finally
Serializer.Free;
end;
end;

function TSerializable.Serialize: string;
var
Serializer: TXMLSerializer;
begin
Serializer := TXMLSerializer.Create(nil);
try
Serializer.Serialize(Self, Result);
finally
Serializer.Free;
end;
end;

end.

   O que você pensa sobre essa solução?

Aguardo seu retorno.

Abraço





GOSTEI 0
Alexandre Neto

Alexandre Neto

23/12/2008

Olá Ricardo,   Esta solução que você me apresentou caiu como uma luva, Obrigado.   Me diga uma coisa, com a sua experiência com esta classe, ela apresenta alguma limitação? Em situações onde temos classes mais elaboradoas, ela já deixou a desejar?   Abração, Alexandre.    
GOSTEI 0
Ricardo Boaro

Ricardo Boaro

23/12/2008

           Alexandre.

           Ótimo, fico contente em poder ajudar-lhe, todas as vezes que precisei serializar, utilizei a classe em questão e sempre foi perfeito, até hj so tenho bons cases com ela. Com certeza ela irá lhe auxiliar por muito tempo.

           Aguardo o seu retorno para encerrarmos esse chamado.

           Você tem mais alguma dúvida?

           Abraço!
GOSTEI 0
Alexandre Neto

Alexandre Neto

23/12/2008

Olá Ricardo,   Não tenho mais nenhuma dúvida sobre o referido assunto. Sua ajuda foi amplamente satisfatória.   Mais uma vez agradeço, obrigado!   Abração, Alexandre.
GOSTEI 0
POSTAR