Primeiras aulas do curso C# Reflection parte 1: Metadados do seu código .NET

C# Reflection parte 1: Metadados do seu código .NET

O pontapé de nossa aplicação Web - Introdução

Olá! Meu nome é Guilherme, e neste curso nós aprenderemos Reflection no .NET e C#. Nós criaremos um projeto web para o banco ByteBank, o que pode te fazer pensar em ASP.NET ou ASP.NET MVC, bastante recorrentes. Mas neste caso, iremos criar nosso próprio framework utilizando o Reflection.

Com isso, criaremos o portal em que os clientes do banco poderão visitar, além de permitir aos potencias clientes conhecerem os serviços oferecidos peplo Bytebank. Construiremos, ainda, algumas páginas interessantes que realizam cálculo cambial.

Ao final, terminaremos nosso projeto com uma página que possui URL bem legível para o usuário: localhost:5341/Cambio/Calculo?valor=10&moedaDestiono=USD&moedaOrigem=BRL.

Construiremos um código que irá mapear rotas automaticamente. E o que isso quer dizer? Usaremos a URL citada e redirecionaremos o usuário para a classe que criamos de forma dinâmica, desta forma, não precisaremos usar um monte de condicionais.

Vamos lidar com situações complexas, por exemplo, observem que o nosso método Calculo() possui diversas sobrecargas; uma com um argumento e outra com dois argumentos.

public string Calculo(string moedaDestino, decimal valor) => 
    Calculo("BRL", moedaDestino,valor);

public string Calculo(string moedaDestino) =>
    Calculo("BRL", moedaDestino, 1);

Caso seja retirado um desses argumentos, a nossa aplicação terá a habilidade de resolver automaticamente o problema.

Passaremos por conceitos de Assembly, app domain no .NET e aprenderemos como são representados seus métodos, construtores e propriedades. Veremos como utilizar estas representações de um tipo dentro do .NET, para recuperar informações sobre objetos de forma dinâmica; como podemos criar uma instância de um objeto, dinamicamente, sabendo apenas seu nome.

Faremos um projeto bem rico que não visitará somente as classes que criamos, mas também o conteúdo estático, como as páginas HTML que estamos utilizando para retornar ao usuário.

Aprenderemos muito conteúdo nesta primeira parte do curso e daremos prosseguimento na segunda parte.

O pontapé de nossa aplicação Web - Começando o nosso projeto

Nesta aula, faremos o papel de desenvolvedores do banco Bytebank, que por sinal, não possui um site ou portal. Sem este recurso, os clientes do banco não podem acessar suas contas e a divulgação do banco para potenciais clientes fica prejudicada. Portanto, a nossa tarefa é criar este portal.

Nós não trabalharemos com o design ou layout, focaremos apenas nas páginas e realizaremos um mock para construir a infraestrutura do site.

Para o nosso portal, temos algumas páginas definidas: é necessário que haja uma página que exiba os cartões de crédito e débito.

Uma outra necessidade é exibir o cálculo cambial, ou seja, as conversões de uma moeda nacional para outra. No caso, trabalharemos com o peso mexicano (MXN) e o dólar americano (USD).

Por último, teremos que estruturar a nossa home page .

/Cartoes/Credito
/Cartoes/Debito

/Cambio/MXN
/Cambio/Index

Já possuímos um diretório que contém as pastas das respectivas páginas ainda bem simples, apenas para testarmos a infraestrutura do site.

No Visual Studio, criaremos um novo projeto no formato Console App do .NET framework. Salvaremos no diretório ByteBank.Portal, que será o nome do projeto.

Já temos uma pasta com os recursos que usaremos para desenvolver o site, como View , Home e Cambio. E o que é muito importante para que um site funcione: os recursos de CSS, para o estilo, e JS, que permitirá uma interação mais interessante no portal.

Os recursos estão disponíveis para download nas atividades do curso.

Copiaremos a raiz do diretório para a raiz do projeto no Visual Studio de forma que todos os arquivos necessários foram adicionados.

O pontapé de nossa aplicação Web - Escrevendo o código de suporte http

Vamos começar a escrever nosso código. Primeiramente, criaremos um diretório na raiz do nosso projeto que chamaremos de Infraestrutura. Daremos esse nome, porque não se trata de um código relacionado ao conteúdo ou ao banco Bytebank, e sim, de uma estrutura para lidar com a rede e responder as requisições necessárias.

