Meu Dindin - Mudando alguns conceitos

Por Juliano Oliveira em Outubro 4, 2008

Hoje fiz uma pequena analise e melhorei muita coisa. Na verdade, voltei um passo para andar mais dois. Hoje temos um sistema de login´e cadastros de usuário. Faltam algumas coisas, como usabilidade, mas foi muito bom fazer as mudanças que fiz. A primeira delas é a modelagem inicial do banco. Vejam como ficou:

Meu Dindin

 

Outra grande mudança é a troca do Linq to Sql para o Linq to Entities. As classes:

image

Foi extinto do projeto as camadas MeuDindin.Interfaces e MeuDindin.Models. Os modelos agora são os Entities gerados pelo framework. As interfaces do Repository foram transferidas para a camada MeuDindin.Data, no mesmo local onde estão as suas implementações.

Foi adicionado ao projeto também um arquivo SQL para facilitar a criação do ambiente para os colaboradores do projeto. Criei também a string de conexão do Linq to Entities com o banco em uma variável. A string é essa:

“metadata=~/bin/MeuDindin.csdl|~/bin/MeuDindin.ssdl|~/bin/MeuDindin.msl; provider=System.Data.SqlClient;provider connection string=”Data Source=localhost\\sqlexpress;Initial Catalog=MeuDindin;Integrated Security=True\”";

A idéia é facilitar a vida de quem quiser colaborar no projeto.

IMPORTANTE: Inicialmente estava sendo distribuido no projeto o banco em arquivo mdf (MeuDindin.mdf). Para melhorar a criação do ambiente para desenvolvimento, o colaborador terá que ter o SQL Express instalado em sua máquina, criar a base de dados MeuDindin e executar o script de SQL que está sendo distribuido junto do projeto.

Dúvidas comentem!

[]´s

Meu Dindin - Desenvolvendo

Por Juliano Oliveira em Outubro 1, 2008

Galera, estive baixando os códigos do projeto na empresa onde trabalho e tive alguma dificuldade em deixar o ambiente de desenvolvimento funcionando normalmente.

A primeira dificuldade que encontrei foi que toda configuração da localização do banco de dados MeuDindin.mdf (Projeto MeuDindin.Web em App_Data) está com o endereço físico da minha máquina! O “mdf” está em:

‘C:\Users\Juliano\Documents\Visual Studio 2008\Projects\MeuDindin.Web\MeuDindin.Web\App_Data\MeuDindin.mdf’

Essa configuração é do Linq. Encontramos isso em vários arquivos no projeto. Essa é a primeira coisa para corrigirmos. Pretendo implementar algum recurso facilitar essa configuração.

Outra coisa é que quando não estamos com o banco de dados em Check-in ele é read-only, ou seja, somente leitura e ao tentarmos gravar alguma coisa nele, vamos ter um erro. Nesse caso, façam um Check-in do banco ou mude os atributos do arquivo e da pasta App_Data.

Verificando essas duas características na solução, você já vai poder colaborar e testar seus códigos.

[]´s

Meu Dindin, agora já tem casa

Por Juliano Oliveira em Setembro 30, 2008

logo

Acabei de liberar o servidor do projeto!

http://www.meudindin.com/

Espero que breve eu possa estar liberando uma preview do projeto!

[]´s

Microsoft e jQuery - Uma esperada união

Por Juliano Oliveira em Setembro 28, 2008

Hoje tive uma notícia feliz. Começou lendo o post do Scott Gu (jQuery and Microsoft).

image

Depois John Resig (criador do jQuery) também anunciou em jQuery, Microsoft and Nokia.

Logo em seguida o Scott Hanselman demonstrando a integração do jQuery no Visual Studio e ASP.NET MVC em jQuery to ship with ASP.NET MVC and Visual Studio.

Microsoft is going to make jQuery part of the official dev platform. JQuery will come with Visual Studio in the long term, and in the short term it’ll ship with ASP.NET MVC. We’ll also ship a version includes Intellisense in Visual Studio.

É isso ai, o jQuery, o melhor framework de Javascript já escrito (não desfazendo dos outros frameworks, mas é que o jQuery é absurdamente eficiente no que foi proposto a fazer), é parte oficial da plataforma de desenvolvimento web. E TERÁ INTERGRAÇÂO TOTAL NO VISUAL STUDIO!

Ótima noticia não é?

UPDATE: Texto legal sobre a mudança da filosofia Microsoft

[]´s

Meu Dindin - Projeto ASP.NET MVC

Por Juliano Oliveira em Setembro 27, 2008

Estou iniciando mais um projeto open-source no Codeplex.

