Community Launch em Campinas

No próximo dia 20 de março acontecerá um evento chamado de Community Launch. Esse evento será espalhado por todo o Brasil, onde cada região criará o evento e abordará os principais produtos da Microsoft que estarão sendo lançados neste ano de 2010, a saber: Visual Studio 2010, Windows Server 2008 R2SQL Server 2008 R2.

Para quem é de Campinas e região, este evento acontecerá na Universidade UNIP, localizada no bairro Swift, à partir das 09:00 da manhã. Caso você não saiba exatamente onde ela está localizada, consulte este endereço para saber como chegar até lá. Entre as várias palestras, eu sou o responsável por falar sobre Visual Studio 2010 e .NET Framework 4.0. É importante dizer que a palestra será de nível 100, que além de abordar superficialmente algumas das principais funcionalidades desta nova versão, falaremos um pouco também sobre algumas tecnologias que já existem e estão à disposição desde as versões anteriores. Abaixo temos a descrição da palestra:

Título: Visual Studio 2010 e .NET Framework 4.0
Palestrante: Israel Aece
Descritivo: Esta palestra tem a finalidade de exibir um “tour” sobre a plataforma .NET, e a principal ferramenta que utilizamos para desenvolver aplicações para ela, que é o Visual Studio. A ideia é demonstrar rapidamente a história e a evolução do .NET Framework até a versão 4.0, incluindo assuntos como as linguagens de programação (C# e VB.NET), acesso à dados e aplicações para internet (WebForms, MVC e Silverlight). Logo após, vamos analisar de forma superficial as novidades que estão sendo incluídas na IDE do Visual Studio 2010 e que dão suporte ao desenvolvimento de qualquer tipo de aplicação sobre a plataforma .NET.

IMPORTANTE: Apesar do evento ser gratuito, para poder participar é necessário efetuar o cadastro aqui.

Parse de Datas

Para quem trabalha com o padrão de comunicação APL/APC, é muito comum que dentro de um arquivo as datas estejam formatadas da seguinte forma: ddMMyyyy (20/07/2010), ou seja, sem as barras ou qualquer outro tipo de separador entre o dia, mês e o ano.

Só que gostaríamos de trazer isso para um DateTime, para assim conseguir manipular melhor a data. Como fazer? Muitos optam pela manipulação da string, via método Substring, etc. Apesar de funcionar, dá um trabalho muito grande. Os métodos Parse da estrutura DateTime ou o ToDateTime da classe Convert, tentam converter a string seguindo o formato especificado pela cultura atual. A cultura geralmente tem uma formatação própria, como por exemplo, a cultura pt-BR é dd/MM/yyyy; já a en-US é MM/dd/yyyy, etc., e se utilizarmos uma dessas técnicas aqui, uma exceção do tipo FormatException é disparada, informando o problema.

Para resolver isso, você pode recorrer ao método ParseExact, também da classe DateTime, que também tem a finalidade de converter uma string em DateTime, mas seguindo uma formatação específica. Ao invocar este método, você deve informar o formato exato em que a data está definida dentro da string, e que no nosso caso é ddMMyyyy:

string data = “20072010”;
DateTime dataDePagamento = DateTime.ParseExact(data, “ddMMyyyy”, null);

MEF – Managed Extensibility Framework

revista mundo .net - 018 Toda aplicação que deseja suportar “plugins”, terá que se preocupar, também, em criar toda a infraestrutura necessária para suportá-los. Como essa preocupação está cada vez mais popular nos dias de hoje, a Microsoft trabalha em um projeto chamado MEF – Managed Extensibility Framework. Ao invés de explicitamente referenciar os componentes na aplicação, o MEF permitirá efetuar o descobrimento desses componentes de forma implícita, através de composição, gerenciando tudo o que for preciso para manter essas extensões, possibilitando que sua aplicação fique dependente de uma abstração, e não de uma implementação.

Atualmente o MEF encontra-se em desenvolvimento, e a Microsoft tem disponibilizado versões CTPs (Community Technology Preview), para avaliações do produto. A versão atual é a CTP 8, que já vem incorporada no Beta 2 do Visual Studio .NET 2010 e .NET Framework 4.0 e, provavelmente, fará parte da versão final do .NET Framework 4.0.

Este artigo tem a finalidade de abordar a API do MEF, mostrando todas as suas funcionalidades e como podemos utilizá-las em nossas aplicações.

Exceções no construtor e blocos using

Se uma determinada classe que está sendo criada possuir referências para outros objetos que são custosos, a boa prática é implementar o padrão Disposable, que nos permite explicitamente descartar estes recursos quando não mais precisamos deles. O padrão Disposable consiste na implementação de uma interface chamada IDisposable, que fornece um método Dispose, que dentro dele você fará toda a limpeza necessária.

Disparar exceções em construtores é algo comum, e que na maioria das vezes representam validações dos parâmetros que são passados à instância da classe que está sendo criada. Um cuidado especial nestes casos, é garantir que você nunca armazene nenhum objeto antes de tais validações, por exemplo:

public class MinhaClasse : IDisposable
{
    private IntPtr _ponteiro;
    private string _valor;

    public MinhaClasse(string valor, IntPtr ponteiro)
    {
        this._ponteiro = ponteiro;

        if (string.IsNullOrEmpty(valor))
            throw new ArgumentNullException(“valor”);

        this._valor = valor;
    }

    public void Dispose()
    {
        if (this._ponteiro != IntPtr.Zero)
            this._ponteiro = IntPtr.Zero;
    }

    ~MinhaClasse() { Dispose(); }
}

Ao criar a instância desta classe e definir o parâmetro valor como nulo, repare que antes da validação acontecer, o membro _ponteiro já estará com o valor armazenado. Mesmo que você esteja trabalhando da forma politicamente correta, que é implementando a interface IDisposable para a liberação dos recursos, você tem ainda outros problemas, já que ela não funciona por si só. Sabemos que a implementação desta interface é apenas uma convenção, mas para que a limpeza realmente funcione, o desenvolvedor deverá explicitamente invocar o método Dispose.

Neste caso, envolver a instância em um bloco using (que garante a chamada implícita do Dispose) não resolverá. Como sabemos, o using é açúcar sintático, pois na verdade ele é compilado para blocos try/finally. Se instanciarmos a classe dentro do using, a criação da instância será colocada fora do bloco try, e como a exceção está sendo disparada no construtor, o Dispose não será invocado e, infelizmente, teremos que esperar até o destrutor ser invocado, isso se o tivermos implementado.

Nova versão do método Monitor.Enter

Desde a primeira versão do .NET Framework, temos a keyword lock. Com ela, podemos criar um bloco de código que será acessado por uma única thread de cada vez. Na verdade, depois de compilado, esse bloco é transformado em chamadas para os métodos Enter e Exit, respectivamente, expostos pela classe Monitor (System.Threading), e envolvido por um bloco try/finally. Imagine o seguinte código: 

lock (_meuLock)
{
    //código “protegido”
}

Ao ser compilado, esse código será transformado em:

Monitor.Enter(_meuLock);
try
{
    //código “protegido”
}
finally
{
    Monitor.Exit(_meuLock);
}

O problema disso é que, segundo o Joe Duffy, exceções podem acontecer entre o método Enter (que é responsável por adquirir o lock) e o bloco try; isso dará origem ao que ele chama de “bloqueios orfãos”, já que nunca serão liberados, pois o bloco finally não será disparado.

Para resolver isso, a Microsoft criou uma nova versão (overload) do método Enter, que além do objeto que representa o lock, recebe um parâmetro boleano indicando se o lock foi ou não adquirido com sucesso. O valor retornado por esse parâmetro boleano, será avaliado mais tarde, que determinará se o método Exit correspondente deverá ou não ser invocado. Além dessa mudança, o método Enter passa a ser chamado dentro do bloco try, garantindo assim que o bloco finally seja disparado e, consequentemente, liberando o lock. O mesmo código acima, a partir da versão 4.0 do .NET Framework, passa a ser compilado da seguinte forma:

bool taken = false;
try
{
    Monitor.Enter(_meuLock, ref taken);
    //código protegido
}
finally
{
    if (taken)
        Monitor.Exit(_meuLock);
}

Novas classes para inicialização de objetos

Quando desenvolvemos algum tipo de aplicação ou componente, é muito comum encontrarmos dentro do nosso código, classes que são extremamente custosas, ou melhor, que possuem um grande overhead na inicialização, como por exemplo, efetuam acesso à IO, cálculos complexos, etc. Dependendo da situação, instanciamos essas classes (pagando o alto preço da inicialização) e não utilizamos, já que, eventualmente, o teu sistema não precisará dela naquele momento.

Para melhorar isso, a Microsoft está disponibilizando no .NET Framework 4.0, uma classe genérica chamada Lazy<T> (namespace System). Basicamente, a finalidade desta classe é postergar, ao máximo, a criação do teu objeto, ou seja, isso somente acontecerá quando você realmente precisar dele. Por ser uma classe genérica e o parâmetro T não ter qualquer restrição, você pode definir T como qualquer tipo. Essa classe será um wrapper para o teu objeto custoso, efetuando a criação do mesmo somente quando for requisitado.

Ao instanciar a classe Lazy<T>, você tem algumas opções que variam de acordo com o overload do construtor que utiliza. Em um dos construtores, há um parâmetro boleano, que determina se a inicialização será ou não thread-safe. Se a instância da classe Lazy<T> pode ser acessada por um ambiente multi-threading, então definir este valor como True (que é o padrão), evitará problemas conhecidos, tal como as races conditions. Com isso, a primeira thread que entrar, incializará o objeto, e as threads subsequentes compartilharão o mesmo objeto, que já está criado. Mas se ambiente multi-threading não é o cenário, então definir esse parâmetro como False evitará processamentos extras, que são desnecessários neste caso.

Há também um overload do construtor, que recebe como parâmetro a instância de um delegate do tipo Func<T>. Esse delegate é referido como uma “factory”, ou seja, apontará para um método responsável por criar o objeto quando for solicitado, nos permitindo inicializá-lo de acordo com uma regra específica. Quando esse parâmetro não é informado, a classe Lazy<T> irá instanciar o tipo através do método CreateInstance da classe Activator, obrigando o tipo definido em T, a ter um construtor público sem parâmetros, caso contrário, uma exceção será disparada.

Além dos construtores, essa classe ainda expõe, publicamente, duas propriedades de somente leitura: IsValueCreated e Value. A primeira delas, retorna um valor boleano indicando se o objeto já foi ou não criado. Já a segunda, é a propriedade que utilizamos para extrair o objeto que foir criado e está sendo gerenciado pelo wrapper. É dentro desta propriedade que há toda a regra utilizada para determinar se o objeto já foi criado. E como vimos acima, caso ele ainda não tenha sido, invocará o método privado LazyInitValue, e me retornará a instância. Chamadas subsequentes, da mesma thread ou não, não entrarão mais neste método, reutilizando a instância criada. O código abaixo exibe um exemplo da utilização desta classe:

public class NotaFiscal
{
    public int Codigo { get; set; }
    public DateTime Data { get; set; }

    private Lazy<List<Item>> _itens;

    public NotaFiscal(int codigo)
    {
        this.Codigo = codigo;
        this._itens =
            new Lazy<List<Item>>(() => DataHelper.RecuperarItensDaNotaFiscal(this.Codigo));
    }

    public IEnumerable<Item> Itens
    {
        get
        {
            return this._itens.Value;
        }
    }
}

Como podemos perceber no código acima, a instância da classe representa uma Nota Fiscal. Muitas vezes carregamos a Nota Fiscal completa, incluindo seus respectivos itens, mas nem sempre eles são utilizados. Ao invés de carregar esses itens na criação da Nota Fiscal, iremos postergar essa tarefa, recorrendo a classe Lazy<T>. Como podemos ter vários itens, então o argumento T será definido como List<Item>. No construtor da classe Nota Fiscal, instanciamos a classe Lazy<List<Item>>, definindo em seu construtor, o método responsável por carregar os itens da Nota Fiscal. A propriedade que expõe os itens da Nota Fiscal, quando solicitada, recorre a propriedade Value do objeto _itens, que como vimos acima, é neste momento que o método (factoryRecuperarItensDaNotaFiscal será disparado.

Além da classe Lazy<T>, ainda temos a classe ThreadLocal<T> (namespace System.Threading). Assim como a anterior, não há nenhuma restrição quanto ao argumento T, ou seja, podemos definir qualquer tipo. A finalidade desta classe, é sanar alguns comportamentos de campos estáticos quando utilizados em conjuto com o atributo ThreadStaticAttribute. Ao aplicar esse atributo, cada thread terá a sua própria cópia do valor, mesmo que ele seja declarado como estático (static). O problema que ocorre ao utilizar esse atributo, é quando temos um campo que já é automaticamente inicializado, como por exemplo:

public class Teste
{
    [ThreadStatic]
    public static int Numero = 4;
}

A inicialização de todo membro estático ocorre apenas uma única vez, mesmo quando temos este atributo aplicado. Para ilustrar isso, vamos criar três threads diferentes, onde cada uma delas escreverá o valor do membro Numero:

new Thread(() => Console.WriteLine(Teste.Numero)).Start();
new Thread(() => Console.WriteLine(Teste.Numero)).Start();
new Thread(() => Console.WriteLine(Teste.Numero)).Start();

E o resultado é: 4, 0 e 0. A classe ThreadLocal<T> vai conseguir lidar com isso, ou seja, permitirá especificar um delegate de inicialização, que será invocado sempre que o valor for requisitado por uma nova thread. Ao invés da inicialização acontecer uma única vez, ele sempre rodará quando solicitado, e sempre trazendo a cópia da informação para dentro da thread corrente, não compartilhando o mesmo, assim como já acontecia anteriormente. Com essa nova classe, podemos reescrever o exemplo da seguinte forma:

public class Teste
{
    public static ThreadLocal<int> Numero = new ThreadLocal<int>(() => 4);
}

new Thread(() => Console.WriteLine(Teste.Numero.Value)).Start();
new Thread(() => Console.WriteLine(Teste.Numero.Value)).Start();
new Thread(() => Console.WriteLine(Teste.Numero.Value)).Start();

E agora, como já era de se esperar, temos como resultado: 4, 4 e 4. É importante dizer que se nada for informado no construtor desta classe, ela sempre construirá o tipo com o seu valor padrão.

Para finalizar, temos a classe estática LazyInitializer, que possui apenas um único método público: EnsureInitialized. Neste caso, ao invés de definir todos os membros como Lazy<T>, podemos recorrer a este método para inicializá-los individualmente, quando você achar necessário, sem a necessidade do wrapper. O código abaixo ilustra a utilização desta técnica, mas repare que informamos o objeto que será abastecido e o método (factory) que o construirá.

public IEnumerable<Item> Itens
{
    get
    {
        if (this._itens == null)
            LazyInitializer.EnsureInitialized(ref _itens, () => DataHelper.RecuperarItensDaNotaFiscal(this.Codigo));

        return this._itens;
    }
}

Conclusão: Criar aplicações multi-threading é bem simples, mas o grande problema sempre é a sincronização delas. Classes como essas que vimos aqui, auxilia bastante neste caso, tirando em algum pontos, a responsabilidade do usuário em gerenciar isso, podendo ele se preocupar cada vez mais com as regras de negócio. Essas classes que vimos aqui, estarão disponíveis a partir da versão 4.0 do .NET Framework, que já trará também uma grande API para suportar o desenvolvimento de código paralelo.

Novos métodos para Enumeradores

A partir da versão 4.0 do .NET Framework, teremos dois novos métodos estáticos para a manipulação de enumeradores fornecidos pela classe Enum: TryParse<TEnum> e HasFlag.

Como podemos perceber, o primeiro deles, TryParse<TEnum>, trata-se de um método genérico, que recebe dois parâmetros. O primeiro deles, é uma string contendo o nome ou valor do item a ser pesquisado dentro do enumerador, já informado pelo argumento genérico TEnum; já o segundo parâmetro (de saída), é do tipo TEnum, pois caso a conversão seja possível, esse resultado já traz a informação tipada. E ainda, este método retorna um valor boleano, indicando se a conversão foi ou não possível, ao contrário do método Parse, que dispara uma exceção. Esse método trabalha de forma semalhante ao método TryParse das estruturas DateTime, Int32, entre outras que já fazem parte do .NET Framework. Abaixo temos o exemplo da sua utilização:

public enum Itens { Read, Write, FullControl, None }

Itens permissoes = Itens.None;

if (Enum.TryParse<Itens>(“Read”, out temp).ToString())
    Console.WriteLine(“Nível de Permissão: {0}”, temp);
else
    Console.WriteLine(“Não foi possível determinar o tipo de Permissão.”);

Além desse método, a Microsoft também está adicionando o método de instância chamado HasFlag, que retorna uma valor boleano indicando se o valor existe ou não dentro daquele enumerador. Com ele, a partir da variável que armazena o(s) enumerador(es) selecionado(s), podemos invocá-lo e passarmos o item a ser verificado, assim como podemos reparar no exemplo abaixo:

Itens permissoes = Itens.Read | Itens.Write;

if (permissoes.HasFlag(Itens.FullControl))
    Console.WriteLine(“Você tem permissão total.”);

Copiando Streams

Uma operação muito comum é a cópia de streams. Há diversas situações onde você pode querer usar isso, como por exemplo, armazenar um conteúdo de um arquivo em memória, para não precisar acessar o arquivo físico toda vez que precisar dele. Antes do .NET Framework 4.0, com o stream de origem em mãos, precisávamos armazenar os blocos em um buffer temporário, e em seguida, copiar para o stream de destino.

Apesar de não ser uma tarefa muito difícil de fazer, ela é propícia a erros, já que você precisa ficar manipulando índices para invocar os métodos Read e Write. Com o .NET Framework 4.0, a Microsoft acaba de adicionar um método (de instância) chamado CopyTo na classe Stream. Com ele, todas as classes que derivam direta ou indiretamente dela, poderão copiar o conteúdo atual para um outro Stream. Tudo o que precisamos fazer é:

MemoryStream ms = new MemoryStream();

using (FileStream fs = File.Open(“Arquivo.xml”, FileMode.Open)
    fs.CopyTo(ms);

Path.Combine

Até antes do .NET Framework 4.0, você possui um método estático chamado Combine, exposto pela classe Path. Dado duas strings para este método, ele retorna uma nova string contendo a combinação desses dois paths, colocando ou removendo barras quando necessário. Isso ajuda bastante, já que não precisamos ficar lidando com a string diretamente, verificando se existe ou não as barras para efetuar a concatenação.

Provavelmente você já deve ter se deparado com a situação onde você tem o path separado em mais partes. Com isso, o problema volta a acontecer, pois o método Combine não permite informarmos mais do que duas strings. A versão 4.0 do .NET Framework, a Microsoft adicionou uma nova versão (overload) deste método, que permite informarmos o path através de um paramarray, e com isso, podemos colocar quantas strings quisermos, que ele fará todo o trabalho necessário, e nos devolverá o resultado esperado. Veja o exemplo abaixo:

Console.Write(new StreamReader(Path.Combine(“d:Arquivos”, “Logs”, “Cobranca”, “2009.log”)).ReadToEnd());

Eventualmente, se você informar uma string vazia, ele automaticamente omitirá do resultado final. Além disso, a primeira string passada para este método, deverá sempre representar o path absoluto (“d:” ou “\arquivos”). Se ele encontrar qualquer outro path absoluto no meio, a operação será reiniciada, e todos os paths anteriores serão descartados.

Novos métodos da classe String

A versão 4.0 do .NET Framework, adiciona novos métodos estáticos na classe String, que possibilita trabalhar de forma muito mais simples do que anteriormente. O primeiro desses métodos é o IsNullOrWhiteSpace, que dado uma string, retorna um valor boleano indicando se é uma referência nula, vazio ou uma sequência de caracteres em branco, evitando a necessidade de chamar o método IsNullOrEmpty em conjunto com o método Trim.

Outra novidade é o método Concat<T>, que permite passar uma instância de alguma classe que implemente a Interface IEnumerable<T>. Isso ajudará, principalmente, quando estamos trabalhando com LINQ, e precisamos concaternar alguma propriedade retornada pela query, sem a necessidade de converter explicitamente em um array de strings. É importante dizer que esse método invoca o método ToString dos objetos (exposto pela classe System.Object), que obrigará você a customizá-lo, exibindo as informações necessárias, que na maioria das vezes, representa o estado do objeto. O exemplo abaixo ilustra o uso:

public class Usuario
{
    public string Nome { get; set; }
    public string Estado { get; set; }

    public override string ToString()
    {
        return this.Nome;
    }
}

string resultado = string.Concat((from u in listaDeUsuarios where u.Estado = “SP” select u));