• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Nazgulled

[C#/VB.NET] Acham que isto tem utilidade? Vocês usariam esta biblioteca?

14 mensagens neste tópico

Já devem ter visto por ai alguns tópicos meus sobre XML, certo? Bem, ontem lá consegui fazer o que queria... Não exactamente o que queria o que significa que as dúvidas que eu tinha, continuam sem resposta, mas encontrei uma forma melhor, mais simples e fácil de fazer o que quero. Pelo que as minhas dúvidas/ideias anteriores foram abandonadas...

A ideia é muito simples. Ter uma classe/biblioteca, que qualquer programador .NET possa usar nas suas aplicações. Esta biblioteca permite ler e gravar definições da respectiva aplicação num ficheiro XML. Assim à primeira vista pensaram que isto não tem utilidade nenhuma porque já existe várias formas de o fazer em .NET mas eu procuro algo ligeiramente diferente e mais simples de utilizar.

As alternativas actuais são as seguintes:

  • APIs do Windows: É uma solução mas não quero ir por ai por várias razões, sendo uma delas que penas queria usar managed code.
  • Classe AppSettingsReader: Não sei explicar bem porquê mas nunca gostei muito de usar os ficheiros app.config/user.config e segundo o estudo que fiz do assunto, não permite fazer exactamente aquilo que quero e/ou se permite iria dar muito mais trabalho a por as coisas a funcionar como eu quero.
  • Registo do Windows: Fora de questão por várias razões. Acho que é óbvio e nem vou explicar porquê.
  • XML Serialization: Parece-me demasiado complicado usar para algo que quero simplificar e a ideia de guardar os dados em objectos não me agrada (não quero ter de fazer castings).

A única alternativa é eu fazer a minha própria biblioteca que trate de tudo da forma mais simples que me ocorre e qual é essa forma? Passo a explicar...

Para começar e na minha opinião a melhor hipotese que temos para guardar definições das nossas aplicações é usando propriedades e como boa prática, colocar todas estas propriedades numa classe própria. Usando propriedades temos "métodos" get e "set" já built in, dos quais podemos tirar partido e colocar lá qualquer tipo de validações necessárias. Não precisamos de andar com validações no código principal quando podemos fazer isso internamente e até definir um valor por omissão no caso do valor passado ser inválida ou então lançar uma excepção. Pormenores que cada um sabe de si, mas a ideia base do uso de propriedades numa única class para guardar as definições, acho a solução ideia.

Vejamos a seguinte classe:

public class MyAppSettings {
public string OpString {
	get; set;
}

public int OpInt {
	get; set;
}

public bool OpBoolean {
	get; set;
}
}

Para usar esta classe bastava fazer algo como:

MyAppSettings settings = new MyAppSettings();

settings.OpString = "Olá Mundo!";
settings.OpInteger = 1500;
settings.OpBoolean = true;

if(settings.OpBoolean == true) {
MessageBox.Show(settings.OpString);
} else {
MessageBox.Show(Convert.ToString(settings.OpInteger));
}

Parece bom não? A ideia agora é criar algo onde eu possa por exemplo fazer um settings.Save() e imediatamente as definições serão todas gravas num ficheiro XML. Carregar as definições do XML seria igualmente fácil fazendo um settings.Load("ficheiro.xml"). Mas melhor ainda (no caso do load) é as definições serem carregadas automaticamente no construtor, ou seja, quando fizéssemos MyAppSettings settings = new MyAppSettings("ficheiro.xml");, por exemplo, o método load só seria usada se a criação do objecto fosse feita com o construtor por omissão que não leva parâmetros ou se calhar é estúpido fazer isto. Bem, pormenores que ainda não pensei bem...

Algumas perguntas que podem ter neste momento talvez sejam: 1) Como é que tudo isto iria funcionar, ou seja, como é que eu iria preparar as minhas definições para usar esta biblioteca? 2) O que acontecerá se tiver propriedades que devolvam um tipo mais complexo, por exemplo um objecto do tipo Color ou Font e se for uma estrutura com um conjunto de outras propriedades?

Por partes...