Logotipo

A idéia é um sistema de contas a pagar, contas a receber, fluxo de caixa e outros recursos de contabilidade voltado para a contabilidade e controle de orçamento pessoal. Iniciativa que vem do meu bom senso: Eu nunca sei para onde vai meu dinheiro.

Inicialmente publiquei apenas a solução e os projetos que usarei na arquitetura do projeto. Próximo passo é fazer um sistema de login de usuários.

Espero a ajuda da comunidade!

Meu Dindin - Descrição

Meu Dindin - Download

[]´s

NHibernate 2.0

Por Juliano Oliveira em Setembro 27, 2008

Para quem ainda não sabe no final de agosto saiu mas uma versão do famoso framework de ORM, o NHibernate 2.0 (irmão do mais famoso ainda Hibernate do Java).

image

Parece que tem bastante coisa nova. Vale a pena conferir.

NHibernate Download

[]´s

StructureMap - Uma Injeção de Dependências

Por Juliano Oliveira em Setembro 25, 2008

Esses dias, estudando alguns Design Patterns (eu e o Rafael que trabalha comigo) conheci o StructureMap. Um framework para aplicarmos em nossas aplicações um pattern chamado Dependency Injection (ou apenas DI) quem tem a missão de baixar o nível de acoplamento da aplicação com e seus componentes.

Um exemplo prático!

Para você entender nosso exemplo, vou explicar o nosso objetivo! Vamos montar uma fábrica de Monitores! (Como assim?!) Pense em uma coisa que todo monitor tem? Um botão! Um botão que liga e desliga! Então, faremos uma interface de monitor com dois métodos: ligar e desligar. A partir dai cada fábrica de monitor implementa as interfaces como quiser.

PS: Desenhei um monitor no formulário. Nossos métodos retornarão cores, simbolizando o estado! Ao ligar nosso monitor Samsung a tela fica azul e ao ligar nosso monitor Lg fica vermelho. Quando desligarmos nosso nomitor Samsung nossa tela fica azul escuro e o Lg deixa a tela branca ao desligarmos. Vocês vão entender ao lerem o post todo!

Para começar, criei uma solução com um projeto Windows Form com o nome de MeuMonitor, um projeto Monitor, que será nossa interface e outros dois projetos class library: MonitorSamsung e MonitorLG!

image

Nosso fomulário tem nosso monitor!

image

Nossa classe Monitor implementa nossa interface:


namespace Monitor
{
  public interface IMonitor
  {
    Color Liga();
    Color Desliga();
  }
}

E nossas classes MonitorSamsung e MonitorLG implementão o seguinte:

MonitorLG retorna Color.Red ao ligar e Color.White ao desligar.


namespace MonitorLG {

  public class MonitorLG : IMonitor {
    public Color Liga() {
      return Color.Red;
    }

    public Color Desliga() {
      return Color.White;
    }
  }
}

MonitorSamsung retorna Color.Blue ao ligar e Color.DarkBlue ao desligar.


namespace MonitorSamsung {

  public class MonitorSamsung: IMonitor {
    public Color Liga() {
      return Color.Blue;
    }

    public Color Desliga() {
      return Color.DarkBlue;
    }
  }
}

Quase tudo pronto, agora configuramos o StrucuteMap através do arquivo StructureMap.config:


<?xml version="1.0" encoding="utf-8" ?>
<StructureMap>
  <Assembly Name="Monitor" />
  <Assembly Name="MonitorLG" />
  <Assembly Name="MonitorSamsung" />
  <PluginFamily Type="Monitor.IMonitor" Assembly="Monitor" DefaultKey="MonitorSamsung">

    <Plugin Type="MonitorSamsung.MonitorSamsung"
            Assembly="MonitorSamsung"
            ConcreteKey="MonitorSamsung" />

    <Plugin Type="MonitorLG.MonitorLG"
                Assembly="MonitorLG"
                ConcreteKey="MonitorLG" />
  </PluginFamily>
</StructureMap>

Olha nosso projeto:

image

O que queremos com tudo isso? Em nosso projeto, referenciamos um objeto global que referencia a interface IMonitor, o objeto “_monitor”. Esse objeto tem os métodos Liga() e Desliga(). Dá uma olhada na tela do monitor lá em cima, está vendo os RadioButtons? Ao serem clicados, eles mudam a instância de “_monitor” atravéz do StructureMap.


    private void oSamsung_Click(object sender, EventArgs e) {
      _monitor = StructureMap.ObjectFactory.GetNamedInstance<IMonitor>("MonitorSamsung");
    }

    private void oLg_Click(object sender, EventArgs e) {
      _monitor = StructureMap.ObjectFactory.GetNamedInstance<IMonitor>("MonitorLG");
    }

