Adicionando Membros em Tempo de Execução

Como sabemos, o C# 4.0 (que virá junto com o Visual Studio .NET 2010) já trará alguns aspectos de linguagens dinâmicas, que permitem a avaliação/checagem de um membro somente em tempo de execução. Para suportar esta funcionalidade, um novo “tipo” foi criado, conhecido como “dynamic”. Ao declarar uma variável do tipo “dynamic”, a checagem de existência de um determinado membro não acontecerá estaticamente, ou seja, independentemente se ele exista ou não, você somente saberá isso em tempo de execução.

Com este tipo especial, você somente conseguirá acessar os membros que, eventualmente, já existam. Mas e como você pode proceder, se quiser construir um tipo dinamicamente? É aqui que entra em cena a classe ExpandoObject (namespace System.Dynamic). Ao instanciar essa classe, você poderá criar tipos dinamicamente, definindo novas propriedades e métodos para este tipo. Para que isso funcione adequadamente, você precisará atribuir a instância desta classe à uma variável do tipo “dynamic”, caso contrário, como vimos acima, a checagem será efetuada durante a compilação, o que não permitirá a compilação. O código abaixo ilustra a utilização desta nova classe:

dynamic obj = new ExpandoObject();
obj.Nome = “Israel”;
obj.Endereco = new ExpandoObject();
obj.Endereco.Cidade = “Valinhos”;
obj.AlgumMetodo = new Action<string>(s => Console.WriteLine(s));

Console.WriteLine(obj.Endereco.Cidade);
obj.AlgumMetodo(“Teste”);

Como podemos notar, instanciamos a classe ExpandoObject para uma variável definida como dinâmica. Depois disso, quando queremos criar “sub-tipos”, basta instanciar uma nova classe ExpandoObject para ele, e seguir criando os novos membros a partir dali. Métodos também podem ser criados, e você pode recorrer a algum delegate já existente para definir a ação a ser executada quando ele for invocado.

Na verdade, esses membros não são incluídos dentro da classe ExpandoObject. A medida que você vai criando estes membros, ele irá armazenando em um dicionário, e quando requisitado, extrai e o executa. Essa funcionalidade é disponibilizada através da Interface IDynamicMetaObjectProvider. Acredito que a performance deva ser mais lenta do que o binding estático, mas é um preço que se deve pagar quando quiser interoperar com linguagens dinâmicas que, além da interoperabilidade com o mundo COM é, ao meu ver, os principais cenários para códigos deste tipo.

Método Zip

Um novo método (de extensão) foi adicionado à classe Enumerable na versão 4.0 do .NET, chamado de Zip. Dado duas coleções/arrays, esse método tem a finalidade de aplicar uma espécie de “zíper” entre eles, ou seja, agrupando os elementos correntes de cada coleção, onde o resultado é a combinação entre esses dois elementos. Para exemplificar, considere os dois arrays de inteiros:

int[] pares = new int[] { 0, 2, 4, 6, 8 };
int[] impares = new int[] { 1, 3, 5, 7, 9 };

foreach
(var item in impares.Zip(pares, (i, p) => string.Format(“{0}, {1}, “, p, i)))
    Console.Write(item);

O resultado ficará: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. O processamento se encerra quando não for encontrado um elemento “correspondente” na outra coleção.

MultiMethods

É muito comum criarmos métodos em nossas classes que possuam “versões” diferentes. Por “versão”, entenda como overload ou sobrecarga do método. Isso quer dizer que podemos ter um método com o mesmo nome, mas que possuem quantidade ou tipos diferentes.

Em linguagens como o C# e o VB.NET, a resolução de qual dos overloads será invocado é feita em tempo de compilação, baseando no tipo que está sendo passado para o método, o compilador determinará qual das versões invocar. Suponhamos que temos a seguinte estrutura de classes:

public class Pessoa
{
    public string Nome;
}

public class PessoaJuridica : Pessoa
{
    public string CNPJ;
}

public class PessoaFisica : Pessoa
{
    public string CPF;
}

Agora, temos uma classe que tem a finalidade de gerenciar instâncias da classe Pessoa. Essa classe possui dois overloads, onde cada um deles espera uma instância concreta da classe Pessoa:

