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:
- Ajax
- Notification
- Message
- UI Block / Busy
- 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/