E os botões Liga e Desliga? Esses são os folgados do nosso projeto. NÃO FAZEM NADA DE DIFERENTE! Sempre fazem a mesma coisa, não havendo diferença mas manitor Samsung ou LG.


    private void bLiga_Click(object sender, EventArgs e) {
        MonitorTela.BackColor = _monitor.Liga();
    }

    private void bDesliga_Click(object sender, EventArgs e) {
        MonitorTela.BackColor = _monitor.Desliga();
    }

Pronto! Agora é só sair implementando várias classes: MonitorPhilips, MonitorSony, MonitorCCE, MonitorMitsubishi e configurar o StructureMap para que ele saiba dos assemblies.

O StructureMap nesse nosso caso serve como um Gerenciador de Plugin. Imagine os as implementações de IMonitor como plugins!

Mas vejam! O que eu quis demonstrar é o Design Pattern Dependency Injection onde nossa aplicação não depende de MonitorSamsung e nem de MonitorLG, baixamos o nível (de acoplamento). E acabamos criando um sistema gerenciador de plugin.

Espero que se diviram!

Download do exemplo da fábrica de monitores

StrutureMap Description

Structure Download

O post que me inspirou

[]’s

LINQ: Logs na Janela Output

Por Juliano Oliveira em Setembro 15, 2008

Um método que é sempre útil nos nossos trabalhos de depurar erros é o Debug.Print (namespace System.Diagnostics). Com esse método podemos definir saídas de dados para a janela de Output, facilitando a visualização de valores de variáveis por exemplo.

Debugar, debugar e debugar! Ese é o nosso trabalho certo. E para isso, as classes DataContext do LINQ possuem uma propriedade chamada Log. Esta propriedade é a saída de log de tudo que é gerado pelo LINQ, por exemplo, as querys geradas automaticamente por ele em ações de insert, select, update ou delete. Em aplicações Console é bem fácil de se utilizar.


DataContext db = new DataContext();
db.Log = Console.Out;

Agora em aplicações Windows ou WPF necessitamos da ajuda de outras classes para visualizarmos essa saída de código. Na aplicação teremos algo assim:


DataContext db = new DataContext();
db.Log = new DebuggerWriter();

Segue agora o código da classe DebuggerWriter que nos ajuda nessa tarefa.


using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;

namespace Vandermotten.Diagnostics
{
    /// <summary>
    /// Implements a <see cref="TextWriter"/> for writing information to the debugger log.
    /// </summary>
    /// <seealso cref="Debugger.Log"/>
    public class DebuggerWriter : TextWriter
    {
        private bool isOpen;
        private static UnicodeEncoding encoding;
        private readonly int level;
        private readonly string category;

        /// <summary>
        /// Initializes a new instance of the <see cref="DebuggerWriter"/> class.
        /// </summary>
        public DebuggerWriter()
            : this(0, Debugger.DefaultCategory)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DebuggerWriter"/> class with the specified level and category.
        /// </summary>
        /// <param name="level">A description of the importance of the messages.</param>
        /// <param name="category">The category of the messages.</param>
        public DebuggerWriter(int level, string category)
            : this(level, category, CultureInfo.CurrentCulture)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DebuggerWriter"/> class with the specified level, category and format provider.
        /// </summary>
        /// <param name="level">A description of the importance of the messages.</param>
        /// <param name="category">The category of the messages.</param>
        /// <param name="formatProvider">An <see cref="IFormatProvider"/> object that controls formatting.</param>
        public DebuggerWriter(int level, string category, IFormatProvider formatProvider)
            : base(formatProvider)
        {
            this.level = level;
            this.category = category;
            this.isOpen = true;
        }

        protected override void Dispose(bool disposing)
        {
            isOpen = false;
            base.Dispose(disposing);
        }

        public override void Write(char value)
        {
            if (!isOpen)
            {
                throw new ObjectDisposedException(null);
            }
            Debugger.Log(level, category, value.ToString());
        }

        public override void Write(string value)
        {
            if (!isOpen)
            {
                throw new ObjectDisposedException(null);
            }
            if (value != null)
            {
                Debugger.Log(level, category, value);
            }
        }

        public override void Write(char[] buffer, int index, int count)
        {
            if (!isOpen)
            {
                throw new ObjectDisposedException(null);
            }
            if (buffer == null || index < 0 || count < 0 || buffer.Length - index < count)
            {
                base.Write(buffer, index, count); // delegate throw exception to base class
            }
            Debugger.Log(level, category, new string(buffer, index, count));
        }

