Archive for the ‘.NET’ Category

Uma experiência a compartilhar

setembro 9th, 2009

Por um motivo que prometo explicar depois, tive que criar uma api para fazer o mapeamento de objeto-relacional para um sistema em Csharp que estamos desenvolvendo.  Como não gosto de reinventar a roda, parti para ver como os frameworks mais usados fazem isso e procurei fazer uma implementação light do que eu vi. Para título de curiosidade me baseiei em Hibernate,  Linq, etc.

O primeiro passo foi determinarmos com o faríamos a questão do mapeamento : para tanto resolvi partir do que hoje é feito pelo hibernate. Dentro do hibernate, simplificando muito o seu funcionamento, você tem um configuração que diz qual campo faz referencia a qual atributo (ou propriedade), qual tabela, as relações, etc.  O hibernate então ao receber o objeto para persistir, por exemplo, pega este dados, monta a query (insert,delete, update, select) e faz a operação. Como disse antes a idéia foi fazer algo light, sendo assim, optamos apenas por mapear os campos, tabela e objetos e não sua relações (com isso eliminamos muita complexidade). Sendo assim, nosso objetos deveriam apenas “saber” qual tabela e colunas a serem mapeadas.

O segundo desafio foi definirmos como iríamos fazer esse mapeamento :  usaríamos um xml, um arquivo de propriedades, base de registro, e por ai seguimos. Após muita discussão vimos que o usuário de nossa api de persistencia seria um outro programador, por isso, teríamos que fazer algo que facilitasse a vida deste cara. Foi aí que decidimos usar Atributos (o mesmo que anotações em Java). Para minha surpresa, criar atributos customizados em Csharp é algo realmente simples (veja o post que escrevi sobre com dicas de como fazer – clique aqui)

Sei que minhas próximas palavras vão soar estranhas para quem não curte codificar como eu, mas :  Não é que a coisa ficou bonita ! A implementação ficou fácil e tudo concentrado na classe sem necessidade de xmls, arquivos externos, problemas de atualização de base de registro, etc.

O meio do caminho – a transformação dos dados dos objetos para relacional e vice versa – foi toda feita com a api de Reflection do .NET. Ela é bastante poderosa, porém com inúmeras diferenças para quem já está acostumado com o Java.  Mas insisto, ela é bem poderosa e interessante.

Ao usar Reflection e rodar nossos testes (isso mesmo estamos desenvolvendo com o TDD – desenvolvimento orientados por teste, escrevemos os testes antes e depois vamos implementando), vimos que ocorria um erro de conversão:  O sistema dizia que não era capaz de converter um valor System.Decimal para System.Int32.

Cabe uma explicação ai: em .NET, ao acessar uma base de dados, para percorres o resultado de uma query você tem um objeto DataReader. Esse objeto é como um mapa dos valores da linha.  Para ele, os valores numéricos ficam mapeados como Decimal e por isso o erro.

A solução achei graças ao Google : basta usar a seguinte linha de código e todos os meus problema sumiram:

1
info.SetValue(obj,System.Convert.ChangeType(objReader[column.name],info.PropertyType),null);

O segredo da linha acima é de usar System.Convert.ChangeType . Ele se encarregará de fazer a conversão correta. Como argumento este metodo tem : valor a ser convertido, tipo para qual será convertido o valor.
Bem essa foi a minha aventura das últimas semanas. Achei legal compartilhar pelas dificuldades e de como fizemos para chegar a solução final.

Usando atributos customizável em C#

setembro 1st, 2009

Muitos programadores sabem o quanto criar configurações ou arquivos de configurações para flexibilizar as aplicações ou uso de apis é um trabalho árduo. Na maioria dos casos opta-se por arquivos de XML  cuja a sintaxe nem sempre é fácil de entender e muito desacoplada da classe que irá usá-la dificultando muito a compreensão do funcionamento do sistema.

