quinta-feira, 10 de novembro de 2011

Receita de bolo para EF CODE FIRST e ORACLE 10G

Utilizando Entity Framework no desenvolvimento de aplicações, temos a vantagem de trabalhar de forma independeente com qualquer banco de dados, desde que haja um "provider" específico para Entity Framework.

Neste post, mostro que é possível utilizar EF com o banco de dados Oracle. Existem diversos providers de Oracle para o EF, um bom exemplo é o da DevArt (dotConnect), porém é uma solução paga. A própria Oracle está desenvolvendo um provedor com suporte ao Entity Framework, porém até o momento deste POST ainda se encontra na versão Beta 3, porém em breve teremos a versão de produção, aí então é só atualizar.


Pré-requisitos:

* ORACLE 10G express edition previamente instalado
http://www.oracle.com/technetwork/database/express-edition/database10gxe-459378.html

* ODAC1120250Beta_EntityFramework_32bit_xcopy
http://www.oracle.com/technetwork/developer-tools/visual-studio/downloads/index.html

* EntityFramework Code First 4.1
http://www.microsoft.com/download/en/details.aspx?id=26825

Mãos à massa!

Crie um novo usuário no Oracle, para este post criei um usuário chamado REPOSITORIO. O banco de dados para este exemplo consite em uma tabela de PESSOAS, que possui zero ou mais telefones, relacionada com uma tabela de TELEONES A estrutura do banco de dados ficou assim:



Crie uma nova aplicação Console e adicione as seguintes referencias:

* EntityFramework.dll
* Oracle.DataAccess.dll (na pasta de instalação do Client do Oracle)

Veja o código completo da aplicação Console (coloquei todas as classes no mesmo arquivo Program.cs para este post, obviamente costumo separar um arquivo para cada classe nos meus projetos) :

Não esquecer de corrigir a string de conexão com o valor correto (geralmente é o nome da estação local).

segunda-feira, 7 de novembro de 2011

A plataforma .NET


Estava pensando aqui sobre a plataforma .NET. É uma plataforma para todos, completa, extensa, robusta, com uma IDE incrível (Visual Studio 2010), com versões express, a maioria do que vou relacionar abaixo são produtos free ou royalty-free, sendo que muitos são OpenSource!

Linguagens criadas para o .NET:

C#
Boo
F#
Visual Basic.NET
Nemerle

Linguagens portadas para .NET:

Programar em Java? IKVM

Programar em Ruby ? IronRuby

Programar em Python? IronPython

Programar p/ Android ? Monodroid

Programar p/ iOS ? Monotouch

Programar em delphi/pascal ? Oxygene

Programar em PHP ? Phalanger.net

Tipos de Aplicativos

Desenvolver para Web ? ASP.NET

Desenvolver para desktop ? WPF, Windows Forms

Desenvolver aplicações RIA? Silverlight

Desenvolver para Cloud ? Azure

Desenvolver WebServices? Windows Communication Foundation


Rodar tudo isso no Linux ? Mono

Existem muitas outras tecnologias envolvendo a plataforma .NET, conforme eu vá encontrando links interessantes vou alterando este post.

terça-feira, 1 de novembro de 2011

Customizando o Repositório - Parte II

Podemos adicionar novas funcionalidades a um determinado repositório e manter a testabilidade. Uma das maneiras de se fazer isso é com o auxílio de uma interface adicional:

Customizando o Repositório - Parte I

Existem alguns métodos que podem ser sobrescritos e customizados com "override" ao extender a classe base do Repositório. Aqui vai um exemplo:

Abaixo segue uns Unit Tests mostrando a utilização do padrão.
Repository Pattern

Utilizando o padrão repositório, as telas e páginas da aplicação que fazem acessos a banco de dados passam a acessar classes intermediárias que atuam como repositórios de dados, tornando a aplicação independente de um banco de dados real. Dessa forma, há uma melhor separação de responsabilidades, onde as telas não possuem lógica de persistência, que passa a ser de responsabilidade do repositório. Isso facilita a troca de banco de dados (utilizar SQL Server, Oracle, MySQL, etc) e também os testes, uma vez que podemos criar repositórios “fake”, trabalhando com listas em memória, além de separar lógica de persistência da lógica de interface com o usuário.