pasta infraestrutura

Dentro da pasta Infraestrutura, criaremos uma classe que receberá o nome WebApplication, afinal, estamos trabalhando em uma aplicação web. Feito isso, adicionaremos o modificador public à classe. Escreveremos, ainda, o método principal cujo nome será Iniciar()

namespace ByteBank.Portal.Infraestrutura
{ 
    public class WebApplication
    {
        public void Iniciar() 
        {

        }
    }
}

Quando a aplicação web criada começar a receber requisições na rede, chamaremos o método Iniciar(), portanto, ele será colocado em nossa classe principal (Program.cs). Criaremos uma variável para armazenar a instância de uma new WebApplication(). O Visual Studo sublinhará o termo, indicando um erro. Por isso, acionaremos o atalho "Ctrl + ." para adicionar a diretiva do using.

Em seguida, chamaremos o método Iniciar().

using.ByteBank.Portal.Infraestrutura;

namespace ByteBank.Portal
{
    class Program
    {
        static void Main(string[] args)
        {
            var webApplication = new WebApplication();
            webApplication.Iniciar();
        }
    }
} 

Iremos implementar o método Iniciar(). Estamos lidando com a rede, ou seja, ficaremos recebendo requisições da rede pelo protocolo http, responsável por trabalhar como a internet. Quando acessamos um site, a URL sempre é formada por "http://" ou "https://".

O .NET fornece uma classe para manipular essas questões de rede, como receber e responder com pacotes e lidar com fluxo de dados que circula pela placa de rede. O nome dessa classe é httpListener, e será adicionada em WebApplication.cs.

A classe httpListener irá ouvir requisições http, colocaremos a diretiva using e o Visual Studio adicionará System.Net;.

Não é por acaso que estamos utilizando nome Iniciar() para nossa aplicação web, pois o httpListener do .NET precisa que se peça a inicialização, portanto usaremos o método Start().

using System.net;

namespace ByteBank.Portal.Infraestrutura
{ 
    public class WebApplication
    {
        public void Iniciar() 
        {
            var httpListener = new HttpListener();

            httpListener.Start();
        }
    }
}

Precisaremos definir qual é o prefixo das URLs que serão acionadas, caso não façamos isso, a nossa instância não saberá o que deverá ser ouvido e aplicado. Como estamos criando uma web application genérica, colocaremos o prefixo da URL como parâmetro. Para isso, criaremos um construtor que terá como parâmetro um array de prefixos.

Criaremos, também, um campo de leitura em nossa classe do tipo array de string, que chamaremos de _prefixos. Citaremos isso no nosso construtor.

using System.net;

namespace ByteBank.Portal.Infraestrutura
{ 
    public class WebApplication
    {
        private readonly string[] _prefixos;

        public WebApplication(string[] prefixos)
        {
            _prefixos = prefixos;
        }

        public void Iniciar() 
        {
            var httpListener = new HttpListerner();

            httpListener.Start();
        }
    }
}

Seguindo as boas práticas de programação, lançaremos uma exceção: se prefixos vier com um valor nulo, lançaremos ArgumentNullException(nameof(prefixos)). nameof é um operador do C#6 que retornará uma string com o nome da variável, ou seja, com o conteúdo de prefixos.

using System.net;

namespace ByteBank.Portal.Infraestrutura
{ 
    public class WebApplication
    {
        private readonly string[] _prefixos;

        public WebApplication(string[] prefixos)
        {
            if (prefixos == null)
                throw new ArgumentNullException(nameof(prefixos));
            _prefixos = prefixos;
        }

        public void Iniciar() 
        {
            var httpListener = new HttpListerner();

            httpListener.Start();
        }
    }
}

Já que alteramos nosso construtor, teremos de realizar modificações em nossa classe principal Program.cs. Primeiramente, criaremos uma nova variável para guardar prefixos. Neste caso, usaremos apenas um: http://. Como ainda estamos na parte de desenvolvimento, usaremos http://localhost:5341.

Feito isso, passaremos prefixos para o construtor WebApplication().

using.ByteBank.Portal.Infraestrutura;

namespace ByteBank.Portal
{
    class Program
    {
        static void Main(string[] args)
        {
            var prefixos = new string[] {"http://localhost:5341/"}; 
            var webApplication = new WebApplication(prefixos);
            webApplication.Iniciar();
        }
    }
} 