Muitas pessoas (desenvolvedores) sempre procuram criar sistemas ou api que sejam capazes de atender a uma grande quantidade de cenários sem que hajam modificações diretas em seus fontes.  Para tanto, parametrizam em forma de configuração externas valores que o sistema deve usar que serão particulares para cada caso, exemplo:  nome do banco de dados, diretório onde ficam os arquivos de template, quantidade de dias que devem manter um dado no memória, mapeamento objeto relacional de um objeto, etc.

Na maioria dos casos essa parametrização ou configuração é possibilitada pela criação de arquivos XML, onde quem irá usar o sistema ou a biblioteca deverá preencher com os valores desejados. Isso faz com que o sistema torne-se flexivel e evita customizações em código para casos particulares.  Detendo-se mais no caso de bibliotecas, por exemplo, api de persitencia (mapeamento objeto relacional), esta forma de fazer é bastante útil, embora adicione uma grande carga ao desenvolver pois além de escrever suas classes e etc, também tem que escrever e gerenciar os arquivos de configuração daquela Dll ( ou jar se for caso de java, por exemplo).

Um outro aspecto que considero no uso de XML para configurações é que ele fica desacoplado demasiadamento do código. Para o caso de um sistema, issso é bom, pois o usuário não interessa, somente importa definir os parametros e é tudo. Para o caso de uma biblioteca a coisa muda um tanto de figura, pois se quer deixar sua aplicação com um entendimento claro e no caso aqui, a classe e sua parametrização ficam em arquivos separados.

Foi pensando nisso que as linguagens atuais começaram a tentar em suas novas versões criarem recurso de forma a facilitar este tipo de trabalho.  Neste contexto que temos as anotações, para o JAVA, e os atributos, para o .NET.

Anotações e atributos fazem o elo entra a implementação e a parametrização. Tornando o código claro, legível e compreensível.

As anotações ou atributos são metadados que adicionamos as nossa classe que nos permitem de através delas passarmos informações de parametrização e configuração.

1
2
3
4
5
6
7
8
9
class Client
{
private string nome;
[MyCustomTag(sbrubles=true)]
public void SayHello()
{
System.out.println("Hello" + nome);
}
}

No exemplo acima, minha classe tem um método que coloco um atributo que tem uma propriedade Sbrubles que pode receber um valor booleano. Depois, por Reflection, posso pegar os dados deste atributo e usar para fazer alguma coisa. Esse tipo de abordagem neste tipo de caso, é bem melhor por fica claro os parametros e sua associação. Além disso o trabalho reduz pois agora basta a própria classe para a implementação e para a configuração.

Em Csharp, para criar seu atributo, bastar criar uma classe que extenda a classe System.Attribute. Além disso, por meio de atributos na classe, é preciso definir se este atributo será ligado a metodo, classe, propriedade, etc, se pode se repetir, etc.  Exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[AttributeUsage(AttributeTargets.Class |
    AttributeTargets.Constructor |
    AttributeTargets.Field |
    AttributeTargets.Method |
    AttributeTargets.Property,
    AllowMultiple = true)]
class MyCustomAtribute : System.Attribute
{
       private bool sbrubles;
       public bool Sbrubles
       {
            get { return sbrubles;}
            set { sbrubles = value;}
       }
}

E para ter acesso ao dados, você pode ter o seguinte codigo:

1
2
3
4
...
object[] attributes;
attributes =
   inf.GetCustomAttributes(typeof(BugFixAttribute),false);

Usando using no seu codigo C#

abril 17th, 2009

