-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Ferramentas necessárias:
- Visual Studio 2017/2019 ou Visual Studio Code
Crie uma aplicação web por meio do Visual Studio. Os seguintes frameworks são compatíveis:
- Net Framework 4.6.1
- Net Core 2.1
- Net Core 2.2
Adicione a referencia do pacote ao seu projeto por meio do gerenciador de pacotes do nuget
Install-Package Fluent.Architecture.Core
Install-Package Fluent.Architecture.EntityFramework
Escolha os pacotes abaixo de acordo com os bancos de dados a serem usados na aplicação:
Install-Package Fluent.Architecture.EntityFramework.MySQL
Install-Package Fluent.Architecture.EntityFramework.Oracle
Install-Package Fluent.Architecture.EntityFramework.PostgreSQL
Install-Package Fluent.Architecture.EntityFramework.SqlServer
Crie uma classe que será responsável pela inicialização da arquitetura, conforme exemplo abaixo:
using Fluent.Architecture;
using Fluent.Architecture.EntityFramework;
using Fluent.Architecture.EntityFramework.PostgreSQL;
using System;
using Fluent.Architecture;
using Fluent.Architecture.EntityFramework;
using Fluent.Architecture.EntityFramework.MySQL;
using System;
public class ArchitectureInit
{
public static void Setup(IServiceProvider serviceProvider)
{
Fluent.Architecture.Setup
.Init()
.SetServiceProvider(serviceProvider)
.UseEntityFramework()
.AddConnectionString("Server=localhost;Database=testDb;Uid=root;Pwd=admin;", createDatabaseIfNotExists: true, typeof(EfContextMySQL))
.Build()
.Run();
}
}À partir do Startup de sua aplicação, inicialize a arquitetura:
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
Inicializacao.Inicialize(app.ApplicationServices); //A inicialização da arquitetura
}
...public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
Inicializacao.Inicialize(null); //A inicialização da arquitetura
}
}Crie uma entidade:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Fluent.Architecture.Attributes;
using Fluent.Architecture.Entities;
using Fluent.Architecture.EntityFramework;
[Table("Users"), DbType(FluentDbType.MYSQL)]
public class User : FluentEntity
{
[Key]
public int Code { get; set; }
[FluentUniqueKey]
public string Email { get; set; }
public string Name { get; set; }
}Note que usamos o atributo Table para indicar o nome da tabela do banco de dados e o atributo DbType para indicar o tipo de banco de dados a ser usado por essa entidade. Uma entidade sempre deve ser criada para um tipo de banco de dados específico. Em casos em que se deseja criar um Model e não uma entidade, deve se tratar de forma um pouco diferente. Veja mais em: Entidade
Crie um controller conforme abaixo:
using Fluent.Architecture.Controllers;
using Microsoft.AspNetCore.Mvc;
[Route("api/[Controller]")]
public class UserController : FluentController<User>
{
// GET api/controller?code=123
[HttpGet]
public User Find([FromQuery] User entity)
{
return Service.Find(entity);
}
// GET api/controller/Count
[HttpGet("Count")]
public object Count()
{
return Service.Count();
}
// POST api/controller
[HttpPost]
public User Add([FromBody] User entity)
{
return Service.Add(entity);
}
// PUT api/controller
[HttpPut]
public User Update([FromBody] User entity)
{
return Service.Update(entity);
}
// DELETE api/controller
[HttpDelete]
public User Remove([FromBody] User entity)
{
return Service.Remove(entity);
}
// DELETE api/controller/RemoveRange
[HttpDelete("RemoveRange")]
public void RemoveRange([FromBody] User[] entidades)
{
Service.RemoveRange(entidades);
}
}Todos os métodos do controller estão prontos para serem executados. Execute a aplicação e teste os métodos. Baixe o template o template do link abaixo e importe no seu postman para facilitar os testes. Template para importação
Crie uma especificação de consulta
using System;
using System.Linq;
using Fluent.Architecture.Specifications;
public class UserByEmailSpec : FluentSpecification<User>
{
public string Email { get; set; }
public UserByEmailSpec AddParameter(string email)
{
Email = email;
return this;
}
public override IQueryable<User> Where(IQueryable<User> query)
{
return query.Where(x => x.Email.Equals(Email, StringComparison.InvariantCultureIgnoreCase));
}
public override IOrderedQueryable<User> Order(IQueryable<User> query)
{
return query.OrderBy(x => x.Name);
}
}Uma especificação define um modelo de consulta e pode ser utilizada em vários métodos do FluentService<>.
Adicione esse novo método ao seu controller:
[HttpGet("GetUserByEMail")]
public User GetUserByEMail(string email)
{
var spec = CreateSpec<UserByEmailSpec>().AddParameter(email);
return Service.FirstOrDefault(spec);
}Execute a aplicação e acesse o endereço da aplicação. Exemplo: http://localhost:5000/api/user/GetUserByEMail?email=dn@dn32.com.br
Adicione o filtro FluentExceptionHandlerAttribute de controle de exceções à classe FilterConfig ou equivalente, ficando como a seguir:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options => options.Filters.Add(new FluentExceptionHandlerAttribute()));
}using Fluent.Architecture.Filters;
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new FluentExceptionHandlerAttribute());
}
}Eventuais erros agora serão apresentados da seguinte forma:
{
Message: "An entity with any of these keys already exists in the database: {Id:0}, {Email:'max@mail.com'}",
ValidationError: true
}O erro de validação refere-se ao e-mail repetido no banco de dados. Quando decoramos a propriedade Email de User com FluentUniqueKey, informamos para o sistema que não é permitido duplicação do valor desse campo.
Veja mais sobre validação em Validação.
Não é obrigatória a criação de mais nenhum arquivo para o funcionamento básico da entidade User, mas se for necessário tratar uma regra de validação, regra de negócio, ou algo mais específico, faz-se necessário criar itens customizador.
É necessário entender cada ponto da arquitetura para executar com sucesso os procedimentos necessários para o desenvolvimento de um sistema limpo e bem feito com ela. Vamos fazer uma abordagem mais detalhada nos próximos tópicos.
Sempre no rodapé da página será apresentado o item que deve ser visto após o atual para facilitar a sequência de atendimento.
Para facilitar o fluxo de aprendizado, sempre que uma informação não necessária para o entendimento geral da arquitetura, esse será marcado como Referência. Veja um exemplo abaixo:
Referência: Informações de referência são para consulta em momentos de necessidade e não para aprendizado imediato.
Pra prosseguir, veja o item Entidade
Entidades | Controller | Serviço | Especificações | Propagação | Validação | Repositório