sábado, 11 de abril de 2015

O ASP.NET Boilerplate

Vale a pena conhecer o projeto ASP.NET Boilerplate que se diz projetado para ajudar no desenvolvimento de aplicações usando melhores práticas e sem nos repetir (Don’t Repeat Yourself – DRY).
O ASP.NET Boilerplate foi projetado e desenvolvido pelo Halil İbrahim Kalkan que também conta com alguns contribuintes, na página do projeto do GitHub é possível reparar que há uma boa dedicação através dos commits:

O projeto tem os princípios [3] de:
1. Ser modularizado através de pacotes que possam ser facilmente compartilhados preferencialmente através do Nuget
2. Seguir melhores práticas para ter código mais entendível e extensível
3. Código Base Escalável mantendo um código fácil de ser mantido, principalmente utilizando camadas e modularização
4. Combinar e usar bibliotecas e frameworks para realizar tarefas bem conhecidas, evitando reinventar as horas
5. Assuntos transversais como autorização, validação, manipulação de erros, fazer log e fazer cache são tarefas comuns para todas aplicações
6. Mais automação no que for possível como migração de banco de dados, testes unitários e distribuição
7. Convenção de configuração para facilitar definições padrões e especificar diferenças
8. Inicialização de novos projetos fácil e rápida
Para aprender detalhes sobre o projeto o Kalkan criou vários artigos no CodeProject passando mais informações [4] [5] [6] e uma boa documentação [7]

NLayer (Multicamadas)


Fonte : http://aspnetboilerplate.com/Pages/Documents/NLayer-Architecture acesso em 4/4/2015
1. Infrastructure Layer
a. Entity Framework ou NHibernate
b. Repositório para abstrair a dependência do Entity Framework
2. Domain Layer
a. Entities (Entidades)
classe base para toda entidade de domínio e que há heranças e interfaces para implementação de auditoria de criação, alteração
b. Repositories (Repositórios)
"Intermediação entre a camada de domínio e de mapeamento de dados, usando uma interface do tipo de coleção para acessar objetos de domínio" (Martin Folwer) Tradução livre do autor deste artigo
O ASP.NET Boilerplate implementa interfaces e classes bases para diminuir, ainda assim é possível criar repositórios customizados.
As conexões a dados e as transações são controladas por UnitOfWork (Unidades de trabalho) [8]
c. Unit of Work (Unidade de Trabalho)
Automatismos para controle de conexão, transação. Há ainda a opção de programar eventos da unidade de trabalho para Completed, Failed e Disposed.
d. Domain Events & EventBus(Eventos de Domínio)
Num desenvolvimento winforms é possível criar eventos em classes e utiliza-los durante a instância da class na aplicação. No desenvolvimento web como os objetos tem pequena duração, já que é durante apenas a requisição, a programação de eventos é feita através do EventBus, que é um objeto singleton e compartilhado entre todas outras classes.
3. Application Layer
a. Serviços de Aplicação (Application Services)
Utilizado para expor lógica de domínio para a camada de apresentação. Utiliza a injeção de dependência e Unidade de Trabalho para apoiar nos serviços a serem expostos. Todo serviço da aplicação, diferentemente do repositório, deve ser explicitamente criado herdando da interface IApplicationService .
b. Data Transfer Objects (Objetos de transferência de dados)
Utilizados para transferir dados da camada de aplicação para a camada de apresentação. A documentação [9] sobre DTO ainda explica os benefícios de não expor diretamente o domínio na camada de aplicação, como facilidade de refatoração. Ainda é mostrado a utilização do AutoMapper
c. Validação de DTO
Há várias validações para o InputDTO (Objeto de Transferência de dados de entrada), utilizado como entrada de métodos de serviço de aplicação, por DataAnnotations (System.ComponentModel.DataAnnotations namespace). Ainda é possível implementar a interface ICustomValidate para uma validação mais complexa. Há também a interface IShouldNormalize para normalizar o InputDTO antes da utilização nos métodos.
4. Web
5. Presentation Layer
a. Dynamic Web API Layer
O ASP.NET Boilerplate pode criar dinamicamente serviços web api baseados nos serviços de aplicação. Também é criado proxies javascript dinamicamente para acesso aos serviços. [10]
b. Javascript API
O ASPNET Boilerplate utiliza várias APIs para facilitar o desenvolvimento de javascripts:
  1. Ajax
  2. Notification
  3. Message
  4. UI Block / Busy
  5. Logging
c. Localization
d. Navigation
O ASP.NET Boilerplate permite a criação de menu nos módulos de servidores e são reutilizados no cliente com a criação de API javascript dinamicamente [11]
e. Handling exceptions
f. Embedded resource files

Injeção de dependências (Dependency Injection)

O ASP.NET Boilerplate implementa a injeção de dependências através do Castle Windsor, e há na documentação [12] uma explicação dos benefícios de se utilizar através da injeção por construtor (quando a dependência é obrigatória na utilização de toda a classe) ou injeção por propriedade (quando a dependência é opcional e pode ser desabilitada por padrão, nos exemplos de logs). A Injeção de dependência ainda facilita a aplicação de testes unitários.

Log

O ASP.NET Boilerplace utiliza a injeção de dependência e a interface ILogger do Castle. Por padrão é utilizado o Log4Net.

ASP.NET Boilerplate e o Nuget