1) Estão a ver o exemplo da classe MyAppSettings que está lá para cima? Bem, apenas teriam de ser feitas algumas mudanças e para o seguinte exemplo vamos imaginar que esta minha biblioteca se chama SettingsLib (com um bocado de sorte ainda será o nome final se não arranjar algo que soe melhor). A nossa classe final iria ser algo do género:

[XmlRootElement("Settings")]
public class MyAppSettings : SettingsLib {
[XmlCategory("Categoria1")]
public string OpString {
	get; set;
}

[XmlCategory("Categoria1")]
public int OpInteger {
	get; set;
}

[XmlCategory("Categoria2")]
public bool OpBoolean {
	get; set;
}
}

Simples e muito fácil de fazer/usar, não acham?

Para quem não sabe, XmlCategory e XmlRootElement são atributos e possivelmente no código final irão existir mais alguns ou então só um mas que com diferentes construtores que aceite um número diferente de argumentos. Como disse lá em cima, pormenores que ainda não pensei ao certo. Este tipo de atributos são muito parecidos com Xml Serialization pois é uma das coisas que gostei nesta alternativa (o uso de atributos), mas quero-o fazer de forma mais simples, pois os exemplos que vi na net de Xml Serialization complicavam muito as coisas.

Mas neste caso concreto o XmlCategory definira uma categoria para a respectiva definição, caso contrário o uso de XML para estrutura as definições não faria sentido nenhum. A ideia de criar um XML é fazê-lo de forma que o XML fique bem estruturado (ainda não pensei bem como vai ficar). O XmlRootElement acho é bastante óbvio para quem sabe como é constituido um ficheiro XML, para quem não sabe, desculpem-me mas não vou perder tempo a explicar XML neste momento, a Wikipedia explica bem ;).

2) Quanto a pergunta 2, realmente é algo que tem passado pela minha cabeça em saber como resolver de uma maneira simples e eficaz. Bem, no caso de tipos como Color e Font, já tenho mais ou menos umas ideias de como o fazer, só chegarei lá quando realmente começar a programar. Quanto a tipos diferentes e/ou estruturas com conjuntos de propriedades, ai poderá ser mais complicado mas ainda tenho de estudar isso melhor. No entanto suporte para alguns tipos mais comuns (como é o caso do Color e Font) talvez a forma mais fácil será implementar métodos na SettingsLib que convertam os valores para texto e vice-versa específicos para esses tipos. No caso de conjuntos de propriedades, ainda não pensei bem por várias razões, pode ser algum complexo a pensar e eu não tenho nenhum exemplo concreto que sirva para eu estudar como vou fazer a coisa e depois se calhar é algo que não será assim tão necessário quanto isso? É um caso a ver mais lá para a frente... Para terminar esta resposta, tudo o que eu disse aqui é algo que será feito internamente na SettingsLib, o programador que use esta biblioteca não tem de se preocupar com nada, apenas com carregar, usar e gravar as definições, nada mais.

O que acham da ideia? Acham que tem interesse em fazer algo bem feito e distribuir publicamente ou esqueço a ideia e faço algo mais simples e básico que apenas funcione para as minhas aplicações? Vocês usariam ou no mínimo pensariam em usar nas vossas aplicações?

Se por acaso têm algumas dúvidas de como funcionaria fazerem alguma coisa que me esteja a perguntar e que talvez seja factor decisivo para usarem ou não esta biblioteca nas vossas aplicações, chutem-na... que eu farei o melhor a tentar explicar como é que a minha biblioteca poderia dar conta do problema, mesmo que seja algo que não tenha pensado, talvez seja algo importante e necessário para muitos que mereça ser implementado. Afinal de contas, é assim que as coisas se desenvolvem, faz-se uma aplicação base, a malta queixa-se que não faz o que querem e o programador implementa novas funcionalidades.

Fico à espera de comentários, críticas, dúvidas, sugestões, tudo o que tiverem a dizer...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não sendo um programador frequente em C#, vou dar a minha opinião como programador de aplicações para desktop.

Esse tipo de APIs existem em várias formas, as duas mais simples que conheço são a Serialização, não de XML, e APIs que guardam dados em ficheiros de texto no formato chave-valor.

