Blazor - CRUD com ADO.NET em camadas - II


  Hoje vamos continuar a criação de um projeto em camadas que realizar o CRUD usando como cliente uma aplicação Blazor Server App.

Continuando a primeira parte do artigo vamos agora definir os demais projetos.

Definindo o projeto Infra

O projeto BlzCrud.Infra representa a camada de infraestrutura e é onde vamos definir a lógica de acesso aos dados usando ADO.NET.

Neste projeto vamos precisar acessar as informações sobre a string de conexão definidas no arquivo appsettings.json do projeto BlzCrud.App.

Assim vamos incluir neste projeto os seguintes pacotes nuget:

A seguir vamos criar no projeto as pastas Data e AppConfig.

Na pasta AppConfig vamos criar a classe AppSettings :

using Microsoft.Extensions.Configuration;
namespace BlzCrud.Infra.AppConfig;
public sealed class AppSettings
{
    private static AppSettings _instance = null;
    private static readonly object padlock = new object();
    public readonly string _connectionString = string.Empty;
    private AppSettings()
    {
        var configuration = new ConfigurationBuilder()
            .AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json"), optional: false)
            .AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.Development.json"), optional: false)
            .Build();
        _connectionString = configuration.GetSection("ConnectionStrings").GetSection("DefaultConnection").Value;
    }
    public static AppSettings Instance
    {
        get
        {
            lock (padlock)
            {
                if (_instance == null)
                {
                    _instance = new AppSettings();
                }
                return _instance;
            }
        }
    }
    public string ConnectionString
    {
        get => _connectionString;
    }
}

Esta classe vai obter a informação sobre a string de conexão armazenada no arquivo appsettings.json na seção 'ConnectionStrings' com o nome 'DefaultConnection' que iremos criar mais adiante. Esta é uma implementação Singleton com segurança de threads.

A seguir na pasta Data vamos criar a classe concreta DataService que implementa interface IDataService :

using System.Data.SqlClient;
using System.Data;
using BlzCrud.Domain.Entities;
using BlzCrud.Domain.Interfaces;
using BlzCrud.Infra.AppConfig;
namespace BlzCrud.Infra.Data;

public class DataService : IDataService
{
    string connectionString = AppSettings.Instance.ConnectionString;