        public override Encoding Encoding
        {
            get
            {
                if (encoding == null)
                {
                    encoding = new UnicodeEncoding(false, false);
                }
                return encoding;
            }
        }

        public int Level
        {
            get { return level; }
        }

        public string Category
        {
            get { return category; }
        }
    }
}

Fonte: Sending the LINQ To SQL log to the debugger output window

[]´s

Facilidade em Chaves Primárias - GUID

Por Juliano Oliveira em Setembro 7, 2008

Sempre gosto mais do que é novo e vem para somar. A alguns anos, sempre quando me deparava com modelagem de bancos dava preferência a tipos de dados uniqueidentifier. É uma preferência pessoal, porém, ajuda quando temos que lidar com INSERTS de aplicações offline.

Mas em uma conversa com o Rafael, um amigo de trabalho, começamos a discutir sobre o desempenho e performance se comparado a uma chave primária do tipo int. Com certeza vai ter problema de escabilidade. Comparar uma a performance de indexação de um campo de 4 bytes com um binário de 16 bytes é covardia.

Mas desde a versao 7 do SQL Server, a Microsoft criou uma solução para isso. Antes, os campos uniqueidentifier você atribuia um valor com alguma função System.Guid.NewGuid() ou mesmo interna do SQL Server, NEWID(). Mas isso gera queda de performance e problemas de escabilidade. O banco vai fragmentar. Olha algumas GUID criadas com o .NET Framework.

  • {4558B194-FA8B-435f-9FDF-363EF258447F}
  • {0C93A685-0F67-4e04-A8BA-AB04B460320E}
  • {669D610F-ECED-4fea-8F88-18B63551A9D0}
  • {66EB380A-CD70-4ede-AF99-5B18927524ED}

Indexar uma tabela carregada com chaves primárias nesse formato traria dor de cabeça.

Agora, veja algumas GUID criadas com a função interna NEWSEQUENTIALID() do SQL Server 7.

  • B3BFC6B1-05A2-11D6-9FBA-00C04FF317DF
  • B3BFC6B2-05A2-11D6-9FBA-00C04FF317DF
  • B3BFC6B3-05A2-11D6-9FBA-00C04FF317DF
  • B3BFC6B4-05A2-11D6-9FBA-00C04FF317DF
  • B3BFC6B5-05A2-11D6-9FBA-00C04FF317DF

Dá pra perceber que apenas o oitavo byte é mudado, o restante é constante, isso que ajuda a indexação. No SQL Server 2000 apenas o 13º byte é constate. Olha agora algumas GUID geradas no meu SQL Server 2005 Express.

  • 6dca3a74-097c-dd11-8241-0019d1a5065d
  • 6eca3a74-097c-dd11-8241-0019d1a5065d
  • 351ccf7a-097c-dd11-8241-0019d1a5065d
  • 54703d8b-097c-dd11-8241-0019d1a5065d
  • 55703d8b-097c-dd11-8241-0019d1a5065d

A sequência é gerada nos 8 primeiros bytes, o restante é constante.

A dica é essa, se quiser usar uniqueidentifier como chave primária de suas tabelas, use a função interna NEWSEQUENTIALID() do SQL Server para melhorar a performance e escabilidade das suas aplicações.

Só lembrando, ainda assim chaves primárias do tipo int ainda assim são mais performáticas, porém, seguindo a dica, a queda de performance não será percebida. Lembrando também que esses problemas de performance e escabilidade só são identificados quando sua base possuir muitos registros, lá na casa dos 300 mil, 500 mil, 1 milhão, ou seja, “coisa pra (b)aralho”.

Para aqueles que se perguntarem “se essa GUID não repete” a possibilidade é mínima. Matematicamente falando é mais facil ganhar na Megasena. NEWSEQUENTIALID() usa um algoritimo que para gerar a GUID se utiliza do MAC da placa de rede (que os fabricantes dizem nunca se repetir) e do DateTime da máquina.

Segue também uma leitura que eu recomendo descrevendo em mais detalhes o assunto!

[]´s

OBS:

Ainda não somos independentes mas pelo menos hoje é um ótimo dia para postar a nossa bandeira que é sem dúvida a mais bonita do mundo!

brazil-flag

ASP.NET MVC Preview 5

Por Juliano Oliveira em Agosto 29, 2008

Saiu mais um, pega o instalador aqui!

Na próxima “fornada” o Phill Haacked prometeu o primeiro Beta.

[]´s


Copyright © 2007 Programando em .NET. Existe direitos reservados na Internet?.