Unit Of Work Pattern

Recentemente refatorei a minha versão de repositório que utilizo em minhas aplicações para dar suporte ao padrão UnitOfWork. Utilizando esse padrão, os repositórios passam a compartilhar entre si um objeto que faz a coordenação das transações dos repositórios a ele anexados em uma única operação Commit/Rollback. Ou seja, ao instanciar os repositórios para uma determinada operação, devo instanciar antes um objeto que implementa IUnitOfWork, e passá-lo na construção desses repositórios. Ao chamar o método Commit() do UnitOfWork, todos os repositórios anexados serão persistidos.


Como foi implementado o repositório?

Após uma refatoração completa, a interface do repositório agora depende de uma interface IUnitOfWork:



Com essa interface criada, podemos criar agora a interface IRepositorio:




Uma classe de extensão para alguns métodos úteis aos repositórios que forem implementados:


Temos o repositório, agora falta a implementação da interface UnitOfWork. Para implementar esta interface, achei conveniente criar uma classe base:

Precisamos da classe Container para nos auxiliar nas implementações de UnitOfWork:



Em seguida todas as implementações para os diversos bancos de dados que desejarmos devem herdar desta classe base, implementando a interface. A seguir a implementação padrão que utiliza Entity Framework CodeFirst, onde no construtor passa-se o DbContext.

A seguir a implementação padrão que utiliza Entity Framework tradicional, onde no construtor passa-se o ObjectContext.



Solução

Download da solution Abaixo segue o código demonstrando como utilizar o Entity Framework 4.1 Code First com 2 tabelas (Pessoas e Enderecos), com relacionamento Many-to-Many, e abstraindo o EFramework com o padrão repositório da forma mais simples, sem injeção de dependência.

Mostre código! 

Classe Pessoa


Classe Endereco


Classe de Mapeamento e Configuração do Entity Framework


Método de teste

sábado, 23 de abril de 2011

Teste a performance do .NET em sua máquina

Momento distração.

Recentemente vi um post do Ayende com a seguinte questão: Quantos objetos podem ser criados por segundo? Conversando com os amigos num Pub, houve chutes de 2.000, 5.000 ou 50.000 objetos por segundo. Então ele fez um teste e para a surpresa dele, o resultado foi 7.000.000 de objetos, isso mesmo, 7 milhões de objetos criados em apenas um segundo com uma aplicação Console.

Fiz o mesmo teste e meu resultado foi melhor: 14.106.434, mais de 14 milhões de objetos por segundo.

Faça o teste em sua máquina, crie uma aplicação console e cole esse código:



    public class MyClass
    {
        public string A;
        public int B;
        public DateTime C;
    }

    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Start();
                var k = Console.ReadKey();
                if (k.Key != ConsoleKey.Enter) break;
            }
        }

        static void Start()
        {
            var sp = System.Diagnostics.Stopwatch.StartNew();
            int i = 0;
            while (sp.ElapsedMilliseconds < 1000)
            {
                new MyClass();
                i++;
            }
            sp.Stop();
            Console.WriteLine("Create {0} in {1}", i, sp.Elapsed);
        }
    }


Faça o teste e comente aqui seu resultado.

Padrão Façade para trabalhar com Sessions em uma aplicação ASP.NET

Trabalhar com strings hard-coded é algo que pode nos levar a introduzir bugs por falta de atenção e erros de digitação.

É algo que pode ocorrer facilmente quando trabalhamos com Sessions dentro de uma aplicação Asp.NET. Para evitar isso, recomenda-se criar constantes e utilizá-las para gravar ou recuperar os valores armazenados nas Sessions.

Uma alternativa interessante é utilizar uma classe Facade para acessar e gravar os valores das Sessions.

Fiz uma classe chamada SessionVars para isso.