De volta ao método Iniciar() em WebApplication.cs, precisaremos especificar que o prefixo a ser escutado pelo HttpListener() é o _prefixos. Iremos varrer todos os prefixos, e para cada um deles em nossa rede _prefixos, ele será adicionado ao httpListener().

using System.net;

namespace ByteBank.Portal.Infraestrutura
{ 
    public class WebApplication
    {
        private readonly string[] _prefixos;

        public WebApplication(string[] prefixos)
        {
            if (prefixos == null)
                throw new ArgumentNullException(nameof(prefixos));
            _prefixos = prefixos;
        }

        public void Iniciar() 
        {
            var httpListener = new HttpListener();

            foreach (var prefixo in _prefixos)

                httpListener.Prefixes.Add(prefixo);

            httpListener.Start();
        }
    }
}

Assim, estamos ouvindo requisições http. No entanto, precisaremos obter o contexto da requisição para obtermos uma resposta. Criaremos uma variável chamada contexto e para acessá-la, temos um método denominado GetContext() no httpListener.

using System.net;

namespace ByteBank.Portal.Infraestrutura
{ 
    public class WebApplication
    {
        private readonly string[] _prefixos;

        public WebApplication(string[] prefixos)
        {
            if (prefixos == null)
                throw new ArgumentNullException(nameof(prefixos));
            _prefixos = prefixos;
        }

        public void Iniciar() 
        {
            var httpListener = new HttpListener();

            foreach (var prefixo in _prefixos)

                httpListener.Prefixes.Add(prefixo);

            httpListener.Start();

            var contexto = httpListener.GetContext();
        }
    }
}

Quando nossa aplicação chega neste ponto ela trava, até que uma requisição seja realizada. Possuímos nosso contexto, mas precisamos nos atentar para dois elementos importantes: um objeto que representa a resposta e outro que representa a requisição em si. Guardaremos os respectivos elementos em duas variáveis, sendo resposta e requisicao.

//...
        public void Iniciar() 
        {
            var httpListener = new HttpListener();

            foreach (var prefixo in _prefixos)

                httpListener.Prefixes.Add(prefixo);

            httpListener.Start();

            var contexto = httpListener.GetContext();
            var requisicao = contexto.Request;
            var resposta = contexto.Response;
        }
    }
}

Estamos apenas testando nossa aplicação, então, adicionaremos alguns elementos default. Iremos definir o tipo de resposta, ou seja, iremos responder com um conteúdo que será um estilo CSS, JavaScript, imagem ou vídeo? Como estamos trabalhando com uma página, nosso conteúdo será html.

Utilizamos a propriedade ContentType para definir conteúdos. ContentType é uma string que definiremos como conteúdo text/html. Diremos, nesta resposta, que o encoding utilizando é charset=utf-8.

        public void Iniciar() 
        {
            var httpListener = new HttpListener();

            foreach (var prefixo in _prefixos)

                httpListener.Prefixes.Add(prefixo);

            httpListener.Start();

            var contexto = httpListener.GetContext();
            var requisicao = contexto.Request;
            var resposta = contexto.Response;

            resposta.ContentType = "text/html; charset=utf-8";
        }

Em seguida, iremos definir que a resposta a ser dada será "Hello World" usando a variável respostaConteudo. Lembrando que estamos apenas realizando um teste, e não retornando um CSS ou página.

        public void Iniciar() 
        {
            var httpListener = new HttpListener();

            foreach (var prefixo in _prefixos)

                httpListener.Prefixes.Add(prefixo);

            httpListener.Start();

            var contexto = httpListener.GetContext();
            var requisicao = contexto.Request;
            var resposta = contexto.Response;

            var respostaConteudo = "Hello Word";

            resposta.ContentType = "text/html; charset=utf-8";
        }

O protocolo http e o objeto httpListener, não trabalham com string pura, e sim, com stream. Mas adiante no curso veremos com detalhes como funciona a stream, que atua com fluxo de dados. Portanto, iremos converter o texto em uma sequência de bytes para que eles sejam devolvidos em um fluxo.