public class GestorDePessoas
{
    public void AdicionarPessoa(PessoaFisica pf)
    {
        Console.WriteLine("PF");
    }

    public void AdicionarPessoa(PessoaJuridica pj)
    {
        Console.WriteLine("PJ");
    }
}

Nossa aplicação trabalhará de forma independente de qual tipo de Pessoa esteja utilizando. Haverá um método chamado ConstruirPessoa que, dado o nome e o número do documento, retornará uma instância da classe PessoaFisica ou PessoaJuridica que, no nosso caso, deveremos passá-la para a classe GestorDePessoas. Se traduzirmos este parágrafo para código, então teríamos algo como:

Pessoa p = ConstruirPessoa(“Israel Aece”, “123456789”);
GestorDePessoas gp = new GestorDePessoas();
gp.AdicionarPessoa(p);

Se tentarmos compilar, receberemos um erro avisando que não foi possível encontrar um método com essa assinatura. As duas versões do método AdicionarPessoa esperam instâncias das classes concretas (PessoaFisica e PessoaJuridica). Mesmo que “p” armazene internamente a instância de uma classe concreta, ele não conseguirá determinar qual dos métodos invocar, pois somente saberemos o que “p” representa durante a execução da aplicação.

MultiMethods é um conceito que existe para escolher qual dos métodos invocar em tempo de execução, ao contrário do que acontece com o overloading, que fará essa escolha estaticamente, ainda em tempo de compilação. Há várias implementações de MultiMethods para .NET, e uma delas é o MultiMethods.NET. Com essa library, podemos criar apenas uma versão pública do método, que por sua vez, receberá a versão mais básica do tipo, que no nosso caso é a classe Pessoa. Internamente, a library determinará qual dos overloads invocar de acordo com o tipo que está sendo passado. O código abaixo ilustra a classe GestorDePessoas ligeiramente alterada, utilizando a library em questão:

public class GestorDePessoas
{
    private MultiMethod.Action<Pessoa> _adicionar;

    public GestorDePessoas()
    {
        this._adicionar = Dispatcher.Action<Pessoa>(this.AdicionarPessoa);
    }

    public void AdicionarPessoa(Pessoa p)
    {
        this._adicionar(p);
    }

    protected virtual void AdicionarPessoa(PessoaFisica pf)
    {
        Console.WriteLine("PF");
    }

    protected virtual void AdicionarPessoa(PessoaJuridica pj)
    {
        Console.WriteLine("PJ");
    }
}

O código de consumo desta classe que antes não funcionava, passa a funcionar, e em tempo de execução, o método AdicionarPessoa será invocado de acordo com o tipo retornado pelo método ConstruirPessoa. Publicamente temos apenas o método AdicionarPessoa que aceita o tipo base, e dentro dele, utiliza o delegate fornecido pela library para efetuar a escolha do método.

É importante dizer que estas libraries de MultiMethods recorrem a Reflection para efetuar todo o trabalho, e como sabemos, isso possui um overhead extra. Se de um lado ganhamos em flexibilidade, do outro perdemos em performance. Já com o .NET 4.0, o “tipo” dynamic evitará o uso dos MultiMethods. Esta palavra chave informará ao compilador que o método somente deverá ser conhecido em tempo de compilação, também se baseando nos tipos que forem passados à ele.

Ao contrário de grande parte dos tipos do .NET, a keyword dynamic não esta mapeada para algo como System.Dynamic; ao detectar uma variável definida com esta keyword, o compilador efetivamente criará uma variável do tipo System.Object mas, internamente, deverá recorrer à alguma API de DLR para invocar o membro, que talvez possa ser mais performático que Reflection.

Serialização de Propriedades Automáticas

Quando queremos expor uma propriedade, na maioria das vezes existe um campo privado que serve como “repositório” para a informação que é definida ou lida. A propriedade tem o papel de interceptar a leitura e escrita à este campo privado através de blocos get/set.

Para reduzir o trabalho, a partir da versão 3.0 do C#, é disponibilizado uma funcionalidade chamada de Automatic Properties que, por sua vez, nos permite omitir a criação deste campo privado. Na realidade, essa funcionalidade nada mais é do que “açúcar sintático”, já que no momento da compilação, o C# irá injetar o campo privado para armazenar a informação que a propriedade expõe. Como exemplo, imagine que voce cria uma classe com a seguinte definição:

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

