Blazor - Despesas Pessoais com Gráfico de Barras e Pizza - II
Neste artigo vamos iniciar a criação de uma aplicação Blazor Web Assemply para gerenciar despesas pessoais onde vamos criar gráficos de barras e de pizza. |
Continuando a primeira parte do artigo vamos implementar o Repositório e os Controladores no projeto Server.
Implementando o padrão Repository na memória
Crie no projeto Server a pasta Repositories e nesta pasta crie a interface IRepository:
using System.Collections.Generic;
namespace Financas.Pessoais.Server.Repositories
{
public interface IRepository<T>
{
void Add(T entity);
void Remove(T entity);
IEnumerable<T> GetAll();
}
}
|
Observe que definimos o contrato para implementar os métodos para Adicionar, Remover e Listar objetos pois como estamos trabalhando na memória a atualização é automática.
Na mesma pasta vamos criar a classe concreta MemoryRepository<T> que implementa esta interface:
using System.Collections.Generic;
namespace Financas.Pessoais.Server.Repositories
{
public class MemoryRepository<T> : IRepository<T>
{
private readonly IList<T> _entities;
public MemoryRepository()
{
_entities = new List<T>();
}
public void Add(T entity)
{
_entities.Add(entity);
}
public IEnumerable<T> GetAll()
{
return _entities;
}
public void Remove(T entity)
{
_entities.Remove(entity);
}
}
}
|
Temos aqui a implementação do repositório na memória de forma genérica e assim poderemos usar essa implementação para qualquer tipo T que no nosso exemplo vai representar a classe Receita e Despesa.
Agora vamos usar esta implementação e criar a classe DadosTestes e nesta classe vamos definir dois métodos de extensão AddDespesasRepository e AddReceitasRepository para IServiceCollection onde vamos popular o repositório com dados de receitas e despesas.
using Financas.Pessoais.Shared; using Microsoft.Extensions.DependencyInjection; using System;
namespace Financas.Pessoais.Server.Repositories
receitaRepository.Add(new Receita { Data = new DateTime(mesAnterior.Year,
mesAnterior.Month, 25), Valor = 2480, Categoria = CategoriaReceita.Salário,
Descricao = "Salário mensal" });
public static void AddDespesasRepository(this
IServiceCollection services)
despesaRepository.Add(new Despesa { Data = new DateTime(mesAnterior.Year,
mesAnterior.Month, 25), Valor = 480, Categoria = CategoriaDespesa.Alimentação,
Descricao = "Compra Mensal" }); |
Com as implementações prontas temos que registrar os serviços na classe Startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddReceitasRepository();
services.AddDespesasRepository();
services.AddControllersWithViews();
services.AddRazorPages();
}
|
Temos assim prontos o repositório e os dados para testes e agora vamos criar os controladores ReceitasControllers e DespesasControllers na pasta Controllers :
Criando os controladores
Na pasta Controllers crie o Controller ReceitasController:
using Financas.Pessoais.Server.Repositories; using Financas.Pessoais.Shared; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; namespace Financas.Pessoais.Server.Controllers [HttpPost] [HttpDelete("{id?}")] _receitaRepository.Remove(entity); |
Nesta Web API injetamos a instância do repositório no construtor do controller e implementamos os métodos Get, Post e Delete.
Agora vamos repetir o procedimento para o controller DepesasController:
using Financas.Pessoais.Server.Repositories; using Financas.Pessoais.Shared; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; namespace Financas.Pessoais.Server.Controllers [HttpPost] [HttpDelete("{id?}")] _receitaRepository.Remove(entity); |
Com isso concluímos as implementações no projeto Server e podemos retornar ao projeto Client para criar os formulários para Despesa e Receita.
Exibindo os dados e concluindo o formulário ReceitaForm
Já temos o formulário ReceitaForm criado e vamos agora incluir o código que vai acessar o API no projeto Server e apresentar os dados de testes para receitas e concluir as funcionalidades do formulário para permitir incluir dados de receitas.
Dessa forma vamos ajustar o código do componente ReceitaForm incluindo a validação dos dados, o envio dos dados acessando a Web API Receitas :
@inject HttpClient Http;
<div class="card"> @code{ private ReceitaDTO receita = new ReceitaDTO { Data = DateTime.Today }; [Parameter] public async Task HandleValidSubmit() |
Note que injetamos uma instância do serviço HttpClient para usar o método PostAsJsonAsync e acessar a API. Isso é possível pois na classe Program incluímos uma implementação do tipo HttpClient no contêiner DI nativo.
Assim podemos postar os dados do componente ReceitaForm mas a tabela faz parte do componente Pai, Receitas.razor e precisamos informar à pagina Receitas para atualizar os dados sempre que um usuário clicar no botão enviar do componente ReceitaForm.
Por enquanto, vamos usar uma solução simples. Vamos definir uma nova propriedade no componente ReceitaForm. Criamos uma propriedade pública do tipo EventCallback e a nomeamos OnSubmitCallback. Também adicionamos o atributo Parameter, que disponibiliza esta propriedade quando o componente é usado.
Em seguida,
executamos o EventCallback depois de postar os
dados na API no método HandleValidSubmit.
A ideia é fornecer um retorno de chamada(EventCallBack) para o componente
ReceitaForm que será executado depois de enviarmos
os dados para a API.
A seguir teremos que fornecer o retorno de chamada de dentro da página Receitas quando formos ajustar o seu código. Assim abra o componente Receitas.razor e ajuste o código conforme abaixo:
@page "/receitas" @inject HttpClient Http;
<div class="row"> protected async Task CarregaDados() public async Task Refresh() |
Observe que implementamos um método Refresh. Neste método, queremos recarregar os dados. Já temos esse comportamento no método OnInitializedAsync. Vamos extrair o código em um método CarregaDados para chamá-lo tanto no método OnInitializedAsync quanto no método Refresh.
Em seguida, queremos fornecer o método Refresh para o componente ReceitaForm. Podemos fazer isso configurando o atributo OnSubmitCallback para o método Refresh na definição do modelo. Não se esqueça de adicionar um símbolo @ na frente do nome do método.
Agora executando o projeto teremos a exibição dos dados e poderemos incluir novas receitas usando o formulário:
Na próxima parte do artigo vamos exibir as despesas, criar o formulário para Despesas e implementar a exclusão de uma receita e/ou despesa.
"Voz do que
clama no deserto: Preparai o caminho do Senhor; endireitai no ermo vereda a
nosso Deus.
Todo o vale será exaltado, e todo o monte e todo o outeiro será abatido; e o que
é torcido se endireitará, e o que é áspero se aplainará."
Isaías 40:3,4
Referências:
ASP .NET Core - Implementando a segurança com
ASP.NET Core MVC - Criando um Dashboard .
C# - Gerando QRCode - Macoratti
ASP .NET - Gerando QRCode com a API do Google
ASP .NET Core 2.1 - Como customizar o Identity
Usando o ASP .NET Core Identity - Macoratti
ASP .NET Core - Apresentando o IdentityServer4
ASP .NET Core 3.1 - Usando Identity de cabo a rabo