public static class SessionVars
    {
        /*constantes para as Sessions*/
        public const string IdUsuario = "IdUsuario";        

        /// 
        /// Verifica se a Contexto da Session é válido
        /// 
        private static bool IsSessionValid
        {
            get { return HttpContext.Current != null && HttpContext.Current.Session != null; }
        }

        /// 
        /// Atalho para a Session
        /// 
        private static HttpSessionState Session
        {
            get { return HttpContext.Current.Session; }
        }

        #region UsuarioId
        public static int? UsuarioId
        {
            get
            {
                if (IsSessionValid)
                {
                    if (Session[IdUsuario] != null)
                    {
                        int idUsuario;
                        if (Int32.TryParse(Session[IdUsuario].ToString(), out idUsuario))
                            return idUsuario;

                        return int.MinValue;
                    }
                }
                return null;
            }
            set
            {
                if (IsSessionValid)
                {
                    Session[IdUsuario] = value;
                }
            }
        }
        #endregion
    }


Em qualquer página aspx.cs basta acessar a classe estática e a propriedade desejada para ler o valor ou gravar.

if (SessionVars.UsuarioId != null)
{                //
SessionVars.UsuarioId = 10;
}


Crie todas as constantes para os nomes das sessions e a propriedade com Get/Set específica.

sábado, 16 de abril de 2011

Porquê Silverlight?

Prefácio

Perfil de uma aplicação Desktop
• Executa diretamente no sistema operacional (Delphi/C++/C).
• Ou através de bytecodes interpretados por uma máquina virtual que faz a compilação JIT (Just-In-Time) em tempo de execução (Java/.NET).
• Em ambas situações, toda a camada de apresentação é criada pela aplicação, que busca os dados em um banco de dados local ou em rede.

Perfil de uma aplicação Web
• Utiliza um software do tipo browser que é executado na estação do cliente que envia e recebe requisições http Get/Post a um servidor WEB http.
• O Servidor recebe as requisições e retorna conteúdo (response) que é interpretado pelo navegador que por sua vez cria componentes visuais de acordo com as intruções recebidas.

Perfil de uma aplicação RIA
• Une o melhor dos dois mundos: Executa na estação cliente e distribuíção é através da Web, com atualizações automáticas (ao carregar a página).
• Utiliza um navegador web que atua como um contêiner para a aplicação.
• A executada da aplicação é controlada por um plugin (Flash, Adobe AIR, Java, Silverlight).
• O plugin é executado no sistema operacional.


Experiências

Delphi

Antigamente eu desenvolvia aplicações utilizando Delphi. Fiz sistemas comerciais para desktop, gerando executáveis nativos para a plataforma Windows, acessando banco de dados Interbase/Firebird, Oracle e SQL Server.

• Prós: ótima IDE, facilidade e rapidez para criar uma aplicação, arrastando componentes visuais e configurando suas propriedades. Cumpre o prometido: RAD - rapid application development.

• Contras: As aplicações têm de ser distribuídas e instaladas diretamente nas estações dos clientes, gerando um trabalho extra e dor de cabeça quando era necessário atualizar versões.

Após a versão 8 do Delphi, muitos programadores passaram a desacreditar no futuro da linguagem, com a Borland vendendo o produto para outras empresas, gerando dúvidas e incertezas. Então os desenvolvedores mais prevenidos passaram a estudar uma outra linguagem, como VB.NET, ou migrar para o mundo WEB, como eu fiz.

PHP

Com a popularização da internet, surgiu uma demanda para criação de aplicações específicas para a Web, e com isso, a necessidade de aprender uma linguagem dinâmica. Dominar Html, CSS e Javascript se tornou essencial. O PHP então era a linguagem mais popular para aplicações web e tinha uma ampla comunidade de desenvolvedores.

• Prós: Ampla comunidade, muitos exemplos na internet e muito material disponível.

• Contras: Na minha experiência com PHP, percebi que não havia um padrão a se seguir, o PHP permite criar aplicações mal codificadas, mal escritas, código “macarrão” (html e código php misturado), e por si só não incentiva o programador a aprender a fundo a linguagem, não exige orientação a objetos nem separação de responsabilidades. É uma linguagem de script, interpretada a cada requisição. Para ter algum padrão, é necessário utilizar um framework. Caso contrário, basta copiar e colar qualquer exemplo de código já existente pela internet simplesmente porque alguém já fez e funcionou.