No momento da compilação, ela será definida como:

public class Usuario
{
    [CompilerGenerated]
    private string <Nome>k__BackingField;

    public string Nome
    {
        [CompilerGenerated]
        get
        {
            return this.<Nome>k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            this.<Nome>k__BackingField = value;
        }
    }
}

Já vi alguns casos em que esses objetos que fazem uso desta técnica, são marcados com o atributo SerializableAttribute e, como o próprio atributo indica, permitir a serialização do mesmo. Quando um objeto com essas características são expostos através de serviços WCF (talvez quando voce já possuir uma API com essas classes definidas), precisamos de alguns cuidados especiais.

O serializador padrão do WCF é o DataContractSerializer. Esse serializador trabalha em conjunto com os atributos DataContractAttribute e DataMemberAttribute, serializando as propriedades ou campos públicos que são decorados com um desses dois atributos. Esse serializador também suporta classes decoradas com o atributo SerializableAttribute mas, como esse atributo foi desenhado para persistir e reconstituir na íntegra a representação do objeto, todos os campos (privados ou públicos) são serializados. As propriedades aqui são ignoradas.

Ao submeter um objeto com as características que vimos acima para o serializador padrão do WCF, ele persistirá os campos privados, que no nosso caso é o <Nome>k__BackingField, e que na maioria dos casos, não é isso que desejamos. Como exemplo, podemos utilizar o seguinte código para analisar o resultado deste processo:

new DataContractSerializer(typeof(Usuario))
    .WriteObject(
        File.Create(“Usuario.xml”),
        new Usuario() { Nome = “Israel” });

Abaixo temos conteúdo Xml correspondente:

<Usuario xmlns=”…” xmlns:i=”…”>
  <_x003C_Nome_x003E_k__BackingField>Israel</_x003C_Nome_x003E_k__BackingField>
</Usuario>

Caso voce não possa alterar os atributos que já foram definidos para a classe, uma possibilidade que temos é utilizar o serializador XmlSerializer. Ao contrário do DataContractSerializer, esta classe irá serializar somente as propriedades ou campos públicos. Assim como o exemplo acima, para efetuarmos este teste, podemos utilizar o seguinte código:

new XmlSerializer(typeof(Usuario))
    .Serialize(
        File.Create(“Usuario.xml”),
        new Usuario() { Nome = “Israel” });

E, finalmente, o resultado em Xml:

<?xml version=”1.0″?>
<Usuario xmlns:xsi=”…” xmlns:xsd=”…”>
  <Nome>Israel</Nome>
</Usuario>

O XmlSerializer é utilizado também pelo ASP.NET Web Services (ASMX). Por mais que esta técnica funcione, antes de alterar o serializador padrão do WCF, é importante que voce analise as vantagens e desvantagens da sua utilização e, para isso, poderá recorrer à própria documentação.

A necessidade do casting

Muitas vezes vejo em fóruns alguns trechos de códigos em que o pessoal faz o casting de um controle em outro para acessar uma determinada propriedade. O que quero chamar a atenção aqui é que nem sempre esses castings são necessários e, por menor que seja, efetuá-los sempre tem o seu custo.

Todo controle em ASP.NET herda direta ou indiretamente da classe Control. Essa classe fornece grande parte das propriedades e métodos que todo server-control deve ter. Imagine que dentro de um controle DataBound, como o ListView, voce possui um controle ASP.NET qualquer, e queira definir a sua propriedade Visible como False. Para exemplificar, notem que abaixo estou procurando pelo controle “Calendar1” através do método FindControl. Com o retorno deste método (que é um objeto derivado da classe Control) eu faço o casting para o controle Calendar e, consequentemente, defino a propriedade Visible como False.

protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    if (e.Item.ItemType == ListViewItemType.DataItem)
    {
        ((Calendar)e.Item.FindControl(“Calendar1”)).Visible = false;
    }
}

Como dito anteriormente, a propriedade Visible está definida na classe Control, e com isso não há necessidade de efetuar o casting para acessá-la. Voce só precisa efetuar o casting caso queira acessar uma propriedade exclusiva do controle. Para finalizar, abaixo temos o mesmo código sem o casting, e tendo o resultado conforme o esperado:

protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    if (e.Item.ItemType == ListViewItemType.DataItem)
    {
        e.Item.FindControl(“Calendar1”).Visible = false;
    }
}

Algumas novidades interessantes

A versão CTP do Visual Studio 2010 com o .NET Framework 4.0 já está disponível, assim como o Soma Somasegar disse neste post. Olhando superficialmente, há algumas funcionalidades que achei bastante interessantes, que quero listar aqui:

  • Code-snippet para HTML.
  • ClientIDMode: Nova propriedade que está contida nos controles ASP.NET, dando-nos a possibilidade de definir como renderizar o ID dos controles.
  • Gráficos: Agora temos nativamente um controle chamado Chart, mas que pode também ser utilizado em conjunto com o Visual Studio 2008 e .NET Framework 3.5. Download: Controles, VS.NET Toolbox (Add-On) e Documentação.
  • Web.config: Possibilidade de criar/transformar o seu arquivo Web.config para diversos estágios do desenvolvimento (Debug/Staging/Release) que, na maioria das vezes, as configurações mudam em cada uma dessas fases.
  • PIA – Primary Interop Assemblies: Quando adicionamos uma referencia a algum componento COM, era criado um Assembly de interoperabilidade em nosso projeto. Esse Assembly apenas contém a estrutura do componente não gerenciado e, que devemos distribuir juntamente com a aplicação onde ele foi referenciado. Com o Visual Studio 2010, podemos embutir esses tipos no Assembly da aplicação/DLL onde o componente está sendo referenciado, sem a necessidade da criação de um Assembly a parte.
  • Computação Paralela: Até então chamada de Parallel Extensions, agora ela foi incorporada dentro do .NET Framework.
  • VB.NET – Propriedades Automáticas: Assim como no C#, o VB.NET agora suporta propriedades automáticas. A sintaxe para isso é: Public Property Nome As String.
  • C# – Parametros Opcionais: Assim como nas versões do Visual Basic, o C# agora passa a suportar parametros opcionais e, assim como no VB, é necessário especificar um valor padrão. A sintaxe para isso é: public void Teste(string nome, int valor = -1){ }.
  • C# – Tipos Dinamicos: Assim como Charlie Calvert comentou aqui há algum tempo, o C# agora terá uma keyword chamada dynamic. Ao declarar uma variável como dinamica, ela suportará a chamada de membros e, a verificação se eles existem ou não, somente acontecerá em tempo de execução. Isso também é conhecido como late-binding.

A facilidade dos Extensions Methods

Os Extensions Methods são novidades do C# 3.0, novidade que veio junto ao .NET Framework 3.5. Eles tornam a programação muito mais simples e intuitiva, como podemos notar abaixo:

//Adicionando dias, contemplando apenas os dias úteis.
DateTime data = DateTime.Now.AddWorkDays(3);

//Adicionando dias, contemplando apenas dias úteis e definindo uma condição
//que determina se o dia inicial deve estar contemplado no cálculo.
//DateTime data = DateTime.Now.AddWorkDays(3, d => d.Hour > 12);

//Verificando se é ou não feriado.
DateTime temp = new DateTime(2008, 12, 25);
Console.WriteLine(temp.IsHoliday());

Obviamente que os feriados estão definindo em hard-code, mas que isso poderia ser buscado em uma tabela do banco de dados ou até mesmo em um arquivo de configuração. Eis aqui o código do exemplo.

Cadê o Intellisense?

Estou fazendo alguns testes com o LINQ e, ao tentar fazer uma query mais completa, notei que o Intellisense do VB.NET não mostra os membros do tipo que foi inferido na variável “i”. Se coloco o mouse em cima da mesma, ela me mostra o tipo correto (ItemDePedido), mas o Intellisense não consegue exibí-la, ao contrário do C#. Através das imagens abaixo podemos comparar a diferença:

Update: Lisa Feigenbaum respondeu ao post: Thank you for reporting this issue. We have reproduced in-house, and it is in fact a bug in intelliSense. We have filed this in our database to consider for the next release.

Lambda Expressions no VB.NET