No caso do Delphi, o sistema funcionava muito bem usando ficheiros INI, o suporte era bom para esse tipo de ficheiros e a forma de usar era bastante simples, muito parecido com o que pretendes, mas novamente, sem ser em ficheiros XML. Em Java tens os ficheiros de propriedades, que tal como a API para manipulação de ficheiros INI em Delphi, é bastante simples de usar e funciona como o que pretendes implementar.

A forma mais simples que usei até este momento para guardar as definições das aplicações foi a serialização. Claro que me obriga a fazer uma classe para cada aplicação mas não mais que isso, depois é só invocar os métodos de serialização e, ora temos as definições persistidas ora as temos em memória e prontas a usar, através de um simples obj.save(), obj.load().

Assim, ou a tua biblioteca acrescenta algo de valor aos sistemas que já existem, ou então não, valeria a pena usar. Isto porque será mais simples usar algo que faça parte da tecnologia que ter de acrescentar uma biblioteca externa ao meu projecto, quando a mesma não acrescenta nada ao desenvolvimento ou à experiência do utilizador que a própria tecnologia base não forneça.

Mas neste caso não faço ideia de como estão as opções no que toca a .net.

Não deixa de ser uma boa ideia, mas seria bom pesquisares o que já existe feito, e até o que existe noutras tecnologias para teres uma visão geral de como alguns dos problemas que colocaste são resolvidos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já pesquisei de mais sobre este assunto (por isso é que criei este tópico com a minha ideia) e como podes ver no tópico, apresentei as alternativas que existem em C# e porquê que não quero usar nenhuma delas

Eu disse inicialmente que não queria serialização para XML e expliquei porquê apesar de não ter aprofundado isso e neste momento também não o vou fazer... Mas da maneira que não quero usar serialização em XML, multiplica isso por 10 e é quanto não quero usar serialização "normal".

Nunca usei serialização "normal" mas uma pesquisa rápida deu para ver que tendo uma classe assim:

public class Employee : ISerializable {
public int EmpId;
public string EmpName;

public Employee() {
	EmpId = 0;
	EmpName = null;
}
}

(código de inicialização às variáveis e serialização não está, mas é irrelevante)

Foi "transformada" num ficheiro com o conteúdo:

  ÿÿÿÿ        @ObjSerial, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null  MyObjSerial.Employee 

EmployeeIdEmployeeName  

    Omkumar

(ate faltam caracteres estúpidos que nem deram para copiar)

Isto é simplesmente estúpido (depende dos casos). Para o que eu pretendo aqui é ridículo fazer isto, a ideia é ser algo simples e queria um ficheiro que seja facilmente lido e editável. A ideia do XML é porque é tipo o standard para guardar dados hoje em dia. Se fosse há uns anos, provavelmente usava APIs para guardar em INI's, mas ficheiros INI's já lá vão... O XML é fixe para guardar este tipo de dados e é isso que quero fazer, serialização está fora de questão.

Logo, na minha opinião, os argumentos que usas não os considero válidos dentro do contexto e da finalidade da biblioteca que pretendo fazer. Serialização pode ser muito bom para várias coisas e por vários motivos, mas está longe de ser o ideal para aquilo que eu quero.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Logo, na minha opinião, os argumentos que usas não os considero válidos dentro do contexto e da finalidade da biblioteca que pretendo fazer. Serialização pode ser muito bom para várias coisas e por vários motivos, mas está longe de ser o ideal para aquilo que eu quero.

Que os consideres irrelevantes é uma coisa, que afirmes não serem válidos é outra.

Apenas indiquei o que tinha usado e o que uso por ser mais simples. E peguei nisso para dizer justificar porque é que eu não usaria a API. Em nada me referi ao facto de ires para a frente com o projecto ou afirmei, que as opções que acho mais simples, sejam as melhores, mais indicadas, etc. São apenas as que considero mais simples de implementar dado serem as que implicam menos tecnologias externas e menos linhas de código.