ASP.NET

Essa percepção “negativa” que tenho hoje do PHP aumentou depois que conheci a plataforma .NET, mais especificamente o ASP.NET, a plataforma da Microsoft para a desenvolvimento de aplicações do tipo “WebForms”. As aplicações WebForms abstraem o conceito de programação para a Web onde cada página é uma tela com componentes visuais, similar a um aplicativo desktop, mas renderizando obviamente conteúdo HTML.

• Prós: Separação de código HTML do código da aplicação, linguagem tipada, estática e compilada, não interpretada a cada requisição.

• Contras: O resultado final ainda é a renderização de HTML,CSS e Javascript que será interpretado no navegador, da mesma forma que qualquer linguagem para Web. Para manter o estado dos webforms e seus controles entre as requisições, simulando uma aplicação desktop), cada webform gera um overhead adicional, utilizando artifícios como Sessions, ViewStates, etc.


A web não foi feita para aplicações

A Web inicialmente não previa a execução de aplicações, como no desktop. Na verdade ela previa apenas a apresentação de conteúdo. Com o tempo, a web foi se adaptadando para simular aplicações. O protocolo HTTP evoluiu, depois surgiu o javascript, a seguir os browsers adicionaram suporte a javascript e plugins, etc. E o que temos hoje é uma mistura de várias linguagens e tecnologias trabalhando em conjunto para fornecer ao usuário um ambiente próximo a um aplicativo desktop. O resultado disso é que cada navegador implementa de maneira diferente essas tecnologias, obrigando o desenvolvedor a prever qual browser o usuário está utilizando, e enviar HTML/CSS/JAVASCRIPT específico para tal navegador (Chrome/IE/Firefox/etc).


Com a Web, sua estação de trabalho é um terminal burro

Vamos resumir o ciclo de vida de uma aplicação Web:

1 – Abrir seu navegador preferido.
2 – Informar a URL do site que contém a aplicação que desejada.
3 – O navegador resolve o endereço IP e encontra o servidor web onde a aplicação está hospedada e envia uma requisição do tipo HTTP/Get.
4 – O servidor web, independente da linguagem em que a aplicação foi feita, vai processar a requisição, executar as instruções necessárias e retornar ao navegador um “Response” contendo o HTML gerado pelo servidor.
5 – O navegador recebe a resposta, e partir daí começa a executar todas as instruções que o código HTML determina. Provavelmente isso vai demandar novas requisições para buscar imagens e outros “includes” como javascript/css, num ciclo interno até que finalmente a página possa ser renderizada no navegador.
6 – Esta página que está sendo exibida, pode conter links para outras páginas, nesse caso, ao clicar num link, inicia-se novamente a partir do item 3.
7 – Esta pagina pode conter um formulário que irá submeter dados ao servidor. Nesse caso, o navegador enviará os dados do formulário para o servidor, através de uma requisição do tipo HTTP/POST. O servidor web receberá esse formulário, a aplicação irá tratar as informações, executando as intruções necessárias e devolverá uma resposta novamente ao navegador. Voltamos então a partir do item 4.

Assim, vemos que uma aplicação web se resume a um navegador que envia requisições do tipo GET/POST, em que todas as respostas geradas pelo servidor web incluem novamente todo o conteúdo necessário para se renderizar uma página com imagens, textos a serem exibidos, código javascript, código CSS para formatação de estilos, etc.

O tráfego de informações que é gerado entre uma requisição e outra não se resume somente aos dados utilizados pela aplicação. Por exemplo, se você solicitar 10 vezes a mesma página ao navegador, todo o ciclo será repetido, e nas 10 vezes você receberá todo o mesmo conteúdo novamente.

Por isso costumo entender que de certa maneira, seu computador quando navega na internet é praticamente um terminal burro conectado a um grande mainframe, em que o mainframe processa toda a informação e envia instruções para o cliente exibir as páginas.