Estive vendo como funcionam as Lambda Expressions no VB.NET. Para testar, criei uma instancia da classe List(Of T) e adicionei nomes dentro dela. Em seguida, utilizei o método ForEach para iterar por essa coleção, onde em cada item eu gostaria de escreve-lo na tela. Inicialmente o código foi:

Dim nomes As New List(Of String)
nomes.Add(“Israel”)
nomes.Add(“Claudia”)
nomes.Add(“Juliano”)
nomes.Add(“Virginia”)
nomes.ForEach(Function(n) Console.WriteLine(n))

Ao compilar, aparece a seguinte mensagem de erro: Expression does not produce a value. O que aparentemente faz sentido. No Visual Basic, quando queremos que um método retorne um valor, então o criamos como Function. O comportamento desta keyword nas Lambda Expressions tem o mesmo comportamento, ou seja, obrigatoriamente ela precisa retornar algum valor que, neste caso, não ocorre. Se, ao invés de utilizar o método ForEach, utilizar o método Find que, por sua vez, retorna o nome caso o mesmo seja encontrado dentro da coleção, então eu poderia fazer o uso da Lambda Expressions sem problemas:

Dim resultado = nomes.Find(Function(n) n = “Israel”)

Há uma alternativa para utilizar uma Lambda Expression para o método ForEach e outros métodos que não retornam valor mas, na minha opinião, perde toda a elegancia destas expressões. Exemplo:

nomes.ForEach(Function(n) Write(n))

Function Write(ByVal nome As String) As String
    Console.WriteLine(nome)
    Return Nothing
End Function

Já no C#, podemos utilizar o operador => para ambos os casos:

nomes.ForEach(n => Console.WriteLine(n));
var resultado = nomes.Find(n => n == “Israel”);

Por dentro da Base Class Library

A Base Classe Library (também conhecida como BCL) é um conjunto de classes que o .NET disponibiliza para todas as linguagens que rodam sob o .NET Framework. Essa base encapsula várias funcionalidades que tornam o trabalho dos desenvolvedores muito mais fácil. As classes contidas dentro da BCL é comum para qualquer tipo de aplicação, ou seja, independentemente de tecnologia (ASP.NET, Windows Forns, WPF, etc.), você poderá consumir essas classes que, representam tarefas que são comumente utilizadas. A imagem abaixo exibe onde a BCL está encaixada dentro da plataforma .NET.

Figura 1Base Class Library (BCL).

A versão 2.0 adicionou novas tipos e namespaces, enriquecendo ainda mais esta estrutura. Essas classes vão desde novas coleções (tipadas) até novos namespaces, como é o caso do System.Transactions. Apesar do .NET Framework estar em sua versão 3.5, ele utiliza o .NET 2.0 como seu núcleo. A figura abaixo ilustra perfeitamente a posição do .NET 2.0 dentro do .NET 3.X.

Figura 2 – Gráfico que exibe a posição do .NET 2.0.

A BCL é composta por vários namespaces e, através dos capítulos abaixo, veremos detalhadamente cada um dos principais deles. A idéia é abordar o conteúdo mais útil ao dia-à-dia, mostrando exemplos em Visual Basic .NET e Visual C#. Sendo assim, nem todas as classes/funcionalidades serão cobertas aqui mas, para isso, poderá recorrer ao MSDN Library.

ATENÇÃO: Os arquivos estão em formato XPS. Caso não tenha o visualizador, você poderá baixá-lo aqui.

