Connections Project Template¶
You can find the official source for the template here:
GitHub – Connections Web API Template
Overview¶
This template provides:
- JWT Authentication and claims-based Authorization.
- API Versioning and response compression.
- Swagger/OpenAPI with XML comments support.
- HSTS and exception handling middleware.
- Serilog logging to file and console.
- Two ways to register services:
- Declarative (lazy) via
connections.json. - Imperative via
ServiceLocator.Register(...)in code.
- Declarative (lazy) via
- Optional SignalR integration for real-time notifications (disabled by default).
It’s ready-to-run with file-based connection metadata in App_Data/connections.json.
For background on providers and plugins (and placeholders like [AppData] / [env:...]), see:
Plugins Reference
Adding the NuGet Package¶
Install the core package:
dotnet add package DHI.Services.Connections.WebApi
If you use specific domains (e.g., Time Series CSV or USGS), also add their packages, for example:
dotnet add package DHI.Services.TimeSeries
dotnet add package DHI.Services.TimeSeries.WebApi
Or add this for provider-specific as well:
dotnet add package DHI.Services.USGS
dotnet add package DHI.Services.PostgreSQL
...
How Connections Are Registered¶
You have two options. Use one or mix both as needed.
1) Declarative (Lazy) via connections.json¶
Enable the Connections Repository and LazyCreation (default true):
var lazyCreation = configuration.GetValue("AppConfiguration:LazyCreation", true);
Services.Configure(new ConnectionRepository("connections.json"), lazyCreation);
Put connections.json in your App_Data folder (the template sets AppDomain.CurrentDomain.SetData("DataDirectory", ...) so [AppData] resolves there).
Example connections.json (CSV repository for Time Series):
{
"$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[DHI.Services.IConnection, DHI.Services]], mscorlib",
"connections-csv": {
"$type": "DHI.Services.TimeSeries.WebApi.TimeSeriesServiceConnection, DHI.Services.TimeSeries.WebApi",
"ConnectionString": "[AppData]",
"RepositoryType": "DHI.Services.TimeSeries.CSV.TimeSeriesRepository, DHI.Services.TimeSeries",
"Name": "CSV time series service connection",
"Id": "connections-csv"
}
}
How it works:
- The connection type is a concrete connection class (e.g.,
TimeSeriesServiceConnectionorDiscreteTimeSeriesServiceConnection) that knows how toCreate()the actual service instance. - The
RepositoryTypepoints to the repository implementation type (e.g., CSV, USGS, PostgreSQL, etc.). - The
ConnectionStringis passed to the repository. You can use[AppData]and[env:VAR]placeholders.
For Time Series, the connection class (source linked above) looks like:
TimeSeriesServiceConnectioncreatesTimeSeriesService<string,double>from the configured repository.DiscreteTimeSeriesServiceConnectioncreatesDiscreteTimeSeriesService<string,double>similarly.
(These classes resolve RepositoryType, instantiate it with ConnectionString.Resolve(), and return the concrete service.)
You can find the list of Connections classes for TimeSeries in this GitHub repository: GitHub – TimeSeries Web API Connections'
Similar Connections classes are available for other Web APIs.
2) Imperative via ServiceLocator (Register in code)¶
You can also register connections directly in code using ServiceLocator.Register(...) instead of (or in addition to) defining them in connections.json.
This works with any domain or module (Time Series, Jobs, Scenarios, Workflows, etc.), the following are only examples.
Example: Time Series service via CSV repository
ServiceLocator.Register(
new DiscreteTimeSeriesService<string, double>(
new DHI.Services.TimeSeries.CSV.TimeSeriesRepository("[AppData]".Resolve())
),
"csv-timeseries"
);
Example: Time Series service via USGS provider
var fixedStartDate = new DateTime(2020, 01, 01);
var fixedEndDate = new DateTime(2020, 12, 31);
ServiceLocator.Register(
new TimeSeriesService<string, double>(
new DHI.Services.Provider.USGS.TimeSeriesRepository(
$"http://waterservices.usgs.gov/nwis/dv?startDT={fixedStartDate:yyyy-MM-dd}&endDt={fixedEndDate:yyyy-MM-dd}"
)
),
"usgs-timeseries"
);
Example: Jobs service via PostgreSQL repository
ServiceLocator.Register(
new JobService(
new DHI.Services.Provider.PostgreSQL.JobRepository(
"Server=localhost;Port=5432;Database=ProviderTest;User Id=postgres;Password=Solutions!"
)
),
"postgres-jobs"
);
Tip: The pattern is always the same:
- Choose the correct service class for your domain (e.g.,
TimeSeriesService,JobService,ScenarioService).- Pass in the repository implementation you want (e.g., CSV, PostgreSQL, USGS, Workflow).
- Give it a unique connection name (the second argument).
Choosing and Configuring Connection Types¶
Pick the connection class that matches your service abstraction:
- DHI.Services.TimeSeries.WebApi.TimeSeriesServiceConnection
- DHI.Services.TimeSeries.WebApi.DiscreteTimeSeriesServiceConnection
- Etc.
Set:
- RepositoryType to the fully qualified repository type (assembly-qualified).
- ConnectionString to what that repository expects (file path, URL, DSN, etc.). Can include [AppData] and [env:...].
Example: Discrete Time Series via CSV
{
"$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[DHI.Services.IConnection, DHI.Services]], mscorlib",
"discrete-csv": {
"$type": "DHI.Services.TimeSeries.WebApi.DiscreteTimeSeriesServiceConnection, DHI.Services.TimeSeries.WebApi",
"ConnectionString": "[AppData]",
"RepositoryType": "DHI.Services.TimeSeries.CSV.DiscreteTimeSeriesRepository, DHI.Services.TimeSeries",
"Name": "CSV discrete time series",
"Id": "discrete-csv"
}
}
Example: Time Series via USGS (provider)
{
"$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[DHI.Services.IConnection, DHI.Services]], mscorlib",
"timeseries-usgs": {
"$type": "DHI.Services.TimeSeries.WebApi.TimeSeriesServiceConnection, DHI.Services.TimeSeries.WebApi",
"ConnectionString": "http://waterservices.usgs.gov/nwis/dv/?startDT=2015-01-01&endDt=2015-01-31",
"RepositoryType": "DHI.Services.Provider.USGS.TimeSeriesRepository, DHI.Services.Provider.USGS",
"Name": "USGS time series service connection",
"Id": "timeseries-usgs"
}
}
The actual repository class names may vary across domains/providers; check the package you’re using.
Security Notes¶
- Store your RSA public key with
[env:PublicRSAKey]and inject it via environment variable. - Keep
ClockSkew = TimeSpan.Zeroif you want strict token lifetimes. - Avoid committing production
connections.jsonwith secrets; move secrets to environment variables and use[env:...]placeholders.
Related Documentation¶
- Plugins Reference — default/provider plugins, placeholders, and concepts.
- Domain Services Overview
- TimeSeries Connections source (GitHub)