IPG is a comprehensive ASP.NET Core 8.0 library providing standardized implementations for logging (Serilog + Application Insights), multiple database support (MySQL, PostgreSQL, Supabase), background jobs (Hangfire), cloud storage, email/SMS services, PDF generation (QuestPDF), CORS security, JWT authentication, and more - helping you build production-ready APIs 10x faster.
$ dotnet add package IPGA production-ready .NET 8 library providing standardized implementations for logging, databases, security, notifications, storage, PDF generation, and more - helping you build ASP.NET Core applications 10x faster.
dotnet add package IPG
// Program.cs
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
// 🎯 One line to register everything!
builder.UseIPGStandard(new[] { Assembly.GetExecutingAssembly() });
var app = builder.Build();
// 🎯 One line to configure middleware!
app.UseIPGStandard();
app.MapControllers();
app.Run();
That's it! Your app now has logging, CORS, Swagger, exception handling, and all configured services ready to use.
Data/ directory)Extension Methods:
AddMySqlContext<T>() - Register MySQL DbContext with retryAddPostgreSqlContext<T>() - Register PostgreSQL/Supabase DbContext with retryGuides:
Middlewares/, Configuration)Enhanced CORS Features: NEW in v1.0.9
Basic Configuration:
{
"Cors": {
"AllowAny": false,
"Origins": ["https://myapp.com", "https://www.myapp.com"],
"AllowCredentials": true
}
}
Advanced Configuration:
{
"Cors": {
"AllowAny": false,
"Origins": ["https://myapp.com"],
"AllowCredentials": true,
"AllowedMethods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"AllowedHeaders": ["Content-Type", "Authorization", "X-API-Key"],
"ExposedHeaders": ["X-Request-ID", "X-Total-Count"]
},
"Jwt": {
"SecretKey": "your-secret-key-32-chars-minimum",
"ValidIssuer": "https://myapp.com",
"ValidAudience": "https://myapp.com",
"KeyDuration": 3600
}
}
📖 See CORS Examples - 10+ production-ready CORS configurations
Helpers/, Configuration)Logging Sinks:
Configuration:
{
"Serilog": {
"serverUrl": "http://localhost:5341",
"apiKey": "your-seq-api-key"
},
"ApplicationInsights": {
"ConnectionString": "InstrumentationKey=xxx;..."
}
}
Services/, Options/)Services:
IAzureCommunicationService - Azure Communication Services (Email & SMS)Features:
Configuration:
{
"AzureCommunication": {
"ConnectionString": "endpoint=https://...;accesskey=...",
"EnableEmail": true,
"EnableSms": true,
"SenderEmail": "noreply@yourdomain.com",
"SenderDisplayName": "My Application",
"SmsFromPhoneNumber": "+1234567890"
}
}
Guide:
Services/)Services:
ISupabaseService - Supabase storage operationsIGoogleStorageService - Google Cloud StorageIAzureBlobStorageService - Azure Blob StorageFeatures:
Configuration:
{
"GoogleCredential": {
"type": "service_account",
"project_id": "your-project-id",
"private_key": "-----BEGIN PRIVATE KEY-----\n...",
"client_email": "...@your-project.iam.gserviceaccount.com"
},
"AzureBlobStorage": {
"ConnectionString": "DefaultEndpointsProtocol=https;...",
"DefaultContainerName": "uploads"
}
}
Services/) NEW in v1.0.8Services:
IPdfService - Basic PDF generation interfaceInvoicePdfService - Pre-built invoice template (example)Features:
Usage:
// Register service
builder.Services.AddScoped<IPdfService, PdfService>();
// Set license (required!)
QuestPDF.Settings.License = LicenseType.Community;
// Generate PDF
var pdfBytes = _pdfService.GeneratePdf(invoiceData);
return File(pdfBytes, "application/pdf", "invoice.pdf");
Guide:
Services/) NEW in v1.1.0Service:
IFirebaseService - Complete Firebase integrationFeatures:
Configuration:
{
"Firebase": {
"CredentialPath": "firebase-service-account.json",
"StorageBucket": "your-project.appspot.com",
"EnableAuth": true,
"EnableMessaging": true,
"EnableFirestore": true
}
}
Or with inline credentials:
{
"Firebase": {
"CredentialJson": "{\"type\":\"service_account\",\"project_id\":\"...\",\"private_key\":\"...\"}",
"StorageBucket": "your-project.appspot.com"
}
}
Usage:
// Verify token from client
var decoded = await _firebase.VerifyIdTokenAsync(idToken);
// Send push notification
await _firebase.SendNotificationAsync(deviceToken, "Hello!", "New message");
// Send to topic
await _firebase.SendToTopicAsync("news", "Breaking News", "Something happened!");
// Set user role
await _firebase.SetCustomClaimsAsync(uid, new Dictionary<string, object>
{
{ "role", "admin" }
});
Guide:
Configuration)Configuration:
{
"HangfireOptions": {
"Enable": true,
"DbType": "PostgreSQL",
"ConnectionStrings": "Host=localhost;Database=hangfire;...",
"WorkerCount": 5,
"Username": "admin",
"Password": "admin123"
}
}
Dashboard: http://localhost:5000/hangfire
OpenApi/, Routes/)/api/v1/...)Configuration:
{
"Swagger": {
"Enable": true
}
}
Swagger UI: http://localhost:5000/api/docs
Services/, Helpers/)Services:
IGeneralService - General utility methodsAuto Registration:
Service are auto-registered as scopedRepository are auto-registered as scopedServices/)Service:
ISupabaseService - Complete Supabase integrationConfiguration:
{
"Supabase": {
"Url": "https://your-project.supabase.co",
"Key": "your-anon-public-key",
"ServiceRoleKey": "your-service-role-key",
"AutoRefreshToken": true,
"PersistSession": true
}
}
Guide:
public class ProductsController : ControllerBase
{
private readonly IDbContextFactory<MyDbContext> _dbFactory;
public ProductsController(IDbContextFactory<MyDbContext> dbFactory)
{
_dbFactory = dbFactory;
}
[HttpGet]
public async Task<IActionResult> GetProducts()
{
await using var context = await _dbFactory.CreateDbContextAsync();
var products = await context.Products
.Where(p => p.IsActive)
.OrderBy(p => p.Name)
.ToListAsync();
return Ok(products);
}
}
public class UsersController : ControllerBase
{
private readonly ISupabaseService _supabase;
[HttpGet]
public async Task<IActionResult> GetActiveUsers()
{
var users = await _supabase.Table<User>()
.Where(x => x.IsActive == true)
.Order(x => x.CreatedAt, Ordering.Descending)
.Get();
return Ok(users.Models);
}
[HttpPost]
public async Task<IActionResult> CreateUser([FromBody] User user)
{
await _supabase.Table<User>().Insert(user);
return Ok(user);
}
}
public class NotificationController : ControllerBase
{
private readonly IAzureCommunicationService _comm;
[HttpPost("welcome-email")]
public async Task<IActionResult> SendWelcomeEmail([FromBody] string email)
{
await _comm.SendEmailAsync(
recipients: new[] { email },
subject: "Welcome to Our Platform!",
htmlContent: "<h1>Welcome!</h1><p>Thanks for joining us.</p>"
);
return Ok("Email sent successfully");
}
}
public class InvoiceController : ControllerBase
{
private readonly IPdfService _pdf;
[HttpGet("{id}/pdf")]
public IActionResult GetInvoicePdf(string id)
{
var invoice = GetInvoiceData(id);
var pdfBytes = _pdf.GeneratePdf(invoice);
return File(pdfBytes, "application/pdf", $"invoice-{id}.pdf");
}
}
public class FilesController : ControllerBase
{
private readonly ISupabaseService _supabase;
private readonly IGoogleStorageService _gcs;
[HttpPost("upload")]
public async Task<IActionResult> Upload(IFormFile file)
{
using var stream = file.OpenReadStream();
// Upload to Supabase
var url = await _supabase.UploadFileAsync("uploads", file.FileName, stream);
// Or upload to Google Cloud Storage
// var result = await _gcs.UploadFilesAsync("my-bucket", file.FileName, stream);
return Ok(new { url });
}
}
{
"ProjectName": "MyApp",
"Env": "DEV",
"Cors": {
"AllowAny": true
}
}
See appsettings.example.json for all available options.
Create environment-specific config files:
appsettings.Development.json - Local developmentappsettings.Staging.json - Staging environmentappsettings.Production.json - Production environmentExample - Development with open CORS:
{
"Cors": {
"AllowAny": true
},
"Serilog": {
"serverUrl": "http://localhost:5341"
}
}
Example - Production with restricted CORS:
{
"Cors": {
"AllowAny": false,
"Origins": [
"https://myapp.com",
"https://www.myapp.com",
"https://admin.myapp.com"
]
}
}
The library provides flexible, production-ready CORS configuration with granular control over origins, methods, headers, and credentials.
1. Development Mode (Allow All):
{
"Cors": {
"AllowAny": true
}
}
⚠️ Warning: Only use in development! This allows ALL origins, methods, and headers.
2. Production Mode (Basic):
{
"Cors": {
"AllowAny": false,
"Origins": ["https://myapp.com", "https://www.myapp.com"]
}
}
✅ Whitelists specific origins ✅ Allows any method and header from those origins
3. Comma-Separated Origins:
{
"Cors": {
"AllowAny": false,
"Origins": "https://myapp.com,https://www.myapp.com,https://admin.myapp.com"
}
}
Alternative format for quick configuration.
Full Control with Credentials:
{
"Cors": {
"AllowAny": false,
"Origins": [
"https://myapp.com",
"https://www.myapp.com",
"https://admin.myapp.com"
],
"AllowCredentials": true,
"AllowedMethods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
"AllowedHeaders": [
"Content-Type",
"Authorization",
"X-Request-ID",
"X-API-Key"
],
"ExposedHeaders": [
"X-Request-ID",
"X-Total-Count",
"X-Page-Number"
]
}
}
Configuration Options:
| Option | Type | Description | Default |
|---|---|---|---|
AllowAny | bool | Allow all origins (dev only) | false |
Origins | string[] or string | Allowed origins (array or comma-separated) | [] |
AllowCredentials | bool | Allow cookies/auth headers | false |
AllowedMethods | string[] | Allowed HTTP methods | All methods |
AllowedHeaders | string[] | Allowed request headers | All headers |
ExposedHeaders | string[] | Headers exposed to browser | None |
Scenario 1: API with Authentication (JWT/Cookies)
{
"Cors": {
"AllowAny": false,
"Origins": ["https://myapp.com"],
"AllowCredentials": true
}
}
✅ Perfect for APIs using JWT tokens or session cookies
Scenario 2: Multi-Frontend Application
{
"Cors": {
"AllowAny": false,
"Origins": [
"https://myapp.com", // Web app
"https://admin.myapp.com", // Admin panel
"capacitor://localhost", // iOS app
"http://localhost:3000", // Local dev
"http://localhost:5173" // Vite dev
],
"AllowCredentials": true
}
}
✅ Supports web, mobile, and local development
Scenario 3: REST API with Custom Headers
{
"Cors": {
"AllowAny": false,
"Origins": ["https://myapp.com"],
"AllowCredentials": true,
"AllowedMethods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"AllowedHeaders": [
"Content-Type",
"Authorization",
"X-API-Key",
"X-Request-ID"
],
"ExposedHeaders": [
"X-RateLimit-Limit",
"X-RateLimit-Remaining",
"X-Total-Count"
]
}
}
✅ Strict control over methods and headers ✅ Exposes rate limit and pagination info to clients
❌ Error: "No 'Access-Control-Allow-Origin' header"
Solution: Add CORS configuration:
{
"Cors": {
"AllowAny": false,
"Origins": ["http://localhost:3000"]
}
}
❌ Error: "Credentials mode with wildcard origin"
Problem: Using AllowCredentials: true with AllowAny: true
Solution: Specify exact origins:
{
"Cors": {
"AllowAny": false,
"Origins": ["https://myapp.com"],
"AllowCredentials": true
}
}
❌ Error: "Method not allowed by CORS policy"
Solution: Add the method explicitly:
{
"Cors": {
"AllowedMethods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
}
}
📖 More Examples: See appsettings.cors-examples.json for 10+ complete CORS configuration scenarios.
⚠️ Security Best Practices:
AllowAny: false in productionAllowCredentials: true for authenticated APIsAllowAny: true in production{
"Jwt": {
"SecretKey": "your-super-secret-key-at-least-32-characters-long",
"ValidateIssuerSigningKey": true,
"ValidIssuer": "https://myapp.com",
"ValidateIssuer": true,
"ValidAudience": "https://myapp.com",
"ValidateAudience": true,
"KeyDuration": 3600
}
}
Usage:
[Authorize] // Requires JWT token
[ApiController]
public class SecureController : ControllerBase
{
[HttpGet("protected")]
public IActionResult GetProtectedData()
{
var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
return Ok($"User ID: {userId}");
}
}
The library automatically catches and handles all exceptions with safe error responses:
builder.UseIPGStandard():*Service and *Repository classesapp.UseIPGStandard():/hangfire/api/docsServices/)SupabaseService - Supabase integrationAzureCommunicationService - Email & SMSGoogleStorageService - Google Cloud StorageAzureBlobStorageService - Azure Blob StorageGeneralService - Utility methodsPdfService - PDF generation (QuestPDF)FirebaseService - Firebase Auth, Cloud Messaging, FirestoreOptions/)JwtOptions - JWT configurationHangfireOptions - Background jobs configSupabaseOptions - Supabase settingsMySqlRetryOptions - MySQL retry policyPostgreSqlRetryOptions - PostgreSQL retry policyAzureCommunicationOptions - Email/SMS configAzureBlobStorageOptions - Azure storage configFirebaseOptions - Firebase configurationMiddlewares/)TraceIdMiddleware - Request tracingHelpers/)SerilogUpgradeLog - Logging utilitiesHangfireCustomBasicAuthenticationFilter - Hangfire authProblem: Frontend getting CORS errors
Solution: Add CORS configuration to appsettings.json:
{
"Cors": {
"AllowAny": false,
"Origins": ["http://localhost:3000", "http://localhost:5173"]
}
}
Problem: Dependency injection fails for a service
Solution:
appsettings.jsonHangfireOptions.Enable = true)UseIPGStandard() is called in Program.csProblem: Swagger UI not available
Solution:
"Swagger": { "Enable": true } in appsettings.json/api/docs (not /swagger)Problem: Cannot connect to database
Solution:
appsettings.jsonProblem: QuestPDF throws license error
Solution: Add to Program.cs before using any PDF services:
QuestPDF.Settings.License = LicenseType.Community; // Non-commercial
// or
QuestPDF.Settings.License = LicenseType.Professional; // Commercial (requires purchase)
| Category | Technologies |
|---|---|
| Databases | MySQL, PostgreSQL, Supabase (PostgreSQL), SQL Server |
| Cloud Storage | Google Cloud Storage, Azure Blob Storage, Supabase Storage |
| Email/SMS | Azure Communication Services, SMTP (FluentEmail) |
| Background Jobs | Hangfire (MySQL/PostgreSQL storage) |
| Logging | Serilog, Application Insights, Seq, Console, Debug |
| Authentication | JWT Bearer, OAuth (Apple, Google) |
| API Docs | Swagger/OpenAPI |
| PDF Generation | QuestPDF |
| Firebase | Auth, Cloud Messaging (FCM), Firestore |
MIT License - See LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
For issues or questions:
/Examples folderIFirebaseService with full Auth and FCM supportAllowCredentials support for authenticated APIsAllowedMethods configuration (specify exact HTTP methods)AllowedHeaders configuration (specify allowed request headers)ExposedHeaders configuration (expose custom headers to clients)Built with ❤️ for rapid .NET development