Nesse artigo eu mostro como usar o Repository Pattern para acessar banco de dados. Eu demostro esse conceito usando o banco de dados SQL com o componente de acesso a dados Dapper (Stackoverflow) e outro usando banco de dados MongoDB com o driver oficial do .NET.
MongoDB é um dos bancos de dados gratuitos NÃO-RELACIONAL mais populares que existem. Isso quer dizer, comparando com o SQL Server, ele não possui tabelas que se relacionam entre si através de chaves primárias ou secundárias, e sim MongoDB trabalha com documentos (normalmente em JSON) que podem armazenar um conjunto de dados inteiro.
Conheça mais a fundo Repository Pattern e outros Design Patterns no meu eBook totalmente gratuito da série Programação no Mundo Real: Design Patterns vol.1.
Uma das principais regras do Repository Pattern é que a classe de negócios não precisa saber onde os dados estão armazenados ou simplemente não precisa saber qual é o banco de dados que está sendo utilizado.
Vamos começar essa parada!
Para esse código, você poderá usar o Visual Studio 2017 se preferir, mas dê uma olhada no artigo que escrevi UNBOXING VS2017: Primeiras Impressões no Mundo Real decida se realmente precisa do 2017.
Repository Pattern
O que é ou para que serve?
É um elo de ligação entre a camada de negócios e a camada de acesso a dados sem que a camada de negócios saiba qual é a base de dados que está sendo acessada.
Onde uso?
No acesso a base de dados.
Principal regra ou cenário:
Criar uma interface e uma classe que implementa essa interface. Nessa classe herde de uma outra classe básica que fará o acesso a base de dados correspondente.
O objetivo principal do exemplo é criar um método para buscar “taxas” (para calcular alguma coisa) em determinado repositório de dados.
Vamos definir a interface ITaxaRepository para o repositório:
public interface ITaxaRepository : IDisposable
{
Task<IEnumerable<Models.Taxa>> ListarTaxa(int codigo);
}
Segundo passo é criar a classe do repositório para o MongoDB:
public class MongoDBTaxaRepository : MongoDBRepository, ITaxaRepository
{
public async Task<IEnumerable<Taxa>> ListarTaxa(int codigo)
{
// comente esse bloco quando instalar o MONGODB, criar a tabela e carregar de dados antes.
return await Task.Run(() =>
{
var taxas = new List<Taxa>();
taxas.Add(new Taxa { Codigo = 1, Valor = 10, Fator = 2 });
return taxas;
});
//código da implementação de mongodb
return await Database.GetCollection<Taxa>("Taxas")
.Find(x => x.Codigo == codigo)
.ToListAsync();
}
}
A classe de MongoDBTaxaRepository busca as taxas no MongoDB e serializa o documento em uma lista de Taxa. Uma coisa interessante a perceber é que essa classe herda de outra classe básica MongoDBRepository.
MongoDBRepository server para se conectar ao MongoDB e pode ser facilmente reutilizada:
public class MongoDBRepository : IDisposable
{
public MongoDBRepository()
: this("localhost")
{
}
public MongoDBRepository(string databaseName)
{
DatabaseName = databaseName;
_client = new MongoClient();
_database = _client.GetDatabase(DatabaseName);
}
public void Dispose()
{
_client = null;
_database = null;
}
public string DatabaseName { get; set; }
private IMongoClient _client;
private IMongoDatabase _database;
public IMongoDatabase Database
{
get
{
return _database;
}
}
}
O próximo passo e criar a classe de acesso ao banco de dados SQL usando Dapper, então vamos fazer isso já!
DapperTaxaRepository com Dapper acessando SQL Server:
public class DapperTaxaRepository : SqlServerRepository, ITaxaRepository
{
public async Task<IEnumerable<Taxa>> ListarTaxa(int codigo)
{
var command = @"SELECT Valor, Fator, Codigo
FROM Taxas
WHERE Codigo = @codigo";
return await Database.QueryAsync<Taxa>(command, new { codigo = codigo });
}
}
O uso do Dapper é muito simples pois possui diversos Extensions Methods úteis para realizar as consultas e operações no banco de dados SQL.
O comando básico para consultas com Dapper é enviar uma string contendo o comando SQL para o método QueryAsync explicitando a serialização/conversão dos dados para a model Taxa. No último parâmetro deste método, passe um objeto anônimo para ser usado na cláusula WHERE. Fácil hein! Retornará uma lista de taxas.
Ambas as classes MongoDBTaxaRepository e DapperTaxaRepository implementam a interface ITaxaRepository.
DapperTaxaRepository também herda de uma classe básica SqlServerRepository, que serve para se conectar ao banco de dados SQL e também pode facilmente ser reutilizada:
public class SqlServerRepository : IDisposable
{
public SqlServerRepository()
: this("sqlserver")
{
}
public SqlServerRepository(string connectionStringId)
{
_connectionStringId = connectionStringId;
}
public virtual string ConnnectionStringId
{
get
{
return _connectionStringId;
}
}
protected SqlConnection Database
{
get
{
if (_connection == null)
{
if (string.IsNullOrEmpty(_connectionString))
{
_connectionString = ConfigurationManager.ConnectionStrings[ConnnectionStringId].ConnectionString;
}
_connection = new SqlConnection(_connectionString);
}
return _connection;
}
}
public SqlServerRepository UseConnectionStringId(string connectionStringId)
{
_connectionStringId = connectionStringId;
return this;
}
public SqlServerRepository UseConnectionString(string connectionString)
{
_connectionString = connectionString;
return this;
}
public virtual void Dispose()
{
if (_connection != null)
{
_connection.Close();
_connection.Dispose();
_connection = null;
}
}
private SqlConnection _connection = null;
private string _connectionStringId;
private string _connectionString;
}
Exemplos de uso:
// Exemplos de chamadas paralelas usando diferentes repositórios // TaxaService se vira para achar o repositório var calculoA = TaxaService.CalcularTaxa(1); // TaxaService recebe o repositório (instanciado via Dependency Injection) var calculoB = TaxaService.CalcularTaxa(1, _repository); // TaxaService recebe o repositório especifico do MongoDB var calculoC = TaxaService.CalcularTaxa(1, new MongoDBTaxaRepository()); await Task.WhenAll(calculoA, calculoB, calculoC);
Eu costumo usar Dependency Injection na definição dos serviços, onde configuro o apontamento uma interface para uma determinada classe sem explicitá-la (primeiro exemplo).
Conheça mais a fundo Dependency Injection no meu eBook totalmente gratuito da série Programação no Mundo Real: Design Patterns vol.1.
Bom é isso. Espero que tenha ajudado.
Ajude a aprimorar o conteúdo deste site sugerindo um artigo ou tema.
Repository Pattern com Dapper SQL e MongoDB
Repository SQL Dapper MongoDB: Perguntas, sugestões ou críticas são bem vindas. Boa sorte!
Esse artigo dedico as 30 Pessoas que Influenciaram Minha Carreira Profissional.
| Faça download completo do código fonte no github. |