O ASP.NET Boilerplace é distribuído através do nuget. Além da Framework, há o Module Zero(para autorização, usuários, perfis e o Test Base (para criar testes unitários e de integração)

Criando a aplicação de um modelo

Esta parte do artigo é uma versão otimizada e baseada nos artigos do Kalkan [4] [5]
Para iniciar a aplicação visite a página de modelos. A primeira opção é entre SPA (Single Page Application, Aplicação de página única com AngularJS ou Durandal) e MPA (Multiple Page Application, aplicação de páginas múltiplas com o MVC).
Após isso é possível escolher o ORM entre Entity Framework ou NHibernate.
Escolha um nome para a aplicação, como AplicacoesWeb e clique em “Create My Project”.
O arquivo baixado está em formato Zip e ao baixa-lo e descompacta-lo ele terá a seguinte estrutura:

Crie a base de dados “AplicacoesWeb” num SQL Server 2008 ou posterior em instância padrão, ou modifique a conexão padrão no web.config.
Abra o projeto no Visual Studio 2013 e aperte F5. A aplicação será iniciada e um navegador será aberto.
Se acontecer o erro abaixo (A project with an Output Type of Class Library cannot be started)
Selecione o projeto “AplicacoesWeb.Web” e o defina como projeto de inicialização (Set as StartUp Project)

Criando as entidades

No projeto AplicacoesWeb.Core crie as classes de Domínio Task (Tarefa), Person (Pessoa) e o enumerado TaskState (Estado da tarefa).

Criando os repositórios

O ASP.NET Bolierplate já implementa repositórios padrões para toda entidade, mas adicionaremos um repositório padrão para cada entidade

Camada de Infraestrutura

ASP.NET Boilerplate template criou um DbContext com o nome AplicacoesWebDbContext para nos ajudar. Basta agora adicionar os IDbSets para Task e Person.

Migração (No caso, a criação da base de dados inicial)

Vamos utilizar o método Configuration.Seed para adicionar alguns registros para a tabela People.
Para criar a migração atualizando a base de dados conforme classes dos nossos domínios, abra o Package Manager Console, configure o projeto padrão como AplicacoesWeb.EntityFramework e execute o comando “add-migration InitialCreate” conforme print abaixo:

Uma classe é criada na pasta Migrations e para persistir as alterações na base de dados, basta executar o comando “update-database”, adicione o parâmetro opcional –verbose caso queira ver os comandos que estão sendo executados (O que é muito útil para identificar problemas):

 Ao executar o comando anterior com sucesso, as tabelas foram criadas na base de dados:

Implementação de Repositórios

Devemos implementar a interface ITaskRepository, e para isso criamos a classe TaskRepository, descendendo de no projeto AplicacoesWeb.EntityFramework e na pasta EntityFramework/Repositories.

Camada de Aplicação

A camada de aplicação deve implementar todos os serviços que serão expostos para a camada de apresentação. Para isso, crie todas estas classes e interfaces:
  • CreateTaskInput
  • GetAllPeopleOutput
  • GetTasksInput
  • GetTasksOutput
  • IPersonAppService
  • ITaskAppService
  • PersonAppService
  • PersonDto
  • TaskAppService
  • TaskDto
  • UpdateTaskInput

WebApi Controller Dinâmicos

Os serviços de aplicativos são consumidos pela camada de apresentação. Em um aplicativo de página única (SPA – Single Page Application), todas os dados são enviados e recebidas usando AJAX entre javascript e o servidor. ABP simplifica a chamada a um método de serviço de aplicação criando o WebApi Controller dinamicamente e o proxy javascript na aplicação
Com esse código é o serviço de Task e de Person está exposto:
DynamicApiControllerBuilder .ForAll<IApplicationService>(typeof(AplicacoesWebApplicationModule).Assembly, "app").Build();.

Camada de Apresentação

Criar a pasta:
AplicacoesWeb.Web\App\Main\views\task\
Adicionar os arquivos
task\list.cshtml
task\list.js
task\new.cshtml
task\new.js
Adicionar o menu no método AplicacoesWebNavigationProvider. SetNavigation as chamadas para o novo menu.
Adicionar as novas localizações para os novos menus no “AplicacoesWeb.xml”

Fonte final:

Veja o fonte final:
https://github.com/mqueirozcorreia/aspnetboilerplatePTSample/

Referências

1. http://blogs.msdn.com/b/webdev/archive/2014/05/13/asp-net-vnext-the-future-of-net-on-the-server.aspx
2. https://www.devbridge.com/articles/entity-framework-6-vs-nhibernate-4/
3. http://aspnetboilerplate.com/About
4. http://www.codeproject.com/Articles/768664/Introduction-to-ASP-NET-Boilerplate
5. http://www.codeproject.com/Articles/791740/Using-AngularJs-ASP-NET-MVC-Web-API-and-EntityFram
6. http://www.codeproject.com/Articles/871786/Unit-testing-in-Csharp-using-xUnit-Entity-Framewor
7. http://aspnetboilerplate.com/Pages/Documents
8. http://aspnetboilerplate.com/Pages/Documents/Unit-Of-Work
9. http://aspnetboilerplate.com/Pages/Documents/Data-Transfer-Objects
10. http://aspnetboilerplate.com/Pages/Documents/Dynamic-Web-API
11. http://aspnetboilerplate.com/Pages/Documents/Navigation
12. http://aspnetboilerplate.com/Pages/Documents/Dependency-Injection
13. http://aspnetboilerplate.com/