Silverlight – Rich Internet Application

Desenvolver com Silverlight é como desenvolver para desktop, utilizando processamento local para formatar telas através de instruções compiladas, com a facilidade de distribuição e atualização que a web oferece. E ainda com a vantagem de reaproveitar todo seu conhecimento em .NET, sem se preocupar com HTML, Javascript e CSS.

Uma aplicação Silverlight incialmente é um objeto carregado dentro de uma página Html. Após esse objeto ser carregado, a aplicação é gerenciada pelo runtime do Silverlight, dentro de uma área isolada e protegida conhecida como sandbox. Nesse ambiente, o silverlight por padrão faz requisições e recebe as respostas através de sua própria implementação de cliente http. Todo o conteúdo necessário para exibir e renderizar as telas e controles não precisam ser carregados ou interpretados novamente, tudo o que a aplicação precisa já está no objeto que foi carregado dentro do navegador. A comunicação com servidores Web se resume apenas a troca de dados, e não mais formatação de telas e regras de negócios.
Portanto, com o Silverlight, você programa praticamente como se programasse para desktop, utilizando uma única linguagem (no meu caso, C#), sendo que a distribuição da aplicação é direto pela Web, unindo o útil ao agradável.

domingo, 27 de março de 2011

Classe base para ViewModels - Padrão MVVM - Silverlight

Para facilitar a utilização do padrão MVVM, devemos utilizar uma classe base para as viewmodels. Segue abaixo o código que uso para minha classe ViewModelBase (http://pastebin.com/h5WD4V6q):



Toda vez que alteramos um valor de uma propriedade ou comando em uma viewmodel, devemos disparar um método NotifyOfPropertyChanged (muitos frameworks chamam de RaiseProperyChanged ou nomes parecidos).

Isso serve para notificar à view que o valor da propriedade foi alterado e que o componente visual relacionado àquela propriedade deve ter seu conteúdo atualizado (Binding Mode=OneWay/TwoWay).

Uma classe simples que implementa essa classe base ficaria assim:



Código comentado

sábado, 19 de março de 2011

Continuando o artigo anterior – Utilizando MEF com Silverlight na prática

No artigo anterior, criamos dois novos UserControl’s com atributos [Export] e mostrei como visualizá-los dentro da MainPage usando MEF.

Uma vez que o MEF criou uma instância de uma classe que foi exportada, toda vez que solicitarmos novamente ao catálogo essa mesma classe, será retornada a mesma instância.

Para deixar isso bem claro, coloquei um textblock que informa a data e hora em que o MEF criou o objeto. No caso de precisarmos atualizar essa data sem criar uma nova instância, teremos que simular um evento que indica quando aquele usercontrol foi solicitado novamente ao Catálogo.

Uma solução para isso é criarmos uma interface que chama um método para realizar essa tarefa de atualizar a data/hora do textblock. Mãos à obra!

Vamos criar duas interfaces: uma interface chamada IMainPage que conterá um método MostrarTela(string contrato), e outra interface chamada ITela que conterá um método Activate().

Crie uma pasta chamada “Contratos” dentro do projeto silverlight e adicione essas duas interfaces da seguinte maneira:

//interface IMainPage
namespace SilverlightApplication1.contracts
{
    public interface IMainPage
    {
        void MostrarTela(string contrato);
    }
}

//interface ITela
namespace SilverlightApplication1.contracts
{
    public interface ITela
    {
        void Activate();
    }
}


Abra o arquivo MainPage.xaml.cs e implemente a interface IMainPage. Os eventos do Click dos botões também devem ser alterados para chamar o método MostrarTela passando a string do contrato desejado como parâmetro. O conteúdo da classe inteira ficará dessa forma:

[Export("MainPageExport", typeof(UserControl))]
public partial class MainPage : UserControl, IMainPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void Tela1_Click(object sender, RoutedEventArgs e)
    {
        MostrarTela("Tela1");
    }

    private void Tela2_Click(object sender, RoutedEventArgs e)
    {
        MostrarTela("Tela2");
    }

    #region Implementation of IMainPage
    public void MostrarTela(string contrato)
    {
        ITela tela = CatalogoMef.GetInstance<UserControl>(contrato) as ITela;
        if (tela != null)
        {
            mainPageContentControl.Content = tela;
            tela.Activate();
        }
    }
    #endregion
}

Repare na implementação do método MostrarTela que chamamos a tela com o contrato solicitado através do catálogo do MEF. Se o MEF encontrou a tela, a variável “tela” não será nula, então setamos o conteúdo do controle MainPageContentControl para o valor retornado pelo MEF e em seguida, chamamos o método Activate() da interface ITela. Esse método será implementado nos UserControl’s Tela1.xaml.cs e Tela2.xaml.cs. Veja como deve ficar:

[Export("Tela1", typeof(UserControl))]
public partial class Tela1 : UserControl, ITela
{
    public Tela1()
    {
        InitializeComponent();
    }

    #region Implementation of ITela

    public void Activate()
    {
        dataHoraCriacao.Text = DateTime.Now.ToString();
    }

    #endregion
}

Faça a mesma alteração no arquivo Tela2.xaml.cs:

[Export("Tela2", typeof(UserControl))]
public partial class Tela2 : UserControl, ITela
{
    public Tela2()
    {
        InitializeComponent();
    }

    #region Implementation of ITela

    public void Activate()
    {
        dataHoraCriacao.Text = DateTime.Now.ToString();
    }

    #endregion
}

Dessa forma, ao implementarmos a interface ITela que criamos na pasta “Contratos”, somos obrigados a implementar o método Activate. Nesse método Activate, será feita a atualização da Data e Hora do textblock.

Execute a aplicação e você verá que agora a data/hora sempre estarão atualizadas.

Neste artigo podemos concluir que através do auxílio de interfaces, podemos controlar e manter o estado das telas que foram instanciadas.

Para finalizar vamos implementar um método DeActivate() que será chamado quando a tela ficar invisível.
Para isto, altere a interface ITela e adicione um método DeActivate() da mesma forma como declarado o método Activate():

//interface ITela
namespace SilverlightApplication1.contracts
{
    public interface ITela
    {
        //método chamado quando a tela ficar vísivel
        void Activate();

        //método chamado quando a tela ficar invisível
        void DeActivate();
    }
}

Como adicionamos um método novo na interface ITela, agora precisamos implementar esse método na Tela1 e Tela2:

public void DeActivate()
{
    dataHoraCriacao.Text = "";
}

Pra concluir essa funcionalidade, vamos adicionar uma propriedade na interface IMainPage, que será uma referência à tela que está Ativa no momento:

//interface IMainPage
namespace SilverlightApplication1.contracts
{
    public interface IMainPage
    {
        //propriedade que vai guardar a referência à tela que estiver ativa
        ITela TelaAtiva { get; set; }
        void MostrarTela(string contrato);
    }
}

Em MainPage.xaml.cs, a classe toda ficará dessa maneira:

[Export("MainPageExport", typeof(UserControl))]
public partial class MainPage : UserControl, IMainPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void Tela1_Click(object sender, RoutedEventArgs e)
    {
        MostrarTela("Tela1");
    }

    private void Tela2_Click(object sender, RoutedEventArgs e)
    {
        MostrarTela("Tela2");
    }

    #region Implementation of IMainPage

    public ITela TelaAtiva { get; set; }

    public void MostrarTela(string contrato)
    {
        if (TelaAtiva != null) TelaAtiva.DeActivate();
        TelaAtiva = CatalogoMef.GetInstance<UserControl>(contrato) as ITela;
        if (TelaAtiva == null) return;
        mainPageContentControl.Content = TelaAtiva;
        TelaAtiva.Activate();
    }
    #endregion
}

Toda vez que uma nova tela for chamada, a tela ativa atual irá executar o método DeActivate(), nesse método poderemos fazer o que acharmos necessário quando uma tela ficar invisível. Em seguida, a nova tela passa a ser ativa e então o método Activate() é chamado.


Código fonte do projeto aqui