Criaremos uma variável denominada respostaConteudoBytes. Diremos que esta string é representada como utf-8. Acessaremos o Enconding - uma classe no .NET - e chamaremos o método GetBytes(). Com isso, os bytes que representam o texto serão retornados.

        public void Iniciar() 
        {
            var httpListener = new HttpListener();

            foreach (var prefixo in _prefixos)

                httpListener.Prefixes.Add(prefixo);

            httpListener.Start();

            var contexto = httpListener.GetContext();
            var requisicao = contexto.Request;
            var resposta = contexto.Response;

            var respostaConteudo = "Hello Word";
            var respostaConteudoBytes = Encoding.UTF8.GetBytes(respostaConteudo);

            resposta.ContentType = "text/html; charset=utf-8";
        }

Na resposta, já podemos enviar o array de bytes para a rede. Precisaremos definir se o código http foi ouvido com sucesso ou houve erros, como algum problema no servidor. Definiremos o código do status da requisição; escreveremos StatusCode sendo 200, indicando que tudo ocorreu bem.

Definiremos o tamanho na nossa resposta. Acessaremos o ContentLenght64 e a propriedade Length.

        public void Iniciar() 
        {
            var httpListener = new HttpListener();

            foreach (var prefixo in _prefixos)

                httpListener.Prefixes.Add(prefixo);

            httpListener.Start();

            var contexto = httpListener.GetContext();
            var requisicao = contexto.Request;
            var resposta = contexto.Response;

            var respostaConteudo = "Hello Word";
            var respostaConteudoBytes = Encoding.UTF8.GetBytes(respostaConteudo);

            resposta.ContentType = "text/html; charset=utf-8";
            resposta.StatusCode = 200;
            resposta.ContentLength64 = respostaConteudoBytes.Length;


        }

Escreveremos a resposta no stream de saída. Acessaremos resposta e o OutputStream. Usaremos o método Write() que recebe três parâmetros: teremos o array de bytes que será enviado para a rede (respostaConteudoBytes). Como se trata de um array, podemos acessar vários índices e partir de cada um deles podemos pegar um número de bytes indeterminado. Começaremos do índice 0 e pegaremos todos os bytes desse array, acessando novamente a propriedade Lenght.

        public void Iniciar() 
        {
            var httpListener = new HttpListerner();

            foreach (var prefixo in _prefixos)

                httpListener.Prefixes.Add(prefixo);

            httpListener.Start();

            var contexto = httpListener.GetContext();
            var requisicao = contexto.Request;
            var resposta = contexto.Response;

            var respostaConteudo = "Hello Word";
            var respostaConteudoBytes = Encoding.UTF8.GetBytes(respostaConteudo);

            resposta.ContentType = "text/html; charset=utf-8";
            resposta.StatusCode = 200;
            resposta.ContentLength64 = respostaConteudoBytes.Length;

            resposta.OutputStream.Write(respostaConteudoBytes, 0, respostaConteudoBytes.Length);


        }

Terminamos de escrever a resposta, citamos o código de status e especificamos o tipo de conteúdo e seu tamanho. Iremos fechar a stream com o Close().

Terminamos nossa requisição. Fecharemos nosso httpListener utilizando o método Stop().

            httpListener.Start();

            var contexto = httpListener.GetContext();
            var requisicao = contexto.Request;
            var resposta = contexto.Response;

            var respostaConteudo = "Hello Word";
            var respostaConteudoBytes = Encoding.UTF8.GetBytes(respostaConteudo);

            resposta.ContentType = "text/html; charset=utf-8";
            resposta.StatusCode = 200;
            resposta.ContentLength64 = respostaConteudoBytes.Length;

            resposta.OutputStream.Write(respostaConteudoBytes, 0, respostaConteudoBytes.Length);

            resposta.OutputStream.Close();

            httpListener.Stop();


        }

Ao executarmos o programa e colarmos o endereço http://localhost:5341 no navegador, veremos a mensagem "Hello World". A estrutua responsável por estabelecer uma comunicação http com o navegador está funcionando.

Sobre o curso C# Reflection parte 1: Metadados do seu código .NET

O curso C# Reflection parte 1: Metadados do seu código .NET possui 201 minutos de vídeos, em um total de 43 atividades. Gostou? Conheça nossos outros cursos de .NET em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda .NET acessando integralmente esse e outros cursos, comece hoje!

  • 1112 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 1112 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 1112 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 1112 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Procurando planos para empresas?
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos toda semana