Dado que não falavas que pretendes editar os ficheiros de definições, e dado que serem ou não editáveis não é importante para uma aplicação, são afinal definições que deverão ser recriadas sempre que faltarem e a aplicação deve conseguir em tudo executar normalmente sem que o ficheiro esteja presente ou seja inválido, não assumi que a serialização fosse algo que te incomodasse.

XML, como tu mesmo indicaste noutro tópico, não parece ser assim tão simples de ler, se nunca usaste serialização como podes afirmar que é mais complicada que ler/escrever XML?

Se querias saber a opinião sobre a utilização da API, dei-te a minha, não usaria tendo em conta as alternativas bem mais simples que existem.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Dado que não falavas que pretendes editar os ficheiros de definições, e dado que serem ou não editáveis não é importante para uma aplicação, são afinal definições que deverão ser recriadas sempre que faltarem e a aplicação deve conseguir em tudo executar normalmente sem que o ficheiro esteja presente ou seja inválido, não assumi que a serialização fosse algo que te incomodasse.

Não se trata da serialização me incomodar, simplesmente acho que é algo estúpido. Sim,  eu li que é assim que tu fazes, não te estou a chamar de estúpido, mas não acho que a serialização seja indicada para este tipo de coisas... Aliás, em 1000 aplicações, encontras quantos que usam serialização para gravar definições de programas? 1? Acho que quer dizer alguma coisa... Serialização serve (e acho que sempre foi feito com isso em mente) para se puder guardar objectos num ficheiro e depois recarrega-lo. Ou seja, tem utilidade para gravar objectos complexos, para algumas strings, inteiros, valores boleanos, etc, não tem utilidade nenhuma e sinal disso é que ninguém faz isso ou raramente se encontra uma aplicação que use serialização para gravar definições de programas.

XML, como tu mesmo indicaste noutro tópico, não parece ser assim tão simples de ler, se nunca usaste serialização como podes afirmar que é mais complicada que ler/escrever XML?

Para começar, não entendes nada do que eu disse no outro tópico. Ler de XML não tem muito que saber, faz-se bem e esse nunca foi o meu problema. Eu nunca disse que esse era o meu problema, tanto neste tópico como nesse de que falas. Completamente irrelevante.

Eu quando disse que nunca usei serialização significa que nunca fiz um pedaço de código para trabalhar com isso, se tiver que fazer isso neste momento não sei como fazer, tenho de pesquisar e ler a documentação. Isso não significa que eu não saiba o que é serialização e como funciona.

E eu nunca disse que serialização normal é mais complicada de ler/escrever que XML. Não sei onde foste buscar isso... Em termos de código, serialização tem muito menos linhas de código mas isso também é irrelevante.

You're totally missing the point!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

boas.

"Re: [C#/VB.NET] Acham que isto tem utilidade?"

A única utilidade que vejo seria refinares as tuas qualidades na concepção da mesma.

"Vocês usariam esta biblioteca?"

Pessoalmente ... não.  existem alternativas que englobam tudo o que referiste, de uma forma simples e prática. http://nini.sourceforge.net/  (p.ex.)

Offtopic.

A serialização é "mais" usada para comunicação, embora também seja usada para configuração em filesystem. Em .NET ou java é relativamente simples e trivial serializar classes instanciadas  para XML . Fica também completamente lefivel.

/ing

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A única utilidade que vejo seria refinares as tuas qualidades na concepção da mesma.

Not really lol... Tenho outras coisas a meio desenvolvimento bem mais interessantes para fazer e que servem melhor para refinar as minhas qualidades, até podes ver por um tópico que anda por ai que já não actualizo à séculos porque nunca mais peguei no controlo, mas daqui a uns tempos volto à carga.

Pessoalmente ... não.  existem alternativas que englobam tudo o que referiste, de uma forma simples e prática. http://nini.sourceforge.net/  (p.ex.)

Realmente tens razão. De facto, já conheci esta biblioteca Nini, mas não me lembrava se quer que existia. Mas na altura que a conheci, houve alguma razão para que eu não querer usar, mas não me lembro qual. Ainda estive aqui a pensar se seria por não suportar XML e desse apenas para ficheiros INI (como indica o nome), se assim fosse não tinha utilidade nenhuma porque eu não quero guardar em INI. Ou então que fosse um .dll muito grande para uma coisa simples. Mas acabei de ver no site que suporta XML e que ocupa uns míseros Kbs...