Conteúdo

  • Capítulo 1 – Tipos de dados e Interfaces Este capítulo abordará a arquitetura de tipos fornecido pelo .NET Framework, onde na primeira parte do capítulo, será abordado os tipos padrões padrões e veremos como identificar se trata-se de um tipo valor ou referência. Além disso, analisaremos um problema grave, deixado de lado por muitos desenvolvedores, que é a questão do boxing e unboxing. Ainda nessa primeira parte, analisaremos alguns novos tipos introduzidos nesta versão do .NET Framework, em principal, os Generics. Na segunda e última parte do mesmo, vamos abordar as várias Interfaces que estão disponíveis para serem implementados em tipos customizados, fornecendo funcionalidades adicionais ao tipo criado.

  • Capítulo 2 – Trabalhando com Coleções As coleções são componentes importantes em qualquer tipo de aplicação e, para isso, esse capítulo abordará extensamente o uso das mesmas, começando pelas coleções primárias, fornecidas desde as primeiras versões do .NET Framework até as novas coleções, introduzidas na versão 2.0 do .NET Framework, quais fazem uso dos Generics. Além das coleções, analisaremos as Interfaces disponíveis para podermos estender as funcionalidades existentes e customizarmos para o nosso cenário.
  • Capítulo 3 – Utilização de Assemblies Um Assembly é a menor unidade de reutilização, segurança e controle de versão. O Assembly é algo importante que deve ser analisado cuidadosamente, pois toda aplicação .NET depois de compilada gerará um Assembly. Este capítulo abordará a sua criação desde um utilitário de linha de comando até o Visual Studio .NET. Além disso, abordaremos também outros assuntos relacionados a Assemblies, como por exemplo, strong names, GAC (Global Assembly Cache), instaladores e arquivos de configuração.
  • Capítulo 4 – Monitoramento e depuração de aplicações Toda e qualquer aplicação necessita de algum tipo de monitoramento de seu código para detectar possíveis problemas que possam acontecer e que devem ser analisados. O .NET Framework fornece várias classes que ajudam nesse monitoramento e, este capítulo, é responsável por apresentar essas classes que vão desde a manipulação do Event Log do Windows até classes que interagem com o WMI – Windows Management Instrumentation.
  • Capítulo 5 – Manipulando o sistema de arquivos Grande parte das aplicações comerciais que temos atualmente manipulam arquivos. Esses arquivos são arquivos de bancos, arquivos de parceiros e fornecedores que servem para troca de informações. Enquanto os XML Web Services ainda não são uma realidade para muitas empresas, a manipulação de arquivos e seus respectivos conteúdos é ainda muito utilizado. Tendo esse cenário, o capítulo em questão abordará as principais classes contidas dentro do namespace System.IO para exemplificar e facilitar a manipulação de arquivos do disco e streams de dados.
  • Capítulo 6 – Serialização A serialização de dados é cada dia mais utilizada em aplicações. Por mais que isso aconteça nos bastidores, esse capítulo abordará desde o seu conceito até como implementá-la; e ainda, em seus diversos formatos, utilizando as classes fornecidas pelo .NET Framework 2.0. Além disso, analisaremos classes e Interfaces que temos disponíveis, que proporcionaram o processo de serialização e deserialização mais flexível, onde podemos customizar e interceptar cada um desses processos de acordo com a nossa necessidade.
  • Capítulo 7 – Globalização de Aplicações Cada vez mais se desenvolve softwares que podem ser acessados por várias pessoas de diferentes idiomas e de diferentes locais do mundo. Tendo esse cenário, é importante que a aplicação que estamos desenvolvendo seja possível ao usuário poder customizar o idioma que deseja visualizar os dados e ainda, poder criar a aplicação independente de qualquer cultura. Essa capítulo tem justamente essa finalidade, ou seja, de exibir o que o .NET Framework é capaz de fazer para atender essa necessidade que, torna-se cada vez mais comum.
  • Capítulo 8 – Criptografia Criptografia de dados é um ponto muito importante nos mais diversos tipos de aplicações. Geralmente, em aplicações onde alguns dos dados são muito sigilosos, como é o caso de aplicações financeiras, quais mantém os dados de seus clientes, é necessário que se mantenha esses dados seguros pois, se esses dados cairem em mãos erradas, essas pessoas com más intenções, não consigam entender e/ou recuperar esses dados em sua forma legível. Esse capítulo abordará extensamente as classes responsáveis por criptografia e hashing que o .NET Framework disponiliza, bem como utilizá-las e como aplicá-las ao dia-à-dia.
  • Capítulo 9 – Utilizando Code Access Security – CAS Toda aplicação que utiliza o Common Language Runtime (CLR) obrigatoriamente deve interagir com o sistema de segurança do mesmo. Quando a aplicação é executada, automaticamente é avaliado se ela tem ou não determinados privilégios. Dependendo das permissões que a aplicação tem, ela poderá rodar perfeitamente ou gerar erros relacionados a segurança. Code Access Security (também conhecido como CAS), é um mecanismo que ajuda limitar/conceder o acesso que o código que está querendo realizar, protegendo recursos e operações. Este capítulo abordará como utilizar o CAS, que é fornecido juntamente com o SDK do .NET Framework e, como configurar devidamente a aplicação para evitar problemas relacionados a segurança.
  • Capítulo 10 – Envio de Mensagens (E-mails) Envio de e-mails é muito comum em qualquer tipo de aplicação, seja ela uma aplicação para internet, uma aplicação para Windows ou até mesmo serviços que rodam sem uma intervenção do usuário. O .NET Framework fornece um namespace contendo classes e muitos outros tipos que podemos utilizar nas aplicação para habilitar o envio de e-mails e, conseqüentemente, torná-las muito mais dinâmicas e inteligentes.
  • Capítulo 11 – Criando Serviços do Windows Os Serviços do Windows (Windows Services), permitem-nos criar aplicações que rodam em “background” no sistema operacional. Estes serviços podem ser automaticamente inicializados quando o sistema operacional inicializar, podendo ainda ser pausado e reinicializado, sem apresentar nenhuma interface com o usuário. Esses serviços são ideais para ser usado em servidores ou em funcionalidades de longa duração que necessitem ser executadas de forma totalmente independente, sem a intervenção de um usuário. O capítulo corrente abordará desde a sua criação, depuração e instalação do mesmo.
  • Capítulo 12 – Interoperabilidade com componentes COM A Microsoft criou a plataforma .NET e, em pouco tempo, essa plataforma foi adotada por muitas e muitas empresas. Algo importante é que muitas dessas empresas, já tinham componentes COM que eram utilizados em massa nas aplicações e que são inviáveis para serem reescritos imediatamente. Felizmente a Microsoft pensou no legado e possibilita a interoperabilidade de componentes COM, interagindo com aplicações baseadas na plataforma .NET e vice-versa. Este capítulo mostrará os passos necessários para efetuar essa interoperabilidade entre as novas aplicações e o que já existe em código legado.
  • Capítulo 13 – Reflection Reflection é a habilidade de extrair informações de metadados de um determinado tipo, ou seja, quais parâmetros, métodos, entre outros membros um determinado tipo possui. Isso torna a aplicação bastante flexível, onde podemos extrair informações necessárias para podermos customizar e automatizar a criação de ferramentas e utilitários que auxiliam os próprios desenvolvedores. Além disso, permite a criação em runtime de Assemblies e como instanciar classes via programação. Esse capítulo propõe-se a explicar como criar esse tipo de funcionalidade dentro da aplicação.
  • Capítulo 14 – Threading A criação de threads permitem aumentar consideravelmente a performance das aplicações. Elas fornecem a habilidade de conseguirmos delegar processamentos em diversas unidades de execução, aumentando a capacidade de processamento de uma aplicação. Mas utilizando isso de forma errada, poderá piorar ao invés de melhorar, consumindo mais recursos do que o necessário, tendo um comportamento inesperado e retornando valores diferentes do esperado. O .NET Framework fornece várias classes que podemos utilizar para criação e gerenciamento de threads, bloqueio de recursos em um ambiente multi-threading e sincronização. Este capítulo irá ajudá-lo a conhecer alguns problemas existentes em aplicações que fazem o uso de threads e como contorná-los.

Referências Bibliográficas

  • Code Complete – Second Edition
    Autor: Steve McConnell
    Editora: Microsoft Press
    ISBN: 0-7356-1967-0
  • Writing Secure Code – Second Edition
    Autores: Michael Howard e David LeBlanc
    Editora: Microsoft Press
    ISBN: 0-7356-1722-8
  • CLR via C# – Second Edition
    Autor: Jeffrey Richter
    Editora: Microsoft Press
    ISBN: 0-7356-2163-2
  • Programming Visual C# 2005: The Language
    Autor: Donis Marshall
    Editora Microsoft Press
    ISBN: 0-7356-2181-0
  • Expressões Regulares – Uma abordagem divertida
    Autor: Aurélio Marinho Jargas
    Editora: Novatec
    ISBN: 85-7522-100-0
  • Collection 5160: Core Development with Microsoft .NET Framework 2.0
    Autor/Editor: Microsoft
  • Collection 5161: Advanced Development with Microsoft .NET Framework 2.0
    Autor/Editor: Microsoft