logo

Acabei de liberar o servidor do projeto!

http://www.meudindin.com/

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

[]´s

, , ,

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

, , , , ,

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

, , , , , , ,

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

, ,

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

, , , , , ,

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

, , ,

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

, , ,