Talvez a tente usar mais uma vez a ver se faz aquilo que eu quero e assim não perco tempo com esta biblioteca ;).

Pena é que a última versão tenha sido lançada em 2006...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pena é que a última versão tenha sido lançada em 2006...

Isto faz-me lembrar dois quotes:

Software doesn't rot.

If it ain't broke, don't fix it.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas eu não acho que seja bem assim, pelo menos é o que parece lá no fórum do Nini no site do Sourceforge... Pelo que me parece (e é algo que tenho interesse) não tem suporte para UTF-8, pelo menos alguém se estava a queixar com algum problema relativamente ao UTF-8. E isso em ficheiros XML dava-me jeito...

EDIT:

Acabei de fazer uns testes rápidos e cheguei (outra vez) à conclusão que não quero usar o Nini. Não sei se são as mesmas razões da outra vez que tive contacto com o Nini, mas pronto... Antes de continuar devo dizer que sim, eu sei que é open-source e que posso pegar no código e modificar consoante as minhas necessitas mas não o quero fazer. Se houver necessidade de ter de modificar o código, uma linha que seja, prefiro fazer a minha própria biblioteca que faça exactamente o que quero da forma que quero. É uma razão como outra qualquer, quer concordem quer não...

As razões para não querer usar o Nini...

A primeira podem achar estúpida mas pronto, eu é que a vou usar, eu é que sei aquilo que quero ;) Mas aquilo não me permite carregar um ficheiro XML que tenha o nodo da raiz com nome que eu quiser, tem de ter um especifico (Nini) ou lança uma excepção e código não continua. Pensem o que quiserem, chamem-lhe mariquices, não quero saber, mas os meus ficheiros não vão começar com <Nini>. Eu gosto de coisas organizadas e com consistência e para mim, usar <Nini> como elemento de raiz vai contra tudo isso, eu quero que o elemento de raiz tenha um nome alusivo aquilo que o ficheiro representa.

A segunda é que assim como a biblioteca que eu usei no passado como a maior parte das que existe ai, tenho de usar um método especifico ( Get() ) para carregar o valor e outro ( Set() ) para o guardar. Fora isso, ainda têm vários métodos get tipo, GetLong(), GetString(), GetInt(), etc... Se leram bem (Se não leram, releiam) a minha biblioteca facilita muito mais isso. Primeiro, não irá existir vários métodos diferentes para carregar tipos diferentes de dados. Como todos os valores serão guardados em propriedades, elas próprias definem o tipo do conteúdo e a biblioteca irá fazer automaticamente as conversões sem ser necessário chamar um método especifico para ler um valor de determinado tipo. Segundo, evita que eu tenha código assim:

string fileName = source.Configs["Logging"].Get("File Name");
int columns = source.Configs["Logging"].GetInt("MessageColumns");
long fileSize = source.Configs["Logging"].GetLong("MaxFileSize");

E passa antes a ter apenas uma linha, que por acaso é a do construtor que irá automaticamente carregar todos os valores. E para gravar, em vez de chamar o método Set() para cada variável que quero gravar, chamo apenas um método geral que pega nos valores todos e grava-os no XML.

Não estou a dizer que o Nini é mau, aquilo faz muita coisa que a minha biblioteca não faz nem nunca irá fazer. O Nini tem suporte para vários tipos de ficheiros de configuração e a minha biblioteca só irá ter suporte para XML. Mas no exemplo que acabei de falar, acho muito mais interessante ter dois métodos, um para carregar tudo e outro para guardar tudo, do que ter uma série deles e ter de escrever tantas linhas de código quantas propriedades/variáveis/definições.

Mas estou a gostar da discussão, pode ser que me consigam mudar de ideias... Aliás, nem me importava, era menos trabalho, mas neste momento ainda não tenho razões que considere válidas para deixar a minha ideia em águas de bacalhau. Não é que esteja à procura delas, mas se tiverem alguma que eu considere valida e concorde convosco, se calhar é porque estou a perder o meu tempo, mas neste momento, não acho que esteja...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E que tal criares um wrapper para o Nini? Não tens que editar o seu código, só fazer uma biblioteca tua, que o use o nini, para manipulação de XML. Aproveitas o melhor dos dois mundos, a menos que existam operações que não te permita o nini fazer (duvido).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já pensaste em usar reflection para fazer o que queres? Pode simplificar bastante o código.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@Warrior

Isso iria implicar distribuir dois .dlls em vez de um único para fazerem a mesma coisa. E além do mais, vocês continuam a bater na mesma tecla... O problema aqui não é, nunca foi, nem nunca será a manipulação do XML, eu já tenho isso mais ou menos feito. E outra razão é que para aquilo que eu pretendo fazer acho desnecessário usar o Nini... Se fosse fazer um wrapper que fosse usar bastantes funcionalidades do Nini e lhe fosse adicionar outras quantas, talvez fosse uma hipótese, mas neste caso, fica muito melhor se for independente porque apenas iria usar uma ou outra coisa do Nini e para isso, prefiro fazer de raiz e pronto.

E depois, que utilidade teria um wrapper ao Nini com as minhas funcionalidades? Nenhuma... quem tivesse/tiver interesse na minha biblioteca, acredita que não vai precisar de nenhuma das funcionalidades da minha biblioteca e a quem o Nini lhe satisfizer, provavelmente a minha biblioteca não lhe interessa para nada. A não ser que usem muito pouco daquilo que o Nini oferece e a minha biblioteca lhes ajude a simplificar alguma coisa. No meu caso sei que simplifica, por isso é que tenho interesse em desenvolve-la.

@Triton

Assim como o Warrior e mais uns quantos ao longo deste fórum e até mesmo outros lá fora, continuam sempre a dar-lhe na mesma tecla... O problema aqui, a discussão que está em causa, nunca foi a implementação. Eu não estou aqui a colocar dúvidas sobre como fazer algo e vocês estão sempre a discutir isso ou dar sugestões para isso quando não é isso que está em causa. O que está em causa é a forma como o utilizador vai usar a minha biblioteca em comparação com outros métodos. Só se está a discutir usabilidade e implementações por parte do programador que usa a biblioteca e não de quem a fez.

Até porque eu já estou a usar reflection mesmo antes de tu teres feito esse reply. Aliás, este tópico só foi criado porque eu consegui usar reflection para fazer o que queria e só depois de conseguir fazer o que queria é que vim aqui perguntar o que achavam da ideia. Porque o que está em causa (e mais uma vez me repito) é a simplicidade (no meu ponto de vista) com que vão usar a minha biblioteca em comparação com outros métodos, é só isso que está em discussão.

Se eu tiver dúvidas em como programar algo, não se preocupem que isso vai direitinho para o respectivo fórum da linguagem e vão perceber que estou com dúvidas em código, aqui, as dúvidas são outras e nada relacionadas com código e/ou o que usar para implementar seja o que for.

Já perceberam ou nem por isso? É que estão sempre a bater na mesma tecla ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não referi problemas a implementar, era somente uma nova perspectiva para o problema no seu todo.

Eu não conheço as bibliotecas de XML para .net, portanto é complicado opinar, mas a regra é de ouro: ou adicionas algo novo, ou não vale a pena perder muito tempo a preparar algo para distribuir. Porque ou é realmente novo, seja por ter mais funcionalidades ou por ser mais simples de usar, ou então faz simplesmente para ti que é mais rápido.

Tu não pareces querer ir pelo caminho das funcionalidades (realmente confesso que é complicado) mas sim pelo da simplificação, daí ter sugerido o wrapper..

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

No meu ponto de vista será mais simples usar da forma que eu pretendo implementar. Como disse, com Nini precisas de carregar/guardar definição a definição, da maneira que pretendo fazer não. Como já expliquei anteriormente...

Novas funcionalidades era muito complicado e trabalhoso e não é isso que eu pretendo... Seria um desafio giro, mas para o qual não tenho tempo nem paciência.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora