Coleção de bibliotecas .NET para desenvolvimento de aplicações robustas, escaláveis e de alta performance.
🎉 Novidade! Agora com suporte completo a filtros dinâmicos com tipos complexos! Use propriedades de navegação como
Customer.Address.Citydiretamente nos seus filtros. Ver exemplos ↓
- Async/Await em todas as operações I/O
- Connection pooling otimizado para bancos de dados
- Retry policies configuráveis com Polly
- Caching inteligente com suporte a distribuído
- JWT Authentication com refresh tokens
- Autenticação Azure AD integrada
- Criptografia de dados sensíveis
- Rate limiting e proteção contra ataques
- Logging estruturado com Microsoft.Extensions.Logging
- Health checks customizados
- Métricas e telemetria
- Distributed tracing pronto para produção
- Clean Architecture e DDD patterns
- SOLID principles aplicados
- Dependency Injection nativa
- Unit of Work e Repository patterns
- Tipos complexos com navegação aninhada (
Customer.Address.City) - Type-safe filters com attributes declarativos
- Performance otimizada com compiled expressions
- Operadores especializados (Contains, StartsWith, Range, etc.)
- Validação automática de propriedades de navegação
- 100% testável com mocks e fakes
- InMemory providers para testes rápidos
- Testcontainers para testes de integração
- Separation of Concerns clara
- Azure Service Bus para mensageria
- Azure Storage para blobs e arquivos
- Docker e Kubernetes ready
- Health checks para orquestração
- ✨ Propriedades de diagnóstico contextuais para Dead Letter Queue e Abandon
- 🔧 Arquitetura modular refatorada com complexidade cognitiva reduzida
- 🔍 Troubleshooting aprimorado com metadados detalhados
- 📊 Observabilidade avançada para monitoramento e métricas
- 🔍 Filtros com tipos complexos - Suporte a propriedades de navegação aninhadas
- 🎯 Notação de ponto (dot notation) - Ex:
Customer.Address.City - ⚡ Performance otimizada com compiled queries e parameterização EF Core
- 🛠️ Validação aprimorada - Detecção automática de propriedades aninhadas
- 📝 Documentação completa com exemplos de filtros complexos
- 📧 Envio via MailKit com templates HTML
- 📎 Anexos (file e stream)
- 👥 Múltiplos destinatários (To, Cc, Bcc)
- 🔄 Retry logic integrado
| Pacote | Descrição | Versão | Downloads |
|---|---|---|---|
| Nuuvify.CommonPack.Extensions | Métodos de extensão e Notification Pattern |
Cada pacote possui documentação detalhada em seu respectivo diretório:
- 📚 BackgroundService - 🆕 Com diagnóstico avançado
- 📚 AzureServiceBus
- 📚 AzureServiceBus.Abstraction
- 📚 AzureStorage
- 📚 AzureStorage.Abstraction
- 📚 StandardHttpClient
- 📚 Email - Envio de e-mails via SMTP
- 📚 Email.Abstraction
- 📚 UnitOfWork - Com queries dinâmicas
- 📚 UnitOfWork.Abstraction - ✨ Com filtros complexos
- 📚 Domain
- 📚 AutoHistory
- 📚 Extensions - Notification Pattern e extensões
- 📚 Samples - Exemplos práticos de uso
- 📚 OrderProcessingWorker - Worker com Azure Service Bus
# Unit of Work com Entity Framework
dotnet add package Nuuvify.CommonPack.UnitOfWork
# Cliente HTTP com resiliência
dotnet add package Nuuvify.CommonPack.StandardHttpClient
# Envio de e-mails
dotnet add package Nuuvify.CommonPack.Email
# Segurança e JWT
dotnet add package Nuuvify.CommonPack.Security
# Background services com Azure Service Bus
dotnet add package Nuuvify.CommonPack.BackgroundService// Configuração no Program.cs
builder.Services.AddNuuvifyDbContext<MyDbContext>(
builder.Configuration.GetConnectionString("DefaultConnection"));
// Uso no serviço
public class ProductService
{
private readonly IUnitOfWork _unitOfWork;
public ProductService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task<Product> CreateProductAsync(Product product)
{
await _unitOfWork.Repository<Product>().AddAsync(product);
await _unitOfWork.SaveChangesAsync();
return product;
}
public async Task<IEnumerable<Product>> GetActiveProductsAsync()
{
return await _unitOfWork.Repository<Product>()
.Where(p => p.IsActive)
.OrderBy(p => p.Name)
.ToListAsync();
}
}// Modelo de filtro com propriedades de navegação
public class OrderFilterModel : IQueryableCustom
{
// Filtro simples
[QueryOperator(WhereOperator.GreaterThanOrEqualTo)]
public decimal? MinTotal { get; set; }
// Filtros com tipos complexos usando notação de ponto
[QueryOperator(WhereOperator.Contains, HasName = "Customer.Name", CaseSensitive = false)]
public string CustomerName { get; set; }
[QueryOperator(WhereOperator.Equals, HasName = "Customer.Address.City")]
public string City { get; set; }
[QueryOperator(WhereOperator.ContainsWithLikeForList, HasName = "Items.Product.Category", CaseSensitive = false)]
public List<string> ProductCategories { get; set; }
// Filtro aninhado de múltiplos níveis
[QueryOperator(WhereOperator.GreaterThan, HasName = "Customer.Profile.CreatedDate")]
public DateTime? CustomerSince { get; set; }
}
// Uso do serviço com filtros complexos
public class OrderService
{
private readonly IUnitOfWork _unitOfWork;
public async Task<IPagedList<Order>> GetFilteredOrdersAsync(OrderFilterModel filter)
{
return await _unitOfWork.Repository<Order>()
.Filter(filter) // ✨ Aplica automaticamente todos os filtros
.OrderByDescending(o => o.OrderDate)
.GetPagedListAsync(pageIndex: 1, pageSize: 20);
}
// SQL gerado automaticamente:
// WHERE Orders.Total >= @p0
// AND UPPER(Customer.Name) LIKE '%' + UPPER(@p1) + '%'
// AND Customer.Address.City = @p2
// AND (Items.Product.Category LIKE '%' + @p3 + '%' OR Items.Product.Category LIKE '%' + @p4 + '%')
// AND Customer.Profile.CreatedDate > @p5
}
// Exemplo de uso
var filter = new OrderFilterModel
{
MinTotal = 100.00m,
CustomerName = "João",
City = "São Paulo",
ProductCategories = new List<string> { "Electronics", "Computers" },
CustomerSince = DateTime.Now.AddYears(-2)
};
var orders = await orderService.GetFilteredOrdersAsync(filter);// Configuração no appsettings.json
{
"EmailConfig": {
"EmailServerConfiguration": {
"ServerHost": "smtp.gmail.com",
"Port": 587,
"Security": "StartTls",
"AccountUserName": "seu-email@gmail.com",
"AccountPassword": "sua-senha"
}
}
}
// Configuração no Program.cs
builder.Services.AddScoped<IEmail, Email>();
builder.Services.Configure<EmailServerConfiguration>(
builder.Configuration.GetSection("EmailConfig:EmailServerConfiguration"));
// Uso no serviço
public class NotificationService
{
private readonly IEmail _emailService;
public async Task SendWelcomeEmailAsync(string email, string name)
{
var recipients = new Dictionary<string, string> { { email, name } };
var senders = new Dictionary<string, string> { { "noreply@empresa.com", "Empresa" } };
await _emailService.EnviarAsync(
recipients: recipients,
senders: senders,
subject: "Bem-vindo!",
message: $"<h1>Olá {name}!</h1><p>Seja bem-vindo à nossa plataforma.</p>"
);
}
}// Configuração no Program.cs
builder.Services.AddStandardHttpClient<MyApiClient>(options =>
{
options.BaseAddress = "https://api.example.com";
options.Timeout = TimeSpan.FromSeconds(30);
options.RetryCount = 3;
});
// Uso no serviço
public class MyApiClient
{
private readonly HttpClient _httpClient;
public MyApiClient(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<Product> GetProductAsync(int id)
{
return await _httpClient.GetFromJsonAsync<Product>($"/products/{id}");
}
}✅ Recentemente corrigido: Problemas de
ObjectDisposedExceptionem testes foram resolvidos com gerenciamento adequado do ciclo de vida do EF Core.
O projeto possui uma estratégia de testes abrangente com 12 projetos de teste cobrindo todos os pacotes principais:
| Projeto de Teste | Tipo | Descrição |
|---|---|---|
| Nuuvify.CommonPack.UnitOfWork.InMemory.xTest | Unit | Testes unitários com InMemory provider |
| Nuuvify.CommonPack.UnitOfWork.Integration.xTest | Integration | Testes de integração com SQL Server (Docker) |
| Nuuvify.CommonPack.Extensions.xTest | Unit | Testes de extensões e Notification Pattern |
| Nuuvify.CommonPack.Email.xTest | Unit | Testes do serviço de e-mail |
| Nuuvify.CommonPack.Security.xTest | Unit | Testes de segurança e JWT |
| Nuuvify.CommonPack.StandardHttpClient.xTest | Unit | Testes do cliente HTTP |
| Nuuvify.CommonPack.BackgroundService.xTest | Unit | Testes de background services |
| Nuuvify.CommonPack.AzureServiceBus.xTest | Unit | Testes de Azure Service Bus |
| Nuuvify.CommonPack.AzureStorage.xTest | Unit | Testes de Azure Storage |
| Nuuvify.CommonPack.Middleware.xTest | Unit | Testes de middlewares |
| Nuuvify.CommonPack.HealthCheck.xTest | Unit | Testes de health checks |
| Nuuvify.CommonPack.Domain.xTest | Unit | Testes de entidades de domínio |
Foco: Velocidade e feedback rápido
- ⚡ Rápidos: Execução em < 1 segundo
- 💚 Leves: Usa EF Core InMemory provider
- ✅ CI/CD Friendly: Sem dependências externas (não requer Docker)
- 🎯 Uso: TDD, desenvolvimento rápido, validação de lógica de negócio
# Executar todos os testes unitários
dotnet test --filter "Category=Unit"
# Executar testes de um projeto específico
dotnet test test/Nuuvify.CommonPack.Extensions.xTestFoco: Fidelidade e validação real
- 🐘 SQL Server Real: Usa Testcontainers com SQL Server 2022
- ✅ Alta Fidelidade: Testa queries SQL específicas e collations
⚠️ Requer Docker: Docker Desktop deve estar em execução- 🎯 Uso: Validação de features específicas do SQL Server, testes de regressão
# Executar testes de integração (requer Docker)
dotnet test --filter "Category=Integration"
# Executar projeto específico de integração
dotnet test test/Nuuvify.CommonPack.UnitOfWork.Integration.xTest# Executar todos os testes
dotnet test
# Executar com cobertura de código
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
# Executar com relatório detalhado
dotnet test --logger "console;verbosity=detailed"📖 Documentação Completa: Integration Tests README
| Aspecto | Unit (InMemory) | Integration (SQL Server) |
|---|---|---|
| Velocidade | ⚡ < 1s | 🐢 2-4s |
| Requisitos | ✅ Nenhum | |
| Fidelidade | ✅ SQL Real | |
| CI/CD | ✅ Sempre | |
| Cobertura | 🎯 Lógica | 🎯 Infraestrutura |
| Feedback | 🚀 Instantâneo | ⏱️ Alguns segundos |
- Durante o desenvolvimento: Use testes unitários (InMemory) para feedback rápido
- Antes do commit: Execute todos os testes unitários
- Antes do merge: Execute testes de integração com Docker
- Pipeline CI/CD: Execute ambos em paralelo quando possível
O projeto mantém alta cobertura de código:
- Testes Unitários: > 80% de cobertura
- Testes de Integração: Valida cenários críticos
- SonarCloud: Análise contínua de qualidade
Contribuições são bem-vindas! Veja como você pode ajudar:
- Fork o repositório
- Clone seu fork:
git clone https://github.com/seu-usuario/Nuuvify.CommonPack.git - Crie uma branch:
git checkout -b feature/minha-feature - Faça suas alterações seguindo as convenções do projeto
- Execute os testes:
dotnet test - Commit suas mudanças:
git commit -m 'feat: adiciona nova feature' - Push para a branch:
git push origin feature/minha-feature - Abra um Pull Request
- ✅ Conventional Commits: Use commits semânticos (feat, fix, docs, etc.)
- ✅ EditorConfig: Siga as regras do
.editorconfig - ✅ Testes: Escreva testes para novas funcionalidades
- ✅ Documentação: Atualize o README quando necessário
- ✅ Code Review: Aguarde aprovação antes do merge
- Siga os princípios SOLID
- Escreva código limpo e legível
- Adicione comentários onde necessário
- Mantenha alta cobertura de testes
- Use async/await para operações I/O
Se você receber o erro abaixo ao tentar fazer push, significa que há credenciais de outra conta em cache:
remote: Permission to nuuvify/Nuuvify.CommonPack.git denied to usuario_anterior.
fatal: unable to access 'https://github.com/nuuvify/Nuuvify.CommonPack.git/': The requested URL returned error: 403
1. Configure o usuário local do repositório:
git config --local user.name "lzocateli"
git config --local user.email "lzocateli@outlook.com"2. Troque o remote para HTTPS (se estiver usando SSH):
git remote set-url origin https://github.com/nuuvify/Nuuvify.CommonPack.git3. Liste e remova credenciais antigas do Windows:
# Listar credenciais relacionadas ao GitHub
cmdkey /list | Select-String -Pattern "github"
# Remover cada entrada encontrada (ajuste o target conforme listado)
cmdkey /delete:git:https://github.com4. Limpe também pelo Git Credential Manager:
# Cole as 3 linhas abaixo e pressione Enter duas vezes
git credential reject
protocol=https
host=github.com5. Se houver credenciais persistentes no Gerenciador de Credenciais do Windows:
- Pressione
Win + R→ digitecontrol /name Microsoft.CredentialManager→ Enter - Clique em Credenciais do Windows
- Localize entradas com
githubno nome (ex:GitHub for Visual Studio - https://usuario_anterior@github.com/) - Clique na entrada e depois em Remover
6. (Opcional) Se usar GitHub CLI:
gh auth logout
gh auth login
# Selecione: GitHub.com → HTTPS → Autentique no navegador com a conta correta7. Faça o push — o Git Credential Manager abrirá o navegador para autenticar:
git push origin sua-branch
⚠️ Dica: Certifique-se de estar logado no GitHub com a conta correta (lzocateli) antes de autorizar no navegador. Se o navegador abrir já logado com outra conta, faça logout no GitHub primeiro.
8. Confirme que está tudo certo:
# Verificar configuração local
git config user.name
git config user.email
# Se usar gh cli
gh auth status- 📦 Pacotes NuGet
- 📋 Changelog - 🆕 Filtros com tipos complexos!
- 📖 Wiki
- 💡 Samples e Exemplos
- 🐛 Issues
- 🔄 Pull Requests
- 🚀 Releases
- 📊 SonarCloud
- 💬 Discussions
- 🌐 Website
Este projeto está licenciado sob a MIT License.
Desenvolvido e mantido pela equipe Nuuvify.
Agradecimentos especiais a todos os colaboradores que ajudaram a tornar este projeto melhor!
Nuuvify CommonPack - Construindo soluções robustas para .NET 🚀