    public List<Cliente> GetClientes()
    {
        try
        {
            List<Cliente> lstCliente = new List<Cliente>();
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                SqlCommand cmd = new SqlCommand("sp_GetClientes", con);
                cmd.CommandType = CommandType.StoredProcedure;
                con.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    Cliente cliente = new Cliente();
                    cliente.ClienteId = Convert.ToInt32(rdr["ClienteId"]);
                    cliente.Nome = rdr["Nome"].ToString();
                    cliente.Email = rdr["Email"].ToString();
                    cliente.Nascimento = Convert.ToDateTime(rdr["Nascimento"]);
                    cliente.Telefone = rdr["Telefone"].ToString();
                    cliente.Sexo = rdr["Sexo"].ToString();
                    cliente.Renda = Convert.ToDecimal(rdr["Renda"]);
                    lstCliente.Add(cliente);
                }
                con.Close();
            }
            return lstCliente;
        }
        catch (Exception)
        {
            throw;
        }
    }
    public void AddCliente(Cliente cliente)
    {
        try
        {
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                SqlCommand cmd = new SqlCommand("sp_AddCliente", con);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@Nome", cliente.Nome);
                cmd.Parameters.AddWithValue("@Email", cliente.Email);
                cmd.Parameters.AddWithValue("@Nascimento", cliente.Nascimento);
                cmd.Parameters.AddWithValue("@Telefone", cliente.Telefone);
                cmd.Parameters.AddWithValue("@Sexo", cliente.Sexo);
                cmd.Parameters.AddWithValue("@Renda", cliente.Renda);
                con.Open();
                cmd.ExecuteNonQuery();
                con.Close();
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
    public void UpdateCliente(Cliente cliente)
    {
        try
        {
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                SqlCommand cmd = new SqlCommand("sp_UpdateCliente", con);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@ClienteId", cliente.ClienteId);
                cmd.Parameters.AddWithValue("@Nome", cliente.Nome);
                cmd.Parameters.AddWithValue("@Email", cliente.Email);
                cmd.Parameters.AddWithValue("@Nascimento", cliente.Nascimento);
                cmd.Parameters.AddWithValue("@Telefone", cliente.Telefone);
                cmd.Parameters.AddWithValue("@Sexo", cliente.Sexo);
                cmd.Parameters.AddWithValue("@Renda", cliente.Renda);
                con.Open();
                cmd.ExecuteNonQuery();
                con.Close();
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
    public Cliente GetCliente(int? id)
    {
        try
        {
            Cliente cliente = new Cliente();
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                SqlCommand cmd = new SqlCommand("sp_GetCliente", con);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@ClienteId", id);
                con.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    cliente.ClienteId = Convert.ToInt32(rdr["ClienteId"]);
                    cliente.Nome = rdr["Nome"].ToString();
                    cliente.Email = rdr["Email"].ToString();
                    cliente.Nascimento = Convert.ToDateTime(rdr["Nascimento"]);
                    cliente.Telefone = rdr["Telefone"].ToString();
                    cliente.Sexo = rdr["Sexo"].ToString();
                    cliente.Renda = Convert.ToDecimal(rdr["Renda"]);
                }
            }
            return cliente;
        }
        catch (Exception)
        {
            throw;
        }
    }
    public void DeleteCliente(int? id)
    {
        try
        {
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                SqlCommand cmd = new SqlCommand("sp_DeleteCliente", con);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@ClienteId", id);
                con.Open();
                cmd.ExecuteNonQuery();
                con.Close();
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
}

Nesta classe estamos usando os recursos da ADO.NET e criando os métodos :

  1. GetClientes - Retorna todos os clientes
  2. AddCliente  - Inclui um novo cliente
  3. UpdateCliente - Atualiza um cliente
  4. GetCliente - Obtém um cliente pelo seu Id
  5. DeleteCliente - Deleta um cliente pelo seu id

Estes métodos utilizam as stored procedures criadas no banco de dados.

Definindo o projeto Application

Vamos criar no projeto BlzCrud.Application a pasta Services e nesta pasta criar a classe concreta ClienteService que implementa a interface IClienteService:

1- ClienteService

using BlzCrud.Domain.Entities;
using BlzCrud.Domain.Interfaces;
namespace BlzCrud.Application.Services;
public class ClienteService : IClienteService
{
    private readonly IDataService _dataService;
    public ClienteService(IDataService dataService)
    {
        _dataService = dataService;
    }
    public void CreateCliente(Cliente cliente)
    {
        _dataService.AddCliente(cliente);
    }
    public void DeleteClientePorId(int? id)
    {
        _dataService.DeleteCliente(id);
    }
    public Cliente GetClientePorId(int? id)
    {
        var cliente = _dataService.GetCliente(id);
        return cliente;
    }
    public List<Cliente> GetClientes()
    {
        var clientes = _dataService.GetClientes();
        return clientes;
    }
    public void UpdateCliente(Cliente cliente)
    {
        _dataService.UpdateCliente(cliente);
    }
}

Aqui estamos injetando uma instância de IDataService e usando esta instância para acessar os métodos que realizam as operações de acesso aos dados no SQL Server.

Na próxima parte do artigo vamos definir o projeto Blazor Server.

"O Senhor é o meu rochedo, e o meu lugar forte, e o meu libertador; o meu Deus, a minha fortaleza, em quem confio; o meu escudo, a força da minha salvação, e o meu alto refúgio."
Salmos 18:2

Referências:


José Carlos Macoratti