Um outro dia estava eu e um amigo discutindo sobre linguagem e acabamos por falar sobre a questão do C# possuir o “using”. Ele é uma das coisas interessantes que o C# tem em relação a outras da mesma familia (como Java).
Para começar é preciso entender que o using tem 2 possiveis usos:

  • criar um apeliado (alias) para um namespace, e assim facilitar o uso das classe dentro dele
  • importar as classes de um determinado namespace; algo parecido com o import do java
  • Um outro uso possível e bem util do keyword é o seguinte: Imaginemos a situação que você tem um Reader de arquivo e vai efetuar a leitura do conteudo:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    StreamReader reade = new StreamReader("teste.txt");
    //vou ler o arquivo agora...
    string msg = "";
    while(!reader.EndOfStream)
    {
          msg << reader.ReadLine();
          cliente.Incremment();
    }
    reader.Close();

    Bom nesse caso, tudo funciona ok… entretanto imagine o caso da classe cliente, por exemplo, ser nula, ou seu metodo de incremment dispare uma exceção. O sistema irá sair do bloco de codigo e não vai fechar o reader. Isso pode gerar diversos problemas futuros como lock do arquivo e etc. Para resolver isso, muitos diriam – “coloca o bloco de codigo dentro de uma estrutura try catch finally”. Excelente, vamos lá:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    try
    {
       StreamReader reade = new StreamReader("teste.txt");
       //vou ler o arquivo agora...
       string msg = "";
       while(!reader.EndOfStream)
       {
          msg << reader.ReadLine();
          cliente.Incremment();
       }
        reader.Close();
    }
    catch(...)
    {
    }
    finally
    {
       reader.Close(); // e quaisquer outros tratamentos
    }

    O código acima garante a robustez, mas, pelo menos para mim, o código fica muito “poluído”. Vamos agora ver um outro uso do using:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    using (StreamReader reade = new StreamReader("teste.txt"))
    {
       //vou ler o arquivo agora...
       string msg = "";
       while(!reader.EndOfStream)
       {
             msg << reader.ReadLine();
             cliente.Incremment();
       }
    }

    Fazendo isso, o interpretador, ao final garantirá o close do Reader. Isso também é valido para Connections (conexão com o banco de dados por exemplo). Isso deixa o codigo bem elegante. Outra coisa que esta clasula garante que o tempo de vida da classe é somente da execução do bloco, ou seja, ele realizará o dispose do objeto assim que terminar ou sair do bloco. Isso ajuda bastante a evitar os memory leaks e deixar seu codigo super elegante e perfomante.
    Aos poucos vou colocar mais tutoriais como este e sobre outras linguagens. Caso tenham duvida podem mandar email ou deixar comentário que tento responder por email ou por meio de um post.

    Lendo um arquivo permitindo que outro processo ou programa o altere

    abril 14th, 2009

    Estava escrevendo um sistema no meu trabalho em C# (csharp) onde se conecta ao log de uma aplicação e escreve as linhas deste num panel (winform). A primeira dificuldade foi como poderia permanecer lendo o arquivo de forma continua. Resolvi com o trecho de codigo abaixo:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ....
    try
    {
          StreamReader reader = new StreamReader (File.OpenRead("<caminho completo do arquivo>"))
          while (true)
          {
               msg = reader.ReadLine();
               ...
         }
    }
    catch(Exception e)
    {
         System.Console.WriteLine(e.Message);
    }

    Bem isso funcionou bem, a questão que ao fazer isso, por padrão o sistema trava o arquivo não permitindo que outro processo possa escrever no documento. Como queria apenas ler e permitir que a aplicação continuasse a escrever seu log, a solução foi, explicitar o a abertura do arquivo, pelo metodo Open, algumas diretivas. Fica mais ou menos assim:

    1
    2
    StreamReader reader = new StreamReader(File.Open("path",FileMode.Open,FileAccess.Read, FileShare.ReadWrite));
    ...

    Isso funcionou legal e me serviu bem pois agora tenho uma ferramenta simples para ficar vendo o log da minha aplicação.

    Fazendo Java conversar com o PLC

    março 15th, 2009

    Alguns conhecidos que lêem este blog me pediram para escrever mais post sobre a questão de como um programa Java poderia conversar com um PLC. Posso adiantar que a tarefa não é da mais simples e, como dizem em diversos foruns do assunto, coisa para que tem “coração forte”. Primeiro, muitos dos que vão se aventurar a fazer algo do genero vão perceber que a quantidade de informações nesse sentido são pouquíssimas e as tem, em sua grande maioria, são pagas. Passei bons meses vasculhando a internet (Deus abençoe o Google :D ) e o resultado por vezes foi desencorajador.
    A maioria dos fabricantes de PLC tem adotado o OPC (OLE for process control) disponibilizando aplicativos para so Windows que expões as tabelas de dados dos plcs através de servidores OPC. Com evolução crescente dos equipamentos, alguns já nem precisam mais do aplicativo e permitem o acesso eles mesmos através de cartas especiais, mas isso é assunto de posso escrever em outro post. O Opc foi algo especificado na tecnologia da Microsoft. Como é algo M$ é facil concluir que toda a gama de produtos da M$ tem este suporte, assim como o seu .NET (suporte nativo através do ActiveX e DCOM) . JUntando outros motivos e o citada anteriormente, tem-se hoje um predileção a escolher a plataforma Windows para o desenvolvimento de drivers, e aplicativos SCADA o que explica a raridade de opções em outras tecnologias e SO. E não é diferente com java.
    Alguém poderia dizer ao ler os paragrafos acima que seria simples: “Basta escrevermos uma bilbioteca OPC em Java que está tudo pronto”. Sim, concordo em parte e digo que quem se candidatar faça-o e depois permita que utilizemos sua API pois esta não é uma tarefa nada facil. Um outro caminho seria partir para implementar algum protocolo particular do plc em Java. Bem isso pode ser um caminho, pois alguns deles estão escritos em C seria algo como um engenharia reversa. A questão que temos que pagar por suas especificações ou bibliotecas e fazÊ-lo seria um violação das leis.
    Nos sobram poucas possibilidades (bem poucas).
    A maioria das opções válidas são pagas e as open source existentes cobrem apenas uma pequenas parte e tem aplicações muito específicas. Uma outra opção seria escrever algo em JAva que acessaria a um driver de um fabricante e por meio deste faria o acesso (é deste jeito que meus programas em .NET fazem). MAS COMO ACESSAR O DRIVER ESCRITO PARA Windows? Bem, a maioria deles expõe seus serviços por meio de DCOMs, bastaria que seu java falasse este “protocolo”. Para tanto, antes que o leitor comece a escrever suas classes através do JNI sugiro uma olhada na api j-Interop. Vale a pena e funciona.
    A minha intenção é juntar um pessoal para escrevermos uma biblioteca de acesso em java sobre a licença LGPL. Assim que conseguir aviso a galera.

    Utilizando Cruise Control para aplicações .NET

    março 4th, 2009

    Por mais que tenha um grande experiência com desenvolvimento de sistemas em Java, alguns das aplicações, principalmente para supervisórios, tenho que fazê-los em .NET, por diversos motivos (facilidade no uso de COM e DCOM, OPC, etc). Ao utilizar o .NET, fora o domínio que não é tão grande quanto domino o Java, sempre senti falta de diversos recursos, como por exemplo: bilbioteca de teste unitário, behavior test, bibliotecas que encapsulem processos trabalhosos, servidores de integração continua, etc. Parti do pressuposto que algo similar deveria existir para .NET e me pus a procurá-los.
    Nessas buscas pela internet (Deus abençoe o Google) acabei achandos, os similares a diversas coisas que temos para Java : hibernate -> nhibernate, ant — >nant, junit —> nunit… e por ai vai… Ainda me restava achar algo para realizar o build de forma integrada, ou seja, integration continuous. Acabei encontrando o Cruise Control (que já utilizei para Java) e vi que eles portaram quase todas as funcionalidades existente na versão Java para a versão .NET.
    O Cruise Control é uma ferramenta feita, creio eu, pelo pessoal da ThoughtWorks, cuja a função é realizar builds da aplicação de forma integrada, por exemplo: ao commitar uma modificação no seu SOurce Safe ou CVs ou SVN, esta ferramenta é capaz de executar os teste unitários para verificar a integridade, executar teste de cenários (behavior tests), criar um build (caso todos os testes deêm ok) e avisar a todos do status do projeto. Isso, para um projeto grande, com uma equipe relativamente numerosa, representa um “mão na roda” e facilita muito a vida e aumenta a qualidade e permite manter no controle de versão um build estável.
    Pretendo utilizá-lo num projeto que devo começar (o mesmo que vou usar o SCRUM – vai ser um verdadeiro laboratório) e assim que for evoluindo em seu uso vou postando pequenos tutoriais e relatos de experiências.