Configuring your APP

If you created your app with the Benevia solution template (see Quick start), then this work is probably done for you already.

Adding packages

//TODO: Update this documentation. Maybe eliminate the "Recommended packages" and "Optional packages" and put the info in the command line in "Installing NuGet packages" and add comments for the description.

Package Purpose
Benevia.Core.API.Events Complete API + Events integration (recommended)
Benevia.Core.Postgres Automatic database migration tool for PostgreSQL
Benevia.Core.Annotations Entity annotations to configure your API and Events.
Benevia.Core.Events.DataTypes Built-in data types and business logic
Benevia.Core.API RESTful OData API infrastructure only
Benevia.Core.Events Event-driven business logic framework only

Optional Add-ons

Additional packages are available for specific features:

  • Benevia.Core.API.Workflows - Multi-step workflow functionality
  • Benevia.Core.API.Postgres - PostgreSQL full-text search via OData $search
  • Benevia.Core.Contacts - Contact/address entities and business logic
  • Benevia.Core.Blobs - Blob storage (Azure/Local)
  • Benevia.Core.Telemetry - OpenTelemetry integration
  • Benevia.Core.DataGenerator.LargeData - Generate blank, demo, or other types of seed data

Installing NuGet Packages

You'll need to add the private NuGet source:

  1. Verify access to the repo: Benevia NuGet
  2. Get a classic PAT from GitHub settings with read:packages scope.
  3. Run this command to add the NuGet source:
dotnet nuget add source --username YourGithubUsername --password GithubPAT --store-password-in-clear-text --name github-packages "https://nuget.pkg.github.com/beneviasoftware/index.json"

Then install the packages:

dotnet add package Benevia.Core.API.Events 
dotnet add package Benevia.Core.Postgres
dotnet add package Benevia.Core.Events.DataTypes

Register services

We heavily use .NET's built in Dependency Injection container IServiceCollection/IServiceProvider. There are various extension methods to add the required services, and a few initialization extensions to use the libraries.

In your Program.cs (example is an ASP.NET app):

var builder = WebApplication.CreateBuilder(args); 
builder
    .AddCoreOpenTelemetry() 
    .AddErpBlobs()
    .AddCorsFromConfig();

builder.Services
    .AddCorePostgres()
    .AddCoreDataGeneration()
    .AddMyAppModel()     //generated extension from your model project named 'MyAppModel'.
    .AddMyAppBL()        //generated extension from your business logic project named 'MyAppBL'.
    //.AddMyAppBL2()     //Each business logic project must have its logic service registered.
    .AddMyAppEndpoints() //generated extension from your API project named 'MyApp'.
    .AddCoreApiEvents((o, t) => o.UseNpgsql(t?.ConnectionString));

    //Optional services
builder.Services
    .AddCoreLargeData()
    .AddCoreContacts()
    .AddCoreApiWorkflows()
    .AddPostgresFullTextSearch();

var app = builder.Build();
app.UseCoreTracing();
app.Logger.LogInformation("Starting app...");

app.Services.UseBusinessLogicEvents();
app.UseCors("AllowClientApp");
app.MapHealthChecks("/status", CustomHealthResponseWriter.healthCheckOptions);

var tenants = app.Services
    .GetAllTenantsMapped(t => new Tenant(t.Id, t.ConnectionString));
await app.Services.UseCorePostgres(tenants);
await app.Services.InitializeDataGeneratorAsync();

app.UseCoreApi();
app.Run();

Configure your tenant

Add tenant configuration to your appsettings.Development.json:

{
  "Tenants": {
    "Demo": {
      "ConnectionString": "Host=localhost;Database=myapp_db;Username=postgres;Password=postgres",
      "EncryptionKey": "e8a916b18c496995374f11beb0922b5231093e1c9ca0f31b34d63edafb25b10c",
      "AdminUsername": "admin",
      "AdminPassword": "Admin@123"
    }
  }
}

Production deployment:
IMPORTANT: For production environments, use environment variables instead of storing secrets in configuration files:

Tenants__Demo__ConnectionString="Host=prod-db;Database=myapp;Username=app;Password=***"
Tenants__Demo__EncryptionKey="***"

What happens on startup?

  1. Business logic is loaded and registered
  2. Database schema is automatically created or upgraded to match your entities
  3. API endpoints are configured for all [ApiEntity] types
  4. Server starts and is ready to handle requests

Automatic Database Migrations: The Benevia.Core.Postgres package compares your entity model with the actual database schema and automatically applies changes (add/remove tables, columns, indexes, etc.) on startup. No manual migrations needed!

Test and use your API

Your entities are now automatically exposed via OData endpoints. See the OData documentation for more details.

See Using the API

Using parts of the Benevia platform

Using Events Without API

If you need business logic without the API layer (e.g., client apps, batch processing):

dotnet add package Benevia.Core.Events

In your Program.cs:

var serviceCollection = new ServiceCollection();

serviceCollection
    .AddMyAppBL()        //generated extension from your model
    .AddCoreEvents(o => o.UseInMemory());

var services = serviceCollection.BuildServiceProvider();

services.UseBusinessLogicEvents();

Using API Without Events

If you only need a simple CRUD API:

dotnet add package Benevia.Core.API

In your Program.cs:

var builder = WebApplication.CreateBuilder(args); 

builder.Services
    .AddMyAppModel()     //generated extension from your model
    .AddMyAppEndpoints() //generated extension from your model
    .AddCoreApi((o, t) => o.UseNpgsql(t?.ConnectionString));

var app = builder.Build();

app.UseCoreApi();
app.Run();