<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tucaz.blog.now() &#187; Desenvolvimento</title>
	<atom:link href="http://blog.tucaz.net/category/desenvolvimento/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tucaz.net</link>
	<description>Software architecture, agile and all that stuff that you can find everywhere</description>
	<lastBuildDate>Tue, 11 Jan 2011 21:00:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Come&#231;ando a aprender F# com: Ubuntu, Mono e Vim</title>
		<link>http://blog.tucaz.net/2011/01/10/comeando-a-aprender-f-com-ubuntu-mono-e-vim/</link>
		<comments>http://blog.tucaz.net/2011/01/10/comeando-a-aprender-f-com-ubuntu-mono-e-vim/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 00:58:47 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[FSharp]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vi]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=479</guid>
		<description><![CDATA[Já faz algum tempo que estou meio de saco cheio de desenvolvimento comercial tradicional que a maioria de nós, desenvolvedores, está acostumado a fazer. De uma forma ou de outra, exceto em projetos excepcionais tudo é uma variação de CRUD o que é um pé no saco pra quem gosta de código. Chega uma hora [...]]]></description>
			<content:encoded><![CDATA[<p>Já faz algum tempo que estou meio de saco cheio de desenvolvimento comercial tradicional que a maioria de nós, desenvolvedores, está acostumado a fazer. De uma forma ou de outra, exceto em projetos excepcionais tudo é uma variação de CRUD o que é um pé no saco pra quem gosta de código. Chega uma hora que a gente começa a procurar maneiras diferentes (não necessariamente melhores) de fazer a mesma coisa só pra acabar com o tédio. Isso estava me incomodando.</p>
<p>Há alguns meses quando este sentimento veio novamente decidi que iria tentar algo diferente. Foi ai que comecei com o combo título deste post. Uma mudança radical de ares.</p>
<p>Não sou o primeiro e com certeza não serei o último.</p>
<p>Apesar de trabalhar com Windows e depender dele pro meu ganha pão adotei o Ubuntu como sistema operacional padrão deixando o Windows em uma VM <strong>[1]</strong> apenas para trabalho e comecei a estudar F# que é uma linguagem com paradigma funcional que é completamente diferente de C#, Java e parentes próximos. Não bastasse a mudança de sistema operacional e de paradigma decidi também aprender mais a respeito de shell e editores de texto pra me livrar mais ainda dos atalhos que uma IDE como o VS proporcionam e adotei o VIM como editor de texto.</p>
<p>Nest post vou mostrar como montar um ambiente como o meu e os primeiros (primeiros mesmo, nada avançado) passos nessa estrada de aprendizado. Se tudo der certo e eu não desistir transformo numa série pra poder compartilhar meu aprendizado e com a colaboração de vocês aprender mais sobre o assunto.</p>
<p>Tudo que estou fazendo é no Ubuntu 10.10, mas deve funcionar com uma boa parte dos *nix por ai.</p>
<h3>Instalando F# com Mono</h3>
<p>Provavelmente o Linux que você tem instalado já deve ter o mono instalado, portanto não precisamos nos preocupar com esta etapa. De qualquer forma, só pra garantir abra o shell (Terminal) veja se você está realmente como o Mono instalado e qual sua versão:</p>
<pre class="shell" name="code">mono -V</pre>
<p>Se tudo estiver certo teremos algo parecido com isso:</p>
<pre class="bash" name="code">Mono JIT compiler version 2.6.7 (Debian 2.6.7-3ubuntu1)
Copyright (C) 2002-2010 Novell, Inc and Contributors. www.mono-project.com
    TLS:           __thread
    GC:            Included Boehm (with typed GC and Parallel Mark)
    SIGSEGV:       altstack
    Notifications: epoll
    Architecture:  amd64
    Disabled:      none</pre>
<p>Caso ele não esteja instalado basta ir ao Ubuntu Software Center <strong>[2] </strong>para instalá-lo ou <a title="Mono Downloads" href="http://www.go-mono.com/mono-downloads/download.html">baixá-lo no site oficial</a>.</p>
<p>Com Mono instalado corretamente e acessível de qualquer lugar precisamos agora baixar a última versão disponível da biblioteca e compilador FSharp. Temos três opções para a instalação: </p>
<ol>
<li>Efetuar o download do código fonte, compilá-lo e efetuar a instalação </li>
<li>Baixar um <a href="http://fsxplat.codeplex.com/">pacote cross-platform</a> que faz a instalação de tudo </li>
<li>Baixar o pacote oficial compilado, efetuar a instalação e configurar as variáveis de ambiente “manualmente” </li>
</ol>
<p>Vamos com a terceira opção, pra ver onde vai cada coisa e como cada um dos executáveis funciona.</p>
<p>A última versão disponível no momento deste post é a 2.0.0.0 de Novembro de 2010.</p>
<p>Como somos usuários ninjas de Linux vamos efetuar o download via linha de comando com <a href="http://www.gnu.org/software/wget/">wget</a>.</p>
<pre class="bash" name="code">wget http://download.microsoft.com/download/4/5/B/45BD9FBC-22BA-4B45-84B7-17D1AD0122A1/fsharp.zip</pre>
<p>Terminado o download, um pacote zip, extraimos todo o conteúdo pra uma pasta qualquer.</p>
<pre class="bash" name="code">unzip fsharp.zip</pre>
<p>Agora devemos ter todo o conteúdo do zip extraido em uma pasta chamada <em>FSharp-2.0.0.0</em>.</p>
<p>Antes de instalar sugiro mover a pasta com o conteúdo extraido do zip para um local mais apropriado para este tipo de arquivos já que é a partir desta pasta que iremos fazer referência mais pra frente aos executáveis do FSharp. Eu utilizo <em>/usr/lib/ </em><strong>[3]</strong>. Além de mover, vamos renomear a pasta de destino apenas para fsharp a fim de deixar tudo mais simples.</p>
<pre class="bash" name="code">sudo mv FSharp-2.0.0.0/ /usr/lib/fsharp/
cd /usr/lib/fsharp/</pre>
<p>Agora para instalar basta executar:</p>
<pre class="bash" name="code">cd fsharp
sudo sh install-mono.sh</pre>
<p>Este comando provavelmente retornará um erro indicando que a DLL não pôde ser adicionada ao GAC por conta de seu strongname. O que acontece é que a versão compilada que baixamos está com uma assinatura para o .NET Framework do Windows então antes de conseguir instalar o FSharp no Mono devemos baixar um <a title="mono.snk @ GitHub" href="https://github.com/mono/mono/raw/master/mcs/class/mono.snk">arquivo.snk</a> próprio para ele e ai sim executar novamente o setup.</p>
<pre class="bash" name="code">wget -O mono.snk https://github.com/mono/mono/raw/master/mcs/class/mono.snk --no-check-certificate
sudo sh install-mono.sh</pre>
<p>Dando tudo certo, devemos receber uma mensagem de sucesso:</p>
<pre class="bash" name="code">-- Resigning FSharp.Core.dll with mono.snk
Assembly bin/FSharp.Core.dll signed.
-- Installing FSharp DLLS into the GAC
Installed bin/FSharp.Core.dll into the gac (/usr/lib/mono/gac)</pre>
<p>Pra testar se tudo der certo, ainda de dentro do diretório onde instalamos o FSharp, podemos executar:</p>
<pre class="bash" name="code">mono bin\fsi.exe</pre>
<p>Se tudo estiver OK vamos entrar no FSharp Interactive que é uma console <a title="REPL @ Wikipedia" href="http://en.wikipedia.org/wiki/Read-eval-print_loop">REPL</a> pra F# muito legal:</p>
<pre class="bash" name="code">Microsoft (R) F# 2.0 Interactive build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

&gt; </pre>
<p>Podemos também fazer o tradicional “Hello World”:</p>
<pre class="bash" name="code">&gt; printfn &quot;Hello World!&quot;;;
Hello World!
val it : unit = ()</pre>
<p><strong>Pronto! </strong></p>
<p>Tecnicamente temos o FSharp instalado com sucesso e pronto para usar. No entanto, tanto o compilador (fsc.exe) e o REPL (fsi.exe) não fazem parte do PATH configurado em nosso Linux. Desta forma, ele está apenas acessível a partir do diretório onde está localizado.</p>
<p>Pra resolver isso vamos baixar o pacote de ferramentas adicionais para FSharp que irá nos prover algums aliases que permitirão o acesso as ferramentas a partir de qualquer diretório.</p>
<p>Dessa vez, como este pacote está hospedado no Codeplex, temos que efetuar o download do pacote “Additional scripts and tools only (.tgz archive)” manualmente localizado em <a title="http://fsxplat.codeplex.com/releases/view/55463" href="http://fsxplat.codeplex.com/releases/view/55463">http://fsxplat.codeplex.com/releases/view/55463</a>. </p>
<p></p>
<p>Feito o download podemos voltar ao nosso querido shell e instalar o pacote de bonus.</p>
<pre class="bash" name="code">cd ~/Downloads
mkdir fsharp-bonus
tar -xvzf fsharp-bonus.tgz -C fsharp-bonus
cd fsharp-bonus
sudo bash install-bonus.sh</pre>
<p>Este script de instalação espera que as DLLs do FSharp estejam na pasta <em>/usr/lib/fsharp. </em>No entanto, no nosso caso elas se encontram em <em>/usr/lib/fsharp/bin</em>, portanto caso o script solicite esta informação, fica fácil de prover. <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Feito isso é hora de testar e já podemos chamar <em>fsharpi</em> de qualquer lugar no shell:</p>
<pre class="bash" name="code">tucaz@tucaz-nb:~$ fsharpi

Microsoft (R) F# 2.0 Interactive build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

&gt; </pre>
<p>Agora podemos chamar tanto o REPL quanto o compilador a partir de qualquer diretório já que os alias foram devidamente criados e adicionados ao PATH.</p>
<h3>Primeiro Hello World com Vim</h3>
<p>Agora que temos todo o ambiente instalado (o que na minha opinião é um dos primeiros grandes obstáculos no aprendizado de uma nova linguagem) podemos fazer nosso primeiro Hello World e gerar uma DLL .NET com F#!</p>
<p>Primeiro, vamos definir um diretório de trabalho onde vamos colocar todos nossos projetos. Eu costumo usar um diretório chamado <em>Workspace</em> dentro do meu profile:</p>
<pre class="bash" name="code">cd ~
mkdir Workspace
cd Workspace
mkdir HelloWorldFSharp
cd HelloWorldFSharp</pre>
<p>Criado o diretório, criamos também nosso primeiro arquivo com código fonte FSharp utilizando o Vim <strong>[4]</strong>:</p>
<pre class="bash" name="code">vim HelloWorldFSharp.fs</pre>
<p>Isso cria um arquivo chamado HelloWorldFSharp.fs (assumindo que um não exista ou abre para edição caso ele exista) e o abre no nosso editor de texto funcionando dentro de um terminal shell, que pra um usuário Windows (que não tenha usado o Edit do DOS) é algo geralmente desconhecido.</p>
<p>O Vim (como o Vi) oferece basicamente dois modos de trabalho: modo de comando e edição/inserção de texto. Quando abrimos um arquivo, por padrão temos o modo de comando onde o texto digitado não é o que vai para o arquivo, mas sim interpretado como um comando (a seguir).</p>
<p>Para entrar no modo de edição de texto digitamos <em>i</em> ou apertamos a tecla <em>insert</em> do teclado. Note que o texto &#8211;INSERT&#8211; irá aparecer no canto esquerdo inferior da tela indicando que agora estamos no modo de inserção de texto. Esta área é destinada aos comandos e mensagens do editor.</p>
<p>Estando no modo de edição vamos escrever nosso Hello World!</p>
<pre class="fsharp" name="code">#light 

printfn &quot;Hello World!&quot;</pre>
<p>Com “todo” nosso código completo vamos sair do modo de edição (e voltar ao modo comando) apertando <em>ESC. </em>Para salvar e sair digitamos o comando :wq (write and quit) e enter retornando ao terminal.</p>
<p>Pra compilar nosso código fonte e gerar o primeiro .exe no Linux:</p>
<pre class="bash" name="code">fsharpc HelloWorldFSharp.fs</pre>
<p>Obtendo a resposta:</p>
<pre class="bash" name="code">Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
tucaz@tucaz-nb:~/Workspace/HelloWorldFSharp$ ls
HelloWorldFSharp.exe  HelloWorldFSharp.fs
tucaz@tucaz-nb:~/Workspace/HelloWorldFSharp$ </pre>
<p>E por último, vamos executar nosso primeiro programa .NET em Linux:</p>
<pre class="bash" name="code">mono HelloWorldFSharp.exe
Hello World!</pre>
<p><strong>Fim!</strong></p>
<p>Neste post vimos como instalar Mono/F# no Linux e como criar nosso primeiro programa Hello World em F# utilizando o Vim. No próximo, quero começar a falar mais a respeito de F# e Vim e deixar para trás<strong>&#160;</strong>questões de ambiente.</p>
<p>Até lá!</p>
<p><strong>[1] – </strong>Estou utilizando Ubuntu 10.10 AMD64 rodando em um notebook Core i7 (2.66ghz) com 6gb de memória RAM sendo que 2gb ficam exclusivos para VM rodando no Virtual Box. A performance é ótima!</p>
<p><strong>[2] – </strong>Menu Principal –&gt; Applications –&gt; Ubuntu Software Center</p>
<p><strong>[3] –</strong> Alguma outra sugestão?</p>
<p><strong>[4]</strong> – Se o Vim não estiver instalado, basta executar “sudo apt-get install vim” para instalá-lo</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2011/01/10/comeando-a-aprender-f-com-ubuntu-mono-e-vim/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Lendo e consumindo XML com dynamic em C# 4</title>
		<link>http://blog.tucaz.net/2010/11/18/lendo-e-consumindo-xml-com-dynamic-em-c-4/</link>
		<comments>http://blog.tucaz.net/2010/11/18/lendo-e-consumindo-xml-com-dynamic-em-c-4/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 23:57:30 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=474</guid>
		<description><![CDATA[Sei que faz tempo que não posto então aqui vai um post rápido, mas com conteúdo (espero que vocês vejam dessa forma também). Finalmente comecei a trabalhar efetivamente com C# 4 e por coincidência (ou não) já precisei de dynamic objects pra resolver um problema.
Meu sistema recebe como entrada alguns arquivos XML para serem processados [...]]]></description>
			<content:encoded><![CDATA[<p>Sei que faz tempo que não posto então aqui vai um post rápido, mas com conteúdo (espero que vocês vejam dessa forma também). Finalmente comecei a trabalhar efetivamente com C# 4 e por coincidência (ou não) já precisei de dynamic objects pra resolver um problema.</p>
<p>Meu sistema recebe como entrada alguns arquivos XML para serem processados e transformados em outros objetos posteriormente. XML é um saco e é definitivamente uma das coisas que eu mais odeio em desenvolvimento de software. Tudo com XML é trabalhoso. Sendo assim criei uma pequena Lib que transforma XML em objetos dinamicos pra eliminar a necessidade de lidar com nós e atributos diretamentes e também permitir futuras implementacões.</p>
<p>Com XmlToObjectParser é possível:</p>
<pre class="xml" name="code">
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;catalog&gt;
  &lt;cd country="USA"&gt;
    &lt;title&gt;Empire Burlesque&lt;/title&gt;
    &lt;artist&gt;Bob Dylan&lt;/artist&gt;
    &lt;price&gt;10.90&lt;/price&gt;
  &lt;/cd&gt;
  &lt;cd country="UK"&gt;
    &lt;title&gt;Hide your heart&lt;/title&gt;
    &lt;artist&gt;Bonnie Tyler&lt;/artist&gt;
    &lt;price&gt;10.0&lt;/price&gt;
  &lt;/cd&gt;
  &lt;cd country="USA"&gt;
    &lt;title&gt;Greatest Hits&lt;/title&gt;
    &lt;artist&gt;Dolly Parton&lt;/artist&gt;
    &lt;price&gt;9.90&lt;/price&gt;
  &lt;/cd&gt;
&lt;/catalog&gt;
</pre>
<pre class="csharp" name="code">
var numberOfCDsinCatalog = catalog.catalog.cd.Count; //Retorna 3
var titleFromUKCD = catalog.catalog.cd[1].title; // Retorna "Hide your heart"
</pre>
<p>Bem mais legível e prático de usar, na minha opinião.</p>
<p>O <a href="https://github.com/tucaz/XmlToObjectParser">projeto</a> e a <a href="https://github.com/downloads/tucaz/XmlToObjectParser/XmlToObjectParser-1.0.zip">DLL compilada</a> estão no GitHub assim como a <a href="https://github.com/tucaz/XmlToObjectParser/wiki/Getting-Started">documentacão e informacões adicionais</a>.</p>
<p>Enjoy! <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2010/11/18/lendo-e-consumindo-xml-com-dynamic-em-c-4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Performance: NHibernate versus ADO.NET</title>
		<link>http://blog.tucaz.net/2010/08/31/performance-nhibernate-versus-ado-net/</link>
		<comments>http://blog.tucaz.net/2010/08/31/performance-nhibernate-versus-ado-net/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 01:18:21 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[Banco de Dados]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[adhoc]]></category>
		<category><![CDATA[ADO.NET]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[stored procedures]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=466</guid>
		<description><![CDATA[Disclaimer
Os testes neste post apresentados não representam uma amostra exata ou fidedigna que represente uma condição real de acesso a dados de uma aplicação a fim de comparar a performance das duas tecnologias. A idéia é apenas mostrar alguns dados e exemplos com o objetivo de dismistificar a idéia de que ORM é uma ferramenta [...]]]></description>
			<content:encoded><![CDATA[<h1><em><span style="color: #ff0000">Disclaimer</span></em></h1>
<p><em><span style="color: #ff0000">Os testes neste post apresentados não representam uma amostra exata ou fidedigna que represente uma condição real de acesso a dados de uma aplicação a fim de comparar a performance das duas tecnologias. A idéia é apenas mostrar alguns dados e exemplos com o objetivo de dismistificar a idéia de que ORM é uma ferramenta lenta e estes testes são apenas um exercício.</span></em></p>
<p><em><span style="color: #ff0000">Sou usuário de NHibernate e defendo o uso de ORM’s portanto as conclusões apresentadas com certeza não são as mais imparciais possíveis.</span></em></p>
<p>Motivado <a title="DDD - Objetos de consulta usando ORM - o que vcs acham? @ DotNetArchitects" href="http://groups.google.com/group/dotnetarchitects/browse_thread/thread/dc01630511ec34ec">por esta thread no DNA hoje</a> decidi fazer alguns testes de perfomance pra comparar acesso a dados utilizando ADO.NET nativo (queries AdHoc e Stored Procedures) versus NHibernate.</p>
<p>Sempre rolam diversas discussões a respeito do assunto e a conclusão que geralmente se chega é de que qualquer ORM vai ser mais lento do que uma chamada nativa. É uma conclusão óbvia já que utilizar um ORM é adicionar uma camada de abstração a mais dentro da nossa aplicação. No entanto, até então eu nunca havia efetuado nenhuma medição pra ver qual a diferença de performance.</p>
<p>Todos os testes foram executados na minha máquina com código compilado em modo Release com banco de dados Sql Server 2008 também local.</p>
<p>Vamos aos testes.</p>
<h1>Cenário de testes</h1>
<p>Criei uma tabela (Product) e populei com cerca de 500 registros vindos do AdventureWorks (banco de dados exemplo do SqlServer).</p>
<p><a href="http://blog.tucaz.net/wp-content/uploads/2010/08/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Modelo de Dados" border="0" alt="Modelo de Dados" src="http://blog.tucaz.net/wp-content/uploads/2010/08/image_thumb.png" width="237" height="175" /></a></p>
<p>Contra essa tabela executei duas categorias de testes:</p>
<ol>
<li>Carregar todos os registros da tabela em um List&lt;&gt; </li>
<li>Carregar apenas um registro </li>
</ol>
<p>Pra ficar mais interessante fiz algumas variações dos testes:</p>
<ul>
<li>Query AdHoc/Inline </li>
<li>Query AdHoc/Inline com hidratação<strong>[1]</strong> via reflection </li>
<li>Query utilizando uma procedure </li>
<li>NHibernate com LINQ </li>
<li>NHibernate com HQL </li>
<li>NHibernate com Criteria </li>
<li>Nhibernate com Projections </li>
</ul>
<p>Como rodando uma única vez não foi possível obter dados suficientes, executei cada teste dentro de um loop com 1000 (numberOfIterations = 1000) iterações que resultou no código abaixo:</p>
<p>Método principal:</p>
<pre class="csharp" name="code">static void Main(string[] args)
{
    for (int i = 1; i &lt;= 3; i++)
    {
        Console.WriteLine(&quot;Test &quot; + i.ToString());
        Console.WriteLine(&quot;======================&quot;);

        SqlAdHocAllProducts();
        SqlAdHocAllProductsWithReflection();
        SProcAllProducts();
        NHibernateAllProductsWithLinq();
        NHibernateAllProductsWithHql();
        NHibernateAllProductsWithCriteria();
        NHibernateAllProductsWithProjections();

        SqlAdHocOneProduct();
        SqlAdHocOneProductWithReflection();
        SProcOneProduct();
        NHibernateOneProduct();

        Console.WriteLine();
    }

    Console.ReadLine();
}</pre>
<p>
  <br />Um dos métodos usando Sql AdHoc e outro usando NHibernate:</p>
<p></p>
<pre class="csharp" name="code">private static void SqlAdHocAllProducts()
{
    List&lt;Product&gt; allProducts = null;

    var connectionString = &quot;Data Source=(local);Integrated Security=SSPI;Database=TDC2010;&quot;;
    var select = @&quot;SELECT P.Id, P.Description, P.Name, P.Price FROM dbo.Product P&quot;;

    var connection = new SqlConnection(connectionString);
    connection.Open();

    Stopwatch watch = new Stopwatch();
    watch.Start();

    for (int i = 0; i &lt; numberOfIterations; i++)
    {
        allProducts = new List&lt;Product&gt;();
        var command = new SqlCommand(select, connection);
        var reader = command.ExecuteReader();

        while (reader.Read())
        {
            allProducts.Add(new Product()
                {

                    Id = Convert.ToInt32(reader[&quot;Id&quot;]),
                    Name = Convert.ToString(reader[&quot;Name&quot;]),
                    Description = Convert.ToString(reader[&quot;Description&quot;]),
                    Price = Convert.ToDecimal(reader[&quot;price&quot;])
                });
        }

        reader.Close();
    }

    watch.Stop();

    connection.Close();
    connection.Dispose();

    Console.WriteLine(
        &quot;Loading &quot; + allProducts.Count + &quot; Products with Sql AdHoc took &quot; + watch.ElapsedMilliseconds + &quot; ms&quot;);
}</pre>
<p>
  </p>
<pre class="csharp" name="code">private static void NHibernateAllProductsWithLinq()
{
    List&lt;Product&gt; allProducts = null;

    var session = CreateForSqlServer().OpenSession();

    Stopwatch watch = new Stopwatch();
    watch.Start();

    for (int i = 0; i &lt; numberOfIterations; i++)
    {
        allProducts = session.Linq&lt;Product&gt;().ToList();
    }

    watch.Stop();

    session.Close();

    Console.WriteLine(
        &quot;Loading &quot; + allProducts.Count + &quot; Products with NHibernate took &quot; + watch.ElapsedMilliseconds + &quot; ms&quot;);
}</pre>
<p><strong>Vou omitir o restante dos métodos para evitar duplicações já que eles são apenas variações dos dois exemplos acima.</strong></p>
<h1>Resultado Geral</h1>
<p><a href="http://blog.tucaz.net/wp-content/uploads/2010/08/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Resultados dos Testes" border="0" alt="Resultados dos Testes" src="http://blog.tucaz.net/wp-content/uploads/2010/08/image_thumb1.png" width="681" height="648" /></a></p>
<h1>Análise dos Resultados</h1>
<h3>Stored Procedures versus Queries AdHoc/Inline [500 registros]</h3>
<p>A diferença entre o uso de stored procedures e queries AdHoc é praticamente inexistente. A diferença média medida foi de <strong>menos de 1%</strong>.</p>
<p>Isso acontece, pois não existe complexidade suficiente neste tipo de query para que a armazenagem do plano de execução no banco de dados faça diferença.</p>
<p>Portanto, na grande maioria dos cenários Stored Procedures não são necessárias.</p>
<h3>NHibernate versus NHibernate [500 registros]</h3>
<p>Na média, todas as variações de consulta utilizando NHibernate também tiveram <strong>mais ou menos o mesmo resultado (~1500ms)</strong> com exceção do uso de <strong>Projections</strong>, que levou o dobro<strong> (~3000ms)</strong> do tempo.</p>
<p>Não conheço o NHibernate suficiente pra afirmar com 100% de certeza o motivo, mas acredito que seja pelo fato de esse tipo de query retornar Arrays bidimensionais que são criados e redimensionados em runtime até que todos os itens possam ser acomodados.</p>
<h3>NHibernate versus ADO.NET [500 registros]</h3>
<p>Este e o comparativo mais importante. Carregando (e hidratando) 500 registros o ADO.NET é cerca de <strong>30% mais</strong> rapido do que o NHibernate. A causa dessa discrepância é uma só e se chama reflection.</p>
<p>Apesar de todas as otimizações o NHibernate utiliza-se de reflection para efetuar a hidratação<strong>[1] </strong>de todos os objetos e é dai que vem a queda de performance que fica clara quando executamos queries AdHoc usando hidratação via reflection conforme o código abaixo.</p>
<pre class="csharp" name="code">private static void SqlAdHocAllProductsWithReflection()
{
    List&lt;Product&gt; allProducts = null;

    var connectionString = &quot;Data Source=(local);Integrated Security=SSPI;Database=TDC2010;&quot;;
    var select = @&quot;SELECT P.Id, P.Description, P.Name, P.Price FROM dbo.Product P&quot;;

    var connection = new SqlConnection(connectionString);
    connection.Open();

    Stopwatch watch = new Stopwatch();
    watch.Start();

    for (int i = 0; i &lt; numberOfIterations; i++)
    {
        allProducts = new List&lt;Product&gt;();
        var command = new SqlCommand(select, connection);
        var reader = command.ExecuteReader();

        while (reader.Read())
        {
            var newProduct = Activator.CreateInstance&lt;Product&gt;();
            SetProperty(newProduct, &quot;Id&quot;, Convert.ToInt32(reader[&quot;Id&quot;]));
            SetProperty(newProduct, &quot;Description&quot;, Convert.ToString(reader[&quot;Description&quot;]));
            SetProperty(newProduct, &quot;Name&quot;, Convert.ToString(reader[&quot;Name&quot;]));
            SetProperty(newProduct, &quot;Price&quot;, Convert.ToDecimal(reader[&quot;Price&quot;]));
            allProducts.Add(newProduct);
        }

        reader.Close();
    }

    watch.Stop();

    connection.Close();
    connection.Dispose();

    Console.WriteLine(
&quot;Loading &quot; + allProducts.Count + &quot; Products with Sql AdHoc and Reflection took &quot; + watch.ElapsedMilliseconds + &quot; ms&quot;);
}

private static void SetProperty(object instance, string property, object val)
{
    Type t = instance.GetType();
    var prop = t.GetProperty(property, BindingFlags.Instance | BindingFlags.Public);
    prop.SetValue(instance, val, null);
}</pre>
<p>Este código quando executado demora cerca de <strong>6000ms, ou 4 vezes mais</strong>, do que o código executado pelo NHibernate.</p>
<p>Mas por que a diferença não é de 30%? Porque o NHibernate possui otimizações quanto ao modo de hidratar um objeto via reflection. No meu código acima podemos ver, por exemplo, que toda vez que chamo o método SetProperty o Type da propriedade a ser refletida ainda não está criado. Provavelmente o NHibernate deve manter cache deste tipo de informação (e de outras) a fim de otimizar o processo de hidratação das entidades.</p>
<h3>Stored Procedures versus Queries AdHoc/Inline [1 registro]</h3>
<p>Mesmo resultado do cenário onde 500 registros são carregados. Não há diferença.</p>
<h3>NHibernate versus ADO.NET [1 registro]</h3>
<p>Aqui a diferença é gigantesca sendo de <strong>quase 4000% a favor do NHibernate. </strong>Isso acontece, pois o NHibernate implementa cache nível 1 nativamente então dentro de uma mesma ISession o objeto é carregado apenas uma vez enquanto com ADO.NET é necessário ir ao banco e carregar o objeto diversas vezes.</p>
<h1>Conclusões</h1>
<p>Olhando para os números apenas, em casos onde diversos registros precisam ser carregados, ADO.NET nativo oferece uma performance superior e parece ser a escolha óbvia. No entanto:</p>
<ul>
<li>Os testes com NHibernate foram executados utilizandos exemplos simples e sem qualquer tipo de otimização. </li>
<li>NHibernate oferece nativamente cache de resultados de queries e cache nível 2 que se utilizados iriam exibir um resultado bem próximo ao cenário “<em>NHibernate versus ADO.NET [1 registro]” </em>onde o NHibernate é 4 vezes mais rápido. </li>
<li>ADO.NET oferece um custo de desenvolvimento e manutenção altissimo e este custo torna-se ainda maior se utilizado com Stored Procedures que transformam o cenário em algo totalmente caótico de gerenciar devido a dificuldade de manter a rastreabilidade desses diabinhos malignos. </li>
</ul>
<p>No caso de sistemas <a title="OLTP @ Wikipedia" href="http://pt.wikipedia.org/wiki/OLTP">OLTP</a> onde as transações carregam unidades individuais e/ou pequenas coleções de entidades por sessão, NHibernate não só é mais rápido como também oferece muito mais flexibilidade pra lidar com praticamente todos os cenários existentes. <a title="25 reasons not to write your own ORM @ Ayende&#39;s Blog" href="http://ayende.com/Blog/archive/2006/05/12/25ReasonsNotToWriteYourOwnObjectRelationalMapper.aspx">Este post do Ayende</a> mostra 25 funcionalidades importantes (cache, gerenciamento de concorrência, etc) que você vai precisar quando estiver lidando com dados e que custariam muito caro (tempo e complexidade) caso você queira escreve-las “na mão”.</p>
<p>Em cenários de aplicações de internet onde o número de leituras é infinitamente superior ao número de escritas no banco de dados deve se utilizar cache no front end (IIS), portanto o tempo que se leva pra montar uma página é irrelevante. Mesmo que você carregasse os dados de um servidor remoto via conexão discada não faria diferença uma vez que os dados estivessem em cache.</p>
<p>Por último, se você se encontrar em uma situação utilizando NHibernate onde o acesso a dados é o gargalo da sua aplicação seu problema não é o NHibernate (a não ser que você tenha usado-o de maneira totalmente absurda, mas a probabilidade de você fazer o mesmo com ADO.NET é grande também). Nestes cenários o problema não é o acesso a dados em si, mas o resto da arquitetura que não escala de maneira adequada seja por meio de cache, processamento assincrono, filas, etc.</p>
<p>Sendo assim, acredito que podemos concluir que não faz sentido algum no meio do ano de 2010 utilizar queries AdHoc ou Stored Procedures em aplicações <a title="Line of Business @ Wikipedia" href="http://en.wikipedia.org/wiki/Line_of_business">LoB</a>. <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>O código completo utilizado está no GitHub e pode ser <a title="NHPerf Source Code @ GitHub" href="http://github.com/tucaz/Samples/tree/master/NHPerf/">acessado online</a> ou baixado em <a title="Download of NHPerf Source Code @ GitHub" href="http://github.com/downloads/tucaz/Samples/NHPerf.zip">formato zip</a>.</p>
<p><strong>[1] – Hidratação é o processo de preenchimento (filling) das propriedades de uma entidade</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2010/08/31/performance-nhibernate-versus-ado-net/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Material da palestra no TDC2010 &#8211; ORM: Por que isso te interessa?</title>
		<link>http://blog.tucaz.net/2010/08/26/material-da-palestra-no-tdc2010-orm-por-que-isso-te-interessa/</link>
		<comments>http://blog.tucaz.net/2010/08/26/material-da-palestra-no-tdc2010-orm-por-que-isso-te-interessa/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 22:09:38 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Apresentações]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[dao]]></category>
		<category><![CDATA[data access]]></category>
		<category><![CDATA[Evento]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[Palestras]]></category>
		<category><![CDATA[slides]]></category>
		<category><![CDATA[tdc2010]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=459</guid>
		<description><![CDATA[
No último fim de semana rolou em São Paulo o TDC2010 organizado pela Globalcode. Fui convidado a palestrar na trilha de .NET pelo @giovannibassi pra falar um pouquinho sobre ORM e porque é uma boa idéia usá-lo.
Abaixo estão os slides da minha palestra, que não fazem muito sentido por si só, mas que tem umas [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.tucaz.net/wp-content/uploads/2010/08/barratopbasic.jpg"><img style="display: inline; border-width: 0px;" title="barra-top-basic" src="http://blog.tucaz.net/wp-content/uploads/2010/08/barratopbasic_thumb.jpg" border="0" alt="barra-top-basic" width="390" height="68" /></a></p>
<p>No último fim de semana rolou em São Paulo o <a href="http://www.thedevelopersconference.com.br/">TDC2010</a> organizado pela <a href="http://www.globalcode.com.br">Globalcode</a>. Fui convidado a palestrar na <a href="http://www.thedevelopersconference.com.br/tdc/2010/sp/trilha-dot-net">trilha de .NET</a> pelo <a href="http://www.twitter.com/giovannibassi">@giovannibassi</a> pra falar um pouquinho sobre ORM e porque é uma boa idéia usá-lo.</p>
<p>Abaixo estão os <a href="http://www.slideshare.net/tucaz/orm-por-que-isso-te-interessa-tdc2010/">slides da minha palestra</a>, que não fazem muito sentido por si só, mas que tem umas imagens divertidas!</p>
<div id="__ss_5047644" style="width: 425px;"><strong><a title="ORM: Por que isso te interessa? (TDC2010)" href="http://www.slideshare.net/tucaz/orm-por-que-isso-te-interessa-tdc2010">ORM: Por que isso te interessa? (TDC2010)</a></strong><object id="__sse5047644" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=orm-100824141739-phpapp01&amp;stripped_title=orm-por-que-isso-te-interessa-tdc2010" /><param name="name" value="__sse5047644" /><param name="allowfullscreen" value="true" /><embed id="__sse5047644" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=orm-100824141739-phpapp01&amp;stripped_title=orm-por-que-isso-te-interessa-tdc2010" name="__sse5047644" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/tucaz">tucaz</a>.</div>
</div>
<p>Em um dos últimos slides tem uma porção de links muito legais sobre NHibernate então pra quem não quiser ter o trabalho de ver os slides ai vai:</p>
<p><span style="text-decoration: underline;"><a href="http://nhforge.org/">http://nhforge.org/</a></span> -&gt; NHibernate official website<br />
<span style="text-decoration: underline;"><a href="http://fluentnhibernate.org/">http://fluentnhibernate.org/</a></span> -&gt; Fluent Mappings for Nhibernate<br />
<span style="text-decoration: underline;"><a href="http://nhprof.com/">http://nhprof.com/</a></span> -&gt; NHibernate Profiler with 30 day trial<br />
<span style="text-decoration: underline;"><a href="http://www.summerofnhibernate.com/">http://www.summerofnhibernate.com/</a></span> -&gt; More than 14 hours of free videos<br />
<span style="text-decoration: underline;"><a href="http://www.manning.com/kuate/">http://www.manning.com/kuate/</a> </span>-&gt; “NHibernate In Action” Book by Manning<br />
<span style="text-decoration: underline;"><a href="http://ayende.com/Blog/category/510.aspx">http://ayende.com/Blog/category/510.aspx</a></span><span style="text-decoration: underline;"> </span>-&gt; NHibernate @ Ayende’s<br />
<span style="text-decoration: underline;"><a href="http://tinyurl.com/25reasons">http://tinyurl.com/25reasons</a></span> -&gt; 25 reasons NOT to write yout own ORM @ Ayende’s<br />
<a href="http://fabiomaulo.blogspot.com/search/label/NHibernate">http://fabiomaulo.blogspot.com/search/label/NHibernate</a> -&gt; NHibernate @ Fabio Maulo’s<br />
<a href="http://blogs.hibernatingrhinos.com/nhibernate/">http://blogs.hibernatingrhinos.com/nhibernate/</a> -&gt; NHibernate Blog<br />
<span style="text-decoration: underline;"><a href="http://code.google.com/p/unhaddins/">http://code.google.com/p/unhaddins/</a></span> -&gt; unhaddins, Unofficial addins for Nhibernate</p>
<p>Além dos slides, <a href="http://github.com/tucaz/Samples">coloquei no GitHub também o código fonte do projetinho que usei na demo que fiz</a>. Apesar de ser uma demo, o código serve como referência pra começar a utilizar o NHibernate e FluentMapping e ter uma idéia de algumas features bem legais que ele oferece.</p>
<p><a href="http://github.com/downloads/tucaz/Samples/TDC2010.zip">Download do zip com o código.</a></p>
<p>Palestraram também, da Stefanini, <a href="http://www.twitter.com/vquaiato">@vquaiato</a> na trilha de Ruby e .NET, <a href="http://www.twitter.com/alnascimento">@alnascimento</a> e <a href="http://www.twitter.com/manoelp">@manoelp</a> em Agile, <a href="http://www.twitter.com/vcavalcante">@vcavalcante</a> em .NET e <a href="http://www.twitter.com/jorgediz">@jorgediz</a> em Testes.</p>
<p>Por último, mas não menos importante eu queria deixar registrado meu agradecimento ao <a href="http://ayende.com/">Oren Eini (a.k.a. Ayende Rahien</a>) pelos cupons de desconto e licensa do <a href="http://nhprof.com/">NHProf</a> que distribui ao final da palestra e também a Candace da <a href="http://www.manning.com/">Manning Publications</a> pelas cópias dos eBooks “<a href="http://www.manning.com/kuate/">NHibernate In Action</a>” que também dei de brinde. Muito obrigado pelas contribuições a comunidade! <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Now in English so I can make this public to English speakers too. Thanks to <a href="http://ayende.com/">Oren Eini (a.k.a Ayende Rahien</a>) for the discount coupons and <a href="http://nhprof.com/">NHProf</a> license that I gave out and to Candace from <a href="http://www.manning.com/">Manning Publications</a> for the copies of “<a href="http://www.manning.com/kuate/">NHibernate In Action</a>” that were also given at the event. You guys are amazing. Thanks a lot for contributing with this growing community! <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2010/08/26/material-da-palestra-no-tdc2010-orm-por-que-isso-te-interessa/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lidando melhor com WCF &#8211; Ciclo de vida no cliente</title>
		<link>http://blog.tucaz.net/2010/02/23/lidando-com-wcf-ciclo-de-vida-no-cliente/</link>
		<comments>http://blog.tucaz.net/2010/02/23/lidando-com-wcf-ciclo-de-vida-no-cliente/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 17:02:31 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[channelfactory]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=415</guid>
		<description><![CDATA[Início de uma pequena série a respeito de melhores práticas no uso do WCF em .NET. Neste primeiro post falo a respeito do ChannelFactory<t> e como seu ciclo de vida deve ser gerenciado. </t>]]></description>
			<content:encoded><![CDATA[<p><strong><em>&lt;Importante&gt;</em></strong></p>
<p>Todos sabem que WCF é uma plataforma poderosa e extensível. O que muita gente não sabe é que WCF é para poucos.</p>
<p>WCF é uma plataforma que permite a construção de sistemas distribuidos e sistemas distribuidos raramente são necessários. De maneira simplificada, podemos dizer que um sistema é distribuido quando tem seus componentes instalados em mais de um computador.</p>
<p>O problema da construção de sistemas distribuídos é que devido a não centralização de seus compnentes existe um overhead de comunicação entre os computadores e serialização/deserialização de objetos e isso consome muita memória e banda de rede.</p>
<p>Como gastamos mais recursos do que necessário temos como resultado final um aumento no tempo de resposta e gasto extra de hardware que, as vezes pode ser um problema grave além é claro do aumento da complexidade técnica.</p>
<p>No entanto, não sei por qual motivo, no momento em que lançou o produto, a Microsoft esqueceu de avisar seus &#8220;consumidores&#8221; a respeito destes pequenos detalhes. Talvez porque queria promover o produto?</p>
<p><strong>&lt;/Importante&gt;</strong></p>
<p><strong>&lt;Importante 2&gt;</strong></p>
<p>WCF é uma tecnologia relativamente simples, mas apenas depois que você entende o BeABá da coisa (ou ABC<strong>[1]</strong> no caso do WCF). Até lá, qualquer coisa que fuja do point&amp;click que o Visual Studio nos oferece é relativamente complexo.</p>
<p>Portanto, sugiro que antes de aplicar WCF você procure entender um pouco mais dos fundamentos e do papel de cada objeto que ele utiliza.<strong> </strong><strong> </strong></p>
<p><strong><em>&lt;/Importante 2&gt;</em><br />
</strong></p>
<p>Agora que entendemos que não devemos usar WCF em toda aplicação que construimos (talvez isso seja tópico pra outro post?) vou falar um pouco da experiência que estou tendo com esta tecnologia e das boas práticas e atalhos que conheci.</p>
<p>Pretendo fazer uma pequena série e pra começar vou abordar boas práticas de consumo de serviços WCF, ou em outras palavras, como acessar um serviço WCF a partir de um cliente da maneira mais eficiente possível.</p>
<p>Para que seja possível consumir um serviço WCF é necessário que alguém o tenha publicado e também que tenha disponibilizado o WSDL<strong>[2]</strong> do serviço.</p>
<p>O WSDL nada mais é do que um arquivo XML que descreve quais são os tipos de dados que o serviço irá trafegar e quais operações ele oferece.</p>
<p>Geralmente, assim que temos um WSDL para consumir vamos ao Visual Studio e utilizamos a funcionalidade de <em>Add Service Reference</em> que ele nos oferece para gerar o objeto proxy que irá cuidar pra nós da comunicação com WCF. A partir dai utilizamos este objeto em toda nossa aplicação<em></em>. E este é o nosso maior erro.</p>
<p>Este proxy, gerado pelo Wizard, encapsula todas as classes necessárias para ler o WSDL, criar os tipos necessários e lidar com os canais de comunicação em cada operação que executamos. No entanto, ele o faz da <strong>pior</strong> maneira possível.</p>
<p>Cada vez que invocamos uma operação através deste proxy, ele cria uma instância da classe <a title="ChannelFactory&lt;T&gt; @ Msdn.com" href="http://msdn.microsoft.com/en-us/library/ms576132.aspx" target="_self">ChannelFactory&lt;T&gt;</a>. Esta classe é responsável por ler as configurações definidas em nosso app.config e baseado nestas configurações abrir os canais de comunicação com o serviço que iremos consumir. Este processo é <strong>muito lento</strong>, pois todos os sockets, listeners e objetos necessários da própria infra estrutura do WCF são criados e configurados neste momento.</p>
<p>No entanto, este processo não precisa ser feito a cada chamada para o serviço WCF uma vez que estas informações não mudarão enquanto a aplicação estiver rodando. Então, para otimizar bastante o consumo de serviços devemos ignorar o proxy gerado pelo Wizard e cuidar da criação e destruição de canais nós mesmos mantendo este objeto (ChannelFactory&lt;T&gt;) como <a title="Singleton @ Wikipedia.org" href="http://pt.wikipedia.org/wiki/Singleton" target="_self">Singleton</a> que irá durar pelo tempo de vida da aplicação. Dessa forma toda vez que chamamos uma operação remota não existe a necessidade de executar o setup e tear down desse objeto.</p>
<p>Para facilitar a gerência desses objetos construi uma pequena DLL que é composta apenas de uma classe. O código está disponível no <a title="Communications Manager @ GitHub" href="http://github.com/tucaz/CommunicationsManager" target="_self">github</a> e a <a title="Communications Manager @ GitHub" href="http://github.com/tucaz/CommunicationsManager/downloads" target="_self">DLL compilada está aqui</a>. A <a title="Communications Manager Docs @ GitHub" href="http://wiki.github.com/tucaz/CommunicationsManager/">documentação inicial também está lá</a>. Tudo pronto para ser usado.</p>
<p><strong>Referências adicionais (e importantes)</strong></p>
<ul>
<li><a title="Performance Improvement for WCF Client Proxy Creation in .NET 3.5 and Best Practices @ Wenlong Dong's Blog" href="http://blogs.msdn.com/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx" target="_self">Performance improvement for WCF client proxy creation in .NET 3.5 and best practices @ Wenlong Dong&#8217;s Blog</a></li>
<li><a title="Internals - Proxy de Serviço WCF @ Israel Aece" href="http://www.israelaece.com/post/Internals-Proxy-de-servicos-WCF.aspx" target="_self">Internals &#8211; Proxy de Serviços WCF @ Israel Aece</a></li>
<li><a title="WCF Client Channel Pool - Improved Client Performance @ Glavs Blog" href="http://weblogs.asp.net/pglavich/archive/2007/05/07/wcf-client-channel-pool-improved-client-performance.aspx">WCF Client Channel Pool &#8211; Improved Client Performance @ Glavs Blog</a></li>
<li><a href="http://stackoverflow.com/questions/1825990/wcf-channelfactory-and-channel-caching-in-asp-net-client-application" target="_self">Bate papo que me levou a este componente @ StackOverflow</a></li>
</ul>
<p><strong>[1]</strong> ABC = Address, Bindings e Contracts<br />
<strong>[2]</strong> É possível consumir um serviço WCF sem acesso ao WSDL, mas este é um cenário pouco comum</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2010/02/23/lidando-com-wcf-ciclo-de-vida-no-cliente/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Eu não uso Scrum porque Scrum não funciona!</title>
		<link>http://blog.tucaz.net/2010/01/14/eu-nao-uso-scrum-porque-scrum-nao-funciona/</link>
		<comments>http://blog.tucaz.net/2010/01/14/eu-nao-uso-scrum-porque-scrum-nao-funciona/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 22:28:15 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Metodologias]]></category>
		<category><![CDATA[Scrum]]></category>
		<category><![CDATA[Agilidade]]></category>
		<category><![CDATA[XP]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=393</guid>
		<description><![CDATA[Scrum não funciona. Os rótulos e o mau uso mataram Scrum. Você vai falhar antes mesmo de tentar. ]]></description>
			<content:encoded><![CDATA[<p>É Isso ai! Scrum não funciona!</p>
<p>Sabe porque Scrum não funciona? Porque se chama Scrum. Esse hoje é o maior problema do Scrum. Há dois anos atrás pouquíssimo se falava nisto que hoje virou hype. Nessa época as pessoas só falavam que usam Scrum depois de estudar bastante, trocar experiências e exercitar bastante. Ai sim alguém tinha coragem de dizer &#8220;Eu uso Scrum&#8221; e ainda assim com um pouco de receio, pois sabiam que tinha mais coisas além de apagar toda documentação do projeto e e quebrar as cadeiras pra fazer as reuniões em pé. As pessoas (a maioria) que diziam isso sabiam o que estavam dizendo. Scrum tinha credibilidade.</p>
<p>Nessa época, essas pessoas que conheciam agiram como evangelizadores do Scrum e finalmente ele atingiu as massas. No entanto, hoje o que mais se ouve são times/pessoas que não tem a menor idéia das noções e fundamentos por trás do Scrum ou qualquer outro processo/metodologia/framework ágil dizendo que são praticantes de Scrum. Até gente que nunca participou de um projeto usando Scrum hoje vende Scrum.</p>
<p>Isso é propaganda ruim. E propaganda ruim se multiplica muito mais rápido do que a boa. O pior da propaganda ruim é que cria-se ainda mais preconceito em cima de algo que já encontra resistência naturalmente. Isso tira todas as chances de sucesso de uma implementação de Scrum. Estou cansado de ver em todos os lugares pessoas frustradas dizendo que tentaram implantar Scrum em suas empresas e não conseguiram. Mas é claro que não! O filme do Scrum já está queimado. Você vai falhar antes mesmo de tentar.</p>
<p>Já faz um tempo que eu parei de vender a idéia de usar Scrum. Desde então eu digo que eu procuro executar práticas ágeis. Soa mais leve, mais simples. O pré-conceito diminui dessa forma e a resistência também. Do que importa se meu facilitador chama Gerente de Projetos ou Scrum Master? As pessoas se preocupam mais com nomes do que com resultados e esse é o problema. Agilidade é o que há, mas funciona melhor sem rótulos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2010/01/14/eu-nao-uso-scrum-porque-scrum-nao-funciona/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Verbos HTTP: GET e POST. Você sabe mesmo a diferença?</title>
		<link>http://blog.tucaz.net/2009/11/22/verbos-http-get-e-post-voce-sabe-mesmo-a-diferenca/</link>
		<comments>http://blog.tucaz.net/2009/11/22/verbos-http-get-e-post-voce-sabe-mesmo-a-diferenca/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 00:23:51 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[WCF]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[escalabilidade]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[post]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[verbos http]]></category>
		<category><![CDATA[webrequest]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=386</guid>
		<description><![CDATA[Sabe a diferença entre POST e GET em um ambiente REST? Não? Então leia este post e assista o vídeo linkado para entender!]]></description>
			<content:encoded><![CDATA[<p>Até pouco tempo atrás quando eu fazia entrevistas a fim de contratar desenvolvedores, não importando o nível, eu fazia a mesma pergunta: &#8220;Você sabe a diferença entre GET e POST em uma request HTTP?&#8221;. Por incrível que pareça poucas pessoas sabiam responder. Na maioria das vezes alguém que se considerava um desenvolvedor web não tinha a menor idéia  sobre o que eu estava falando. Acho que era culpa do RH que fazia uma pré-seleção muito ruim, mas anyway&#8230;</p>
<p>Hoje essa informação já chegou a maioria dos desenvolvedores web (já era hora, não?) então a pergunta no contexto original perdeu um pouco a validade. Todo mundo sabe que enviar formulários via GET manda as informações pela querystring e que POST manda encapsulado dentro da request e bla bla bla. No entanto, com a nova &#8220;moda&#8221;, que acho bem bacana aliás, de REST(ful) a pergunta ganhou um contexto novo e tornou a ser válida: você sabe qual a diferença dos verbos em uma request HTTP? Não só de GET e POST, mas de todo o resto?</p>
<p>Decidi fazer esse post rápido enquanto retomava meus estudos a respeito de WCF e assistia a um vídeo do MIX do ano passado que está no final deste post.</p>
<p>POST não escala, GET sim. Porquê? Por causa da semântica! POST, PUT, DELETE e outros verbos são por definição non-safe e com efeitos colaterais, ou seja, é esperado que uma request usando esses verbos modifique algum recurso. Dessa forma é impossível fazer cache desse tipo de chamada. E como todos nós sabemos, sem cache = sem escalabilidade, isn&#8217;t that right?</p>
<p>Vamos tomar como exemplo uma chamada a URI imaginária: <em>http://meusite.com.br/usuario/novo</em> passando via POST todas as informações necessárias para se criar um usuário. Se tudo correr bem, vamos receber como resposta um HTTP Status Code 201 indicando que o recurso foi criado e a URL para acessa-lo. Provavelmente algo como <em>http://meusite.com.br/usuário/765</em>.</p>
<p>Agora a pergunta: é seguro para os intermediários dessa request tais como proxies, clientes, etc efetuarem o cache disso? Não! Imagine um usuário do sistema que utiliza esse recurso tentando cadastrar um novo usuário com os mesmos dados. Ao invés de receber uma resposta de conflito ele receberia um status 201 dizendo que o recurso foi criado. De fato o recurso foi criado, mas será que deveriamos mostrar isso pra ele quando na verdade a criação desse recurso já havia acontecido e a ação que ele executou neste momento não trouxe sucesso? Acho que não.</p>
<p>Já o GET, por definição é cacheavel, pois não possui efeitos colaterais. Ele apenas devolve o recurso desejado sem modificar nada. Claro que isso só acontece quando bem usado, pois tem muita gente que utiliza esse verbo de maneira errada e baseado em parâmetros executa ações que deveriam ser associadas a outros verbos HTTP. Como não modifica nenhuma informação é possível efetuar o cache desse recurso com segurança.</p>
<p>Pra quem quiser ver mais a respeito de <a title="Caching REST with WCF in MIX 09" href="http://videos.visitmix.com/MIX09/T64M" target="_self">REST, GET, POST e cache, basta acessar o vídeo no site do MIX 09</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2009/11/22/verbos-http-get-e-post-voce-sabe-mesmo-a-diferenca/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>(Inglês) Basic stuff: handling exceptions in .NET</title>
		<link>http://blog.tucaz.net/2009/07/21/basic-stuff-handling-exceptions-in-net/</link>
		<comments>http://blog.tucaz.net/2009/07/21/basic-stuff-handling-exceptions-in-net/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 18:19:09 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[handling]]></category>
		<category><![CDATA[vb.net]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=336</guid>
		<description><![CDATA[(Inglês) A simple guide on How to build proper exception handling in .NET.]]></description>
			<content:encoded><![CDATA[<p>Desculpe, mas este post só está disponível em <a href="http://blog.tucaz.net/en/category/desenvolvimento/feed/">Inglês</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2009/07/21/basic-stuff-handling-exceptions-in-net/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails e WinDBG</title>
		<link>http://blog.tucaz.net/2009/04/03/ruby-on-rails-e-windbg/</link>
		<comments>http://blog.tucaz.net/2009/04/03/ruby-on-rails-e-windbg/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 02:46:39 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[RoR]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[windbg]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=273</guid>
		<description><![CDATA[Dicas a respeito de Windows Debugging e Ruby on Rails]]></description>
			<content:encoded><![CDATA[<p>Não, não, não! Uma coisa não tem nada a ver com a outra. Não é um post falando de como debuggar rails utilizando o WinDBG. Mas um único post dando dicas de boas referências sobre o assunto.</p>
<p>Ultimamente não tenho mexido muito em código. Na verdade não tenho visto nada técnico, pois estou atolado de propostas pra fazer (quem mandou não estudar? <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). Mas&#8230;hoje quando cheguei em casa decidi que iria dedicar algum tempinho para mexer em algo interessante e diferente. Foi ai que topei primeiro com rails que eu já queria começar a estudar e depois com o WinDBG numa dica que veio do Twitter do <a title="André Nobre no Twitter" href="http://twitter.com/nbrtec" target="_self">André Nobre</a>.</p>
<p><strong>Ruby on Rails</strong></p>
<p>Há alguns dias instalei o ubuntu em uma VM aqui em casa e montei todo o ambiente Rails para começar a fuçar. Apesar de ainda não ter concluído e contrariando as dicas do <a title="Blog Rafael Rosa" href="http://www.rafaelrosafu.com/" target="_self">Rafael Rosa</a> que disse para eu fazer algo mais simples, iniciei a construção de um programinha de FTP web em Rails. Na verdade, hoje eu parei num &#8220;Hello World&#8221;. De qualquer forma, para quem está curioso para começar a mexer e ver o poder da ferramenta decidi disponibilizar alguns links que eu já havia encontrado e que o Rafa me passou. Ai vai:</p>
<ul>
<li><a title="Ruby Inside - Maior portal Brasileiro de notícias sobre Ruby" href="http://www.rubyinside.com.br/" target="_self">RubyInside</a> &#8211; Maior portal Brasileiro sobre notícias de Ruby. Primo do site gringo <a title="RubyInside.com" href="http://www.rubyinside.com" target="_self">http://www.rubyinside.com</a>.</li>
<li><a title="RailsCasts - Screencasts gratuitos sobre Rails" href="http://railscasts.com/" target="_self">RailsCasts</a> &#8211; Diversos screencasts gratuitos a respeito de Rails. Cobre diversos assuntos com exemplos.</li>
<li><a title="RubyQuickRef" href="http://www.zenspider.com/Languages/Ruby/QuickRef.html" target="_self">RubyQuickRef</a> &#8211; Site contendo uma referência rápida as classes de Ruby.</li>
<li><a title="Rails Guides" href="http://guides.rubyonrails.org/" target="_self">Rails Guides</a> &#8211; Segundo o Rafa, site que contém guias obrigatórios para os Railers que além de ensinar a programar em RoR, ensina &#8220;in the rails way&#8221;.</li>
<li><a title="RoR API Documentation" href="http://api.rubyonrails.org/" target="_self">Rails API</a> &#8211; Toda documentação da API do Rails.</li>
<li><a title="Ruby API Documentation" href="http://www.ruby-doc.org/core/" target="_self">Ruby API</a> &#8211; Toda documentação da API do Ruby.</li>
<li>Micro-tutorial Rails <a title="AkitaOnRails - Micro-tutorial Ruby Parte 1" href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-i" target="_self">Parte 1</a>, <a title="AkitaOnRails - Micro-tutorial Ruby Parte 2" href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-ii" target="_self">Parte 2</a> e <a title="AkitaOnRails - Micro-tutorial Ruby Parte 3" href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-iii" target="_self">Parte 3</a> &#8211; Micro-tutorial sobre Ruby no blog do AkitaOnRails. Desde o básico até alguns conceitos avançados.</li>
<li><a title="Montando ambiente Rails em Windows - AkitaOnRails" href="http://www.akitaonrails.com/2009/01/12/o-melhor-ambiente-windows-para-rails" target="_self">Montando ambiente Rails em Windows</a> &#8211; Tutorial ensinando a montar o melhor ambiente Rails em Windows também do AkitaOnRails.</li>
<li><a title="Blog Rafael Rosa" href="http://www.rafaelrosafu.com/" target="_self">Blog do Rafael Rosa</a> &#8211; Várias coisas a respeito de Rails e também de Asp.NET MVC <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>Esses são só alguns. Com certeza tem muito mais e espero colocar mais informações a respeito de Rails conforme eu for mexendo!</p>
<p><strong>WinDBG</strong></p>
<p>Debuggar código é uma arte. As vezes mais difícil do que criar código do zero. Afinal, quando debuggamos código que não é nosso temos que entender o que quer dizer e as vezes é tão mau escrito que é triste de ver&#8230;</p>
<p>Além do debug que estamos acostumados, dentro do VS existem debugs mais baixo nível que podemos fazer. Lá na CLR e no Windows, quando as fronteiras já passaram nossa aplicação. Praticamente coisa de louco!</p>
<p>Não é um assunto simples, nem tão pouco fácil de aprender. Há alguns meses navegando nos blogs da Microsoft encontrei o blog da <a title="Tess Fernandes Blog" href="http://blogs.msdn.com/tess/" target="_self">Tess Fernandes</a> que é engenheira da Microsoft. A menina é du mau e ela fala basicamente de debugging e assuntos relacionados a performance. O problema é que muito dos tópicos sobre debug que ela aborda são muito avançados para newbies como eu.</p>
<p>Ai é onde entra o blog do <a title="Blog do André Nobre" href="http://weblogs.asp.net/andrenobre/" target="_self">André Nobre</a> que já tem <a title="WinDBG - Série de posts sobre o assunto" href="http://weblogs.asp.net/andrenobre/archive/tags/WinDBG/default.aspx" target="_self">diversos posts</a> em português e em um nível iniciante para ajudar as mentes mais ignorantes neste assunto como é meu caso. Alguns dos posts inclusive são em formato de screencast com demos. Vale a pena conferir para aprofundar um pouquinho mais nesse assunto e conhecer uma outra alternativa para descobrir porque aquela maravilhosa aplicação que desenvolvemos não funciona como deveria. <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2009/04/03/ruby-on-rails-e-windbg/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Como gerenciar versões de banco de dados &#8211; Parte 2</title>
		<link>http://blog.tucaz.net/2009/03/08/como-gerenciar-versoes-de-banco-de-dados-parte-2/</link>
		<comments>http://blog.tucaz.net/2009/03/08/como-gerenciar-versoes-de-banco-de-dados-parte-2/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 03:42:17 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[Banco de Dados]]></category>
		<category><![CDATA[migrations]]></category>
		<category><![CDATA[Migrator.NET]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=255</guid>
		<description><![CDATA[Utilizando Migrator.NET no gerenciamento de versões de banco de dados.]]></description>
			<content:encoded><![CDATA[<p>Na <a title="Como gerenciar versões de banco de dados - Parte 1" href="http://blog.tucaz.net/2009/03/01/como-gerenciar-versoes-de-banco-de-dados-parte-1/" target="_self">primeira parte</a> falei um pouco dos problemas envolvidos no controle de versionamento de banco de dados. Agora esta na hora de apresentar alguma solução, certo? <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Apresentando Migrator.NET</strong></p>
<p>Para resolver a maioria (senão todos) os problemas de versionamento de banco temos uma ferramenta maravilhosa chamada<a title="Migrator.NET - Google Code" href="http://code.google.com/p/migratordotnet/" target="_self"> Migrator.NET</a>. Essa ferramenta é um port para .NET do original em <a title="RoR Migrations" href="http://api.rubyonrails.org/classes/ActiveRecord/Migration.html" target="_self">Rails</a>. A idéia por trás dela é bastante simples: consiste em diversos objetos (classes) versionados (da mesma maneira que código normal) contendo as instruções que devem ser executadas para gerar e/ou voltar o schema do banco de dados. Cada classe corresponde a uma instrução de alteração e contém um método Up (adicionar/avançar) e um método Down (retroceder/fallback) equivalente. Vejamos como é facil no exemplo abaixo:</p>
<pre name="code" class="c-sharp">#region Usings

using System.Data;
using Migrator.Framework;

#endregion

namespace NetScrum.Migrations.Tables
{
    [Migration(20090209211900)]
    public class CreateTableProject : Migration
    {
        public override void Down()
        {
            Database.RemoveTable("netscrum_project");
        }

        public override void Up()
        {
            Database.AddTable("netscrum_project",
                new Column("id", DbType.Int32, ColumnProperty.Identity)
                , new Column("name", DbType.AnsiString, 100, ColumnProperty.NotNull)
                , new Column("description", DbType.AnsiString, 300, ColumnProperty.Null)
                );

            Database.AddPrimaryKey("pk_project", "netscrum_project", "id");
        }
    }
}</pre>
<p>Viram? Basta referenciar a DLL <strong>Migrator.Framework.dll</strong>, adicionar a diretiva <strong>using</strong> criar sua classe herdando de <strong>Migration</strong> e dar override nos métodos <strong>Up</strong> e <strong>Down</strong>.</p>
<p><strong>Gerenciando as versões</strong></p>
<p>Para gerenciar as versões e garantir que os migrations sejam executados na ordem correta, você deve utilizar o atributo <strong>Migration(long version)</strong> decorando a classe. Você deve preenche-lo com um long contendo o timestamp no formato AAMMDDhhmmss (ano/mes/dia/hora/minuto/segundo) em que seu migration foi gerado. Ou seja, um alter table da tabela projeto, por exemplo, deve conter um valor mais novo (maior) que o create table correspondente para que o migration de create seja executado antes do alter.</p>
<p><strong>Configurando o build</strong></p>
<p>Criar e gerenciar migrations é muito fácil. No entanto, as configurações dele são um pouquinho chatas para quem não está familizarizado com <a title="MSBuild Reference - MSDN.com" href="http://msdn.microsoft.com/pt-br/library/0k6kkbsd.aspx" target="_self">MSBuild</a> ou <a title="NAnt - Sourceforge" href="http://nant.sourceforge.net/" target="_self">NAnt</a>. Neste artigo vamos usar o MSBuild que já é nativo e eu gosto mais simplesmente por estar familiarizado.</p>
<p>Junto com o código fonte compilado do Migrator.NET vem também o assembly <strong>Migrator.MSBuild.dll </strong>que é onde está a o target especifico que o MSBuild precisa para executar os migrations. Este target será usado no arquivo de build (explicado mais abaixo) e deve ser configurado como o exemplo abaixo apontando para o caminho onde esta o assembly. Arquivos Migrator.Targets:</p>
<pre name="code" class="xml">

        $(MigratorTasksPath)\Migrator.MSBuild.dll</pre>
<p>A propriedade <em>$(MigratorTasksPath)</em> define onde está o assembly Migrator.MSBuild.dll. O valor desta propriedade pode ser hard-coded ou então preenchida no arquivo de build conforme veremos.</p>
<p>Por padrão, todo projeto (arquivo.csproj no caso de C#) é um arquivo de MSBuild. É possível editá-lo para incluir as configurações necessárias ao Migrations, mas cedo ou tarde é perigoso que Visual Studio o recrie ou o modifique a seu bel prazer e ai perderiamos as customizações. Portanto, prefiro criar um outro arquivo de build exclusivo para os migrations e chama-lo quando eu bem entender. Segue abaixo o arquivo NetScrum.Migrations.build:</p>
<pre name="code" class="xml">

    $(MSBuildProjectDirectory)</pre>
<p>Este arquivo define uma série de paramêtros:</p>
<ul>
<li>MigratorTasksPath &#8211; Caminho utilizado para apontar onde esta o target (mencionado acima). Neste caso, é preenchido pela propriedade $(MSBuildProjectDirectory) que aponta para onde o arquivo build que está sendo chamado está localizado.</li>
<li>DatabaseVersion &#8211; Será passado via paramêtro na hora da chamada do Migrator.NET. Caso não seja informado, o valor default é -1 que indica para a última versão.</li>
<li>Provider = Banco de dados de destino. Neste caso estamos usando SqlServer, mas Migrator.NET funciona para <a title="Bancos suportados pelo Migrator.NET" href="http://code.google.com/p/migratordotnet/" target="_self">outros bancos também</a>.</li>
<li>Connectionstring &#8211;  Óbvio, né? <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>To &#8211; Recebe o valor do parametro DatabaseVersion indicando a versão de destino do migrations.</li>
<li>Migrations &#8211; Caminho onde se encontra o assembly compilado contendo as migrations.</li>
</ul>
<p>Existem alguns outros paramêtros que permitem uma configuração um pouco diferenciada, como por exemplo, ao invés de fornecer o assembly compilado apenas informar o caminho onde estão as classes para que o próprio Migrator.NET faça a compilação.</p>
<p>Uma vez que tudo esteja configurado, basta ir até o command prompt, navegar até a pasta onde o arquivo.build e chamar o MSBuild passando os paramêtros conforme o exemplo abaixo:</p>
<pre name="code" class="brush: shell">%windir%\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe NetScrum.Migrations.build /t:Migrate /p:DatabaseVersion=-1</pre>
<p>Os paramêtros são:</p>
<ul>
<li>NetScrum.Migrations.build &#8211; Nome do arquivo de build que contém as configurações do Migrator.NET</li>
<li>/t:Migrate &#8211; Target que deve ser executado. Neste caso o target de migrations <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>/p:DatabaseVersion=-1 &#8211; Versão do banco para qual desejo ir. Caso queira ir para última versão é só informar -1. Caso queira zerar o banco (executar Down de todas as migrations) é só informar 0. No caso de ir para uma versão específica é só informar o timestamp desejado.</li>
</ul>
<p>É isso! Configurar a primeira vez é um pouco chato. Acertar os caminhos dos arquivo requer algumas tentativas para quem não está familizarizado com o MSBuild, mas nada muito traumático. Nos exemplos, todos os arquivos necessários (menos o assembly contendo as migrations) estavam na mesma pasta (tools) para facilitar.</p>
<p><strong>Exemplo</strong></p>
<p>Quem quiser ver o exemplo funcionando, basta baixar a <a title=".NET Scrum" href="http://netscrum.codeplex.com/" target="_self">última versão do .NET Scrum</a>. Ele contém as pastas e arquivos configurados direitinho pra funcionar.</p>
<p><strong>Importante</strong></p>
<p>A versão utilizada para este artigo foi a 0.8 que baixei tem uns 45 dias. Na época, apesar de compilada não estava funcionando então tive que efetuar umas pequenas correções do trunk. Não testei a versão 0.8 disponível hoje, portanto você pode <a title="Migrator.NET 0.8" href="http://tucaz.net/downloads/Migrator_0.8.zip" target="_self">baixar aqui a versão 0.8 compilada e corrigida por mim</a>.</p>
<p><strong>Referências</strong></p>
<p>Até alguns dias atrás eu não tinha encontrado nenhum outro artigo a respeito deste assunto em português. Acredito que ainda não exista e esse seja o primeiro. Além das instruções básicas de banco que foram apresentadas no migration do exemplo ainda é possível criar PKs, FKs, executar Sql&#8217;s open text entre outros procedimentos não descritos aqui.</p>
<p>Vocês podem encontrar informações a respeito desses <a title="Escrevendo migrations" href="http://code.google.com/p/migratordotnet/wiki/WritingMigrations" target="_self">procedimentos no site do projeto</a> ou tirar dúvidas e perguntar aqui mesmo no blog.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2009/03/08/como-gerenciar-versoes-de-banco-de-dados-parte-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

