{"id":865,"date":"2010-03-24T09:20:16","date_gmt":"2010-03-24T01:20:16","guid":{"rendered":"http:\/\/www.andreanolanusse.com\/pt\/?p=865"},"modified":"2013-05-01T23:56:56","modified_gmt":"2013-05-02T06:56:56","slug":"utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010","status":"publish","type":"post","link":"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/","title":{"rendered":"Utilizando generics para transforma\u00e7\u00e3o gen\u00e9rica de Objetos em DataSnap 2010"},"content":{"rendered":"<p>No meu post anterior <a href=\"http:\/\/www.andreanolanusse.com\/pt\/datasnap-2010-enviando-e-recebendo-objetos\/\">&#8220;DataSnap 2010 &#8211; Enviando e Recebendo objetos&#8221;<\/a> mostrei como transferir objetos atrav\u00e9s de JSON objects, nos coment\u00e1rios relacionados a este post Rafael Soares fez uma interessante observa\u00e7\u00e3o com rela\u00e7\u00e3o a necessidade de se ter que escrever em toda a classes os m\u00e9todos de convers\u00e3o de JSON para TObject e TObject para JSON. Na verdade isso n\u00e3o \u00e9 necess\u00e1rio, voc\u00ea pode utilizar generics e assim ter apenas dois m\u00e9todos de convers\u00e3o para qualquer classe.<\/p>\n<p>O exemplo utilizado no post anterior o qual os fontes foram disponibilizados para download, traz a classe TCustomer como exemplo e implementa os m\u00e9todo JSONtoCustomer e CustomerToJSON, este fazem refer\u00eancia direta a classe TCustomer, assim sendo fiz algumas modifica\u00e7\u00f5es onde nos permitir\u00e1 utilizar estes dois m\u00e9todos para qualquer classe, primeiro os m\u00e9todos foram renomeados para JSONtoObject e ObjectToJSON e adicionados a uma nova classe chamada TBaseObject, este m\u00e9todos foram definidos como class function, desta forma n\u00e3o precisamos instanciar o objeto. Agora TCustomer passa a herdar desta, assim sendo qualquer objeto ter\u00e1 este m\u00e9todo implemetado.<\/p>\n<p>Os m\u00e9todos da classe TBaseObject agora definem &lt;T&gt; como par\u00e2metro de entrada e retorno, ou seja, o tipo que for definido durante a utiliza\u00e7\u00e3o do m\u00e9todo \u00e9 o que ser\u00e1 considerado pelo m\u00e9todo, aqui estamos utilizando Generics.<\/p>\n<pre class=\"brush: delphi\">unit BaseObject;\r\n\r\ninterface\r\n\r\nuses DBXJSON, DBXJSONReflect;\r\n\r\ntype\r\n  TBaseObject = class\r\n  public\r\n    { public declarations }\r\n    class function ObjectToJSON&lt;T : class&gt;(myObject: T): TJSONValue;\r\n    class function JSONToObject&lt;T : class&gt;(json: TJSONValue): T;\r\n  end;\r\n\r\nimplementation\r\n\r\n{ TBaseObject }\r\n\r\nclass function TBaseObject.JSONToObject&lt;T&gt;(json: TJSONValue): T;\r\nvar\r\n  unm: TJSONUnMarshal;\r\nbegin\r\n  if json is TJSONNull then\r\n    exit(nil);\r\n  unm := TJSONUnMarshal.Create;\r\n  try\r\n    exit(T(unm.Unmarshal(json)))\r\n  finally\r\n    unm.Free;\r\n  end;\r\n\r\nend;\r\n\r\nclass function TBaseObject.ObjectToJSON&lt;T&gt;(myObject: T): TJSONValue;\r\nvar\r\n  m: TJSONMarshal;\r\nbegin\r\n\r\n  if Assigned(myObject) then\r\n  begin\r\n    m := TJSONMarshal.Create(TJSONConverter.Create);\r\n    try\r\n      exit(m.Marshal(myObject));\r\n    finally\r\n      m.Free;\r\n    end;\r\n  end\r\n  else\r\n    exit(TJSONNull.Create);\r\n\r\nend;\r\n\r\nend.<\/pre>\n<p>J\u00e1 a classe TCustomer herda de TBaseObject.<\/p>\n<pre class=\"brush: delphi\">unit Customer;\r\n\r\ninterface\r\n\r\nuses\r\n   DBXJSON, DBXJSONReflect, SysUtils, BaseObject;\r\n\r\ntype\r\n   TMaritalStatus = (msMarried, msEngaged, msEligible);\r\n\r\nTCustomer = class(TBaseObject)\r\n    private\r\n       FName: string;\r\n       FAge: integer;\r\n       FMaritalStatus: TMaritalStatus;\r\n    public\r\n        property Name: string read FName write FName;\r\n        property Age: integer read FAge write FAge;\r\n        property MaritalStatus: TMaritalStatus read FMaritalStatus write FMaritalStatus;\r\n\r\n        function toString : string;override;\r\n  end;<\/pre>\n<p>Agora todos os Server Methods da classe TDSServerMethods passam a utilizar os m\u00e9todos de convers\u00e3o de objetos especificando qual o tipo que dever\u00e1 ser utilizado. O exemplo abaixo retorna uma lista de TJSONArray, cada elemento adicionado ao Array usa a sintaxe TCustomer.ObjectToJSON&lt;TCustomer&gt;.<\/p>\n<p>&lt;TCustomer&gt; define que o tipo do Objeto que est\u00e1 sendo adicionado ao Array.<\/p>\n<pre class=\"brush: delphi\">function TDSServerMethods.ListofCustomer: TJSONArray;\r\nvar\r\n  i: Integer;\r\n  myCustomer: TCustomer;\r\nbegin\r\n  Result := TJSONArray.Create;\r\n\r\n  for i := 0 to 19 do\r\n  begin\r\n    myCustomer := GetCustomer;\r\n    myCustomer.Name := 'Customer ' + IntToStr(i);\r\n    myCustomer.Age := i;\r\n    Result.AddElement(myCustomer.ObjectToJSON&lt;TCustomer&gt;(myCustomer));\r\n  end;\r\nend;<\/pre>\n<p>Para ler o retorno no lado Client utilizamos o mesmo princ\u00edpio com Generics, onde cada item \u00e9 transformado de JSON para TCustomer conforme o exemplo abaixo:<\/p>\n<pre class=\"brush: delphi\">var\r\n  proxy: TDSServerMethodsClient;\r\n  mySingleCustomer: TCustomer;\r\n  allCustomers: TJSONArray;\r\n  i: Integer;\r\nbegin\r\n\r\n  proxy := nil;\r\n  try\r\n    proxy := TDSServerMethodsClient.Create\r\n      (DMClientContainer.MyDSServer.DBXConnection);\r\n    allCustomers := proxy.ListofCustomer;\r\n\r\n    for i := 0 to allCustomers.Size - 1 do\r\n    begin\r\n      mySingleCustomer := TCustomer.JSONToObject&lt;TCustomer&gt;(allCustomers.Get(i));\r\n      MMLog.Lines.Add(mySingleCustomer.ToString);\r\n      mySingleCustomer.Free;\r\n    end;\r\n\r\n  finally\r\n    proxy.Free;\r\n  end;<\/pre>\n<p>Vimos aqui como Generics nos auxilia na transforma\u00e7\u00e3o de objetos em DataSnap.<\/p>\n<p>O exemplo atualizado est\u00e1 dispon\u00edvel no CodeCentral &#8211; Download do <a href=\"http:\/\/cc.embarcadero.com\/Download.aspx?id=27361\">c\u00f3digo fonte<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>No meu post anterior &#8220;DataSnap 2010 &#8211; Enviando e Recebendo objetos&#8221; mostrei como transferir objetos atrav\u00e9s de JSON objects, nos coment\u00e1rios relacionados a este post Rafael Soares fez uma interessante observa\u00e7\u00e3o com rela\u00e7\u00e3o a necessidade de se ter que escrever em toda a classes os m\u00e9todos de convers\u00e3o de JSON para TObject e TObject para [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4202,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_s2mail":"no","footnotes":""},"categories":[102],"tags":[23,181,29],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v16.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Utilizando generics para transforma\u00e7\u00e3o gen\u00e9rica de Objetos em DataSnap 2010<\/title>\n<meta name=\"description\" content=\"No meu post anterior &quot;DataSnap 2010 - Enviando e Recebendo objetos&quot; mostrei como transferir objetos atrav\u00e9s de JSON objects, nos coment\u00e1rios relacionados\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Utilizando generics para transforma\u00e7\u00e3o gen\u00e9rica de Objetos em DataSnap 2010\" \/>\n<meta property=\"og:description\" content=\"No meu post anterior &quot;DataSnap 2010 - Enviando e Recebendo objetos&quot; mostrei como transferir objetos atrav\u00e9s de JSON objects, nos coment\u00e1rios relacionados\" \/>\n<meta property=\"og:url\" content=\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/\" \/>\n<meta property=\"og:site_name\" content=\"Andreano Lanusse | Tecnologia e Desenvolvimento de Software\" \/>\n<meta property=\"article:published_time\" content=\"2010-03-24T01:20:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2013-05-02T06:56:56+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.andreanolanusse.com\/pt\/wp-content\/uploads\/2011\/09\/Icon_Delphi.png\" \/>\n\t<meta property=\"og:image:width\" content=\"170\" \/>\n\t<meta property=\"og:image:height\" content=\"170\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@andreanolanusse\" \/>\n<meta name=\"twitter:site\" content=\"@andreanolanusse\" \/>\n<meta name=\"twitter:label1\" content=\"Est. tempo de leitura\">\n\t<meta name=\"twitter:data1\" content=\"3 minutos\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#website\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/\",\"name\":\"Andreano Lanusse | Tecnologia e Desenvolvimento de Software\",\"description\":\"Andreano Lanusse blog - artigos, tutoriais e v&iacute;deos sobre tecnologia, desenvolvimento de software (Delphi XE4, C#, PHP, .NET) e t&eacute;cnicas de programa&ccedil;&atilde;o\",\"publisher\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"http:\/\/www.andreanolanusse.com\/pt\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"ImageObject\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#primaryimage\",\"inLanguage\":\"pt-BR\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/wp-content\/uploads\/2011\/09\/Icon_Delphi.png\",\"contentUrl\":\"http:\/\/www.andreanolanusse.com\/pt\/wp-content\/uploads\/2011\/09\/Icon_Delphi.png\",\"width\":170,\"height\":170},{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#webpage\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/\",\"name\":\"Utilizando generics para transforma\\u00e7\\u00e3o gen\\u00e9rica de Objetos em DataSnap 2010\",\"isPartOf\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#website\"},\"primaryImageOfPage\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#primaryimage\"},\"datePublished\":\"2010-03-24T01:20:16+00:00\",\"dateModified\":\"2013-05-02T06:56:56+00:00\",\"description\":\"No meu post anterior \\\"DataSnap 2010 - Enviando e Recebendo objetos\\\" mostrei como transferir objetos atrav\\u00e9s de JSON objects, nos coment\\u00e1rios relacionados\",\"breadcrumb\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/\",\"name\":\"In\\u00edcio\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#webpage\"}}]},{\"@type\":\"Article\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#article\",\"isPartOf\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#webpage\"},\"author\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\"},\"headline\":\"Utilizando generics para transforma\\u00e7\\u00e3o gen\\u00e9rica de Objetos em DataSnap 2010\",\"datePublished\":\"2010-03-24T01:20:16+00:00\",\"dateModified\":\"2013-05-02T06:56:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#webpage\"},\"commentCount\":16,\"publisher\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\"},\"image\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#primaryimage\"},\"keywords\":[\"DataSnap\",\"Delphi\",\"JSON\"],\"articleSection\":[\"Delphi\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010\/#respond\"]}]},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\",\"name\":\"Andreano Lanusse\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#personlogo\",\"inLanguage\":\"pt-BR\",\"url\":\"http:\/\/0.gravatar.com\/avatar\/6a9c6f73c7c480fb826c7303288abfd3?s=96&d=mm&r=g\",\"contentUrl\":\"http:\/\/0.gravatar.com\/avatar\/6a9c6f73c7c480fb826c7303288abfd3?s=96&d=mm&r=g\",\"caption\":\"Andreano Lanusse\"},\"logo\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#personlogo\"},\"sameAs\":[\"https:\/\/twitter.com\/andreanolanusse\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/posts\/865"}],"collection":[{"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/comments?post=865"}],"version-history":[{"count":0,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/posts\/865\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/media\/4202"}],"wp:attachment":[{"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/media?parent=865"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/categories?post=865"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/tags?post=865"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}