Getting Started - Configuration
Registering IoC Dependencies
In your application's AppHost
, you will see a
ConfigureServices()
method which is fired during your application startup and is
the location that should contain all your configuration, including registering resources you want easy access to in your Services.
ServiceStack uses the same ASP.NET Core IOC as the rest of your ASP.NET Web Application. This the primary way to share code across services as well as configuration your might need.
Use constructor injection to inject required dependencies into your services. Using C# 12's Primary Constructors is the
easiest way to do this that requires the least boilerplate. Any optional dependencies that may or may not be registered
can use public properties with the [FromServices]
attribute.
[assembly: HostingStartup(typeof(AppHost))]
namespace MyApp;
public class AppHost() : AppHostBase("MyApp"), IHostingStartup
{
public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices(services => {
// Configure ASP.NET Core IOC Dependencies
services.AddSingleton<IBar>(new Bar {
Name = "Registered as interface"
});
services.AddSingleton(new Bar {
Name = "Registered as Concrete type"
});
});
public override void Configure()
{
// Configure ServiceStack, Run custom logic after ASP.NET Core Startup
}
}
public class MyServices(IBar bar) : Service
{
[FromServices] // Inject optional dependencies from ASP.NET Core IOC
public Bar? ConcreteBar { get; set; }
public object Any(Hello request)
{
return new HelloResponse {
Result = $"Hello, {bar.Name}"
};
}
}
Add features via Plugins
ServiceStack has an easy way to add packaged up functionality into your application with the use of the
Plugin API.
Plugins can be added using the function services.AddPlugin
which takes an instance of an IPlugin.
ServiceStack automatically registers several plugins by default including CSV Format
, HTML Format
, and Predefined Routes
but also has a range of other Plugins available to add functionality to configure and add to your application with minimal fuss.
You can create your own Plugins using the IPlugin interface as a way to isolate a feature set you have built which can help if you need to share features among multiple hosts.
[assembly: HostingStartup(typeof(MyApp.ConfigureAutoQuery))]
namespace MyApp;
public class ConfigureAutoQuery : IHostingStartup
{
public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices(services => {
// Enable Audit History https://docs.servicestack.net/autoquery/audit-log
services.AddSingleton<ICrudEvents>(c =>
new OrmLiteCrudEvents(c.GetRequiredService<IDbConnectionFactory>()));
// Enable AutoQuery Data https://docs.servicestack.net/autoquery/data
services.AddPlugin(new AutoQueryDataFeature());
// Enable AutoQuery Services https://docs.servicestack.net/autoquery/
services.AddPlugin(new AutoQueryFeature {
MaxLimit = 1000,
//IncludeTotal = true,
});
})
.ConfigureAppHost(appHost => {
// Run Custom Logic on App Startup, e.g. Create Audit Schema table
appHost.Resolve<ICrudEvents>().InitSchema();
});
}
Manage AppSettings
ServiceStack has several ways to make it easy to populate application configuration from
various data sources into a flexible
IAppSettings
instance including Web.config
, database
, environment variables
,
text files
and more.
A MultiAppSettings
builder is also provided which creates a cascading configuration that checks various sources in
priority order. AppSettings provides a good base for your own custom strongly typed class of settings that can be initialized
from AppSettings and then shared in your application as your own custom settings class.
AppSettings can be registered and used like any other auto wired dependency in your IoC container to make it easy to share runtime configuration among your services. This creates an easy to manage a central place for your application settings that can be used anywhere in your application.
[assembly: HostingStartup(typeof(MyApp.ConfigureServerEvents))]
namespace MyApp;
public class ConfigureServerEvents : IHostingStartup
{
public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices((context,services) => {
services.AddPlugin(new ServerEventsFeature());
var customSettings = new FileInfo("appsettings.txt");
if (customSettings.Exists)
{
var appSettings = new TextFileSettings(customSettings.FullName);
services.AddSingleton<IAppSettings>(appSettings);
var redisHost = appSettings.GetString("RedisHost");
if (redisHost != null)
{
services.AddSingleton<IServerEvents>(
new RedisServerEvents(new PooledRedisClientManager(redisHost)));
}
}
})
.ConfigureAppHost(appHost =>
{
appHost.TryResolve<IServerEvents>()?.Start();
});
}
public class ServerEventsServices(IAppSettings settings) : Service
{
public void Any(PostRawToChannel request)
{
if (!IsAuthenticated && settings.Get("LimitRemoteControlToAuthenticatedUsers",false))
throw new HttpError(HttpStatusCode.Forbidden,
"You must be authenticated to use remote control.");
//...
}
}
appsettings.txt
# Which port to host Chat app on
port 1337
# Change what starting background image should be used
background /img/bg.jpg
# Don't allow Anon Users to use Remote Control
LimitRemoteControlToAuthenticatedUsers False
#default settings for all oauth providers uses OAuth configured for http://localhost:1337/
oauth.RedirectUrl http://localhost:1337/
oauth.CallbackUrl http://localhost:1337/auth/{0}
Mix in functionality using templates
A great way to speed up development is to use the ServiceStack dotnet x
tool to create new projects as well as mix in additional functionality. Once installed, using the command x mix
will show a list of features that can be mixed into an existing application.
For example, using the command x mix sqlite
in the root of your project folder will add the required ServiceStack SQLite related dependencies to your project as well as a startup module Configure.Db.cs
file with all the required code to incorporate a SQLite OrmLite connection straight into your application.
The dotnet x
tool is cross platform, and can be installed using the command:
[assembly: HostingStartup(typeof(MyApp.ConfigureDb))]
namespace MyApp;
public class ConfigureDb : IHostingStartup
{
public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices((context, services) => {
services.AddSingleton<IDbConnectionFactory>(new OrmLiteConnectionFactory(
context.Configuration.GetConnectionString("DefaultConnection")
?? ":memory:",
SqliteDialect.Provider));
})
.ConfigureAppHost(appHost => {
// Enable built-in Database Admin UI at /admin-ui/database
// appHost.Plugins.Add(new AdminDatabaseFeature());
});
}
Register a Database connection
ServiceStack's bundled Object Relational Mapper (ORM), OrmLite, is the standard way to register a RDBMS connect for the rest of your application to use. This can be done by registering an IDbConnectionFactory
with your IoC container.
When registering an OrmLiteConnectionFactory
, a Provider
must be specified to match which vendor technology you are using. For example, if you are using PostgreSQL as your database backend, you'll need to add the ServiceStack.OrmLite.PostgreSQL
dependency to your AppHost project and specify the PostgreSqlDialect.Provider
.
Once the IDbConnectionFactory
is registered, it can be resolved from IoC using container.Resolve<IDbConnectionFactory>
to be used in other configuration as well as accessed in your services using the Db
property helper to open a new database connection. Your other projects will only need the ServiceStack.OrmLite
package to access the OrmLite API.
[assembly: HostingStartup(typeof(MyApp.ConfigureDb))]
namespace MyApp;
public class ConfigureDb : IHostingStartup
{
public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices((context, services) => {
services.AddSingleton<IDbConnectionFactory>(new OrmLiteConnectionFactory(
context.Configuration.GetConnectionString("DefaultConnection"),
PostgreSqlDialect.Provider));
// Enable built-in Database Admin UI at /admin-ui/database
services.AddPlugin(new AdminDatabaseFeature());
})
.ConfigureAppHost(appHost =>
{
using var db = appHost.Resolve<IDbConnectionFactory>().Open();
if (db.CreateTableIfNotExists<MyTable>())
{
db.Insert(new MyTable {
Name = "Seed Data for new MyTable"
});
}
});
}
public class MyServices : Service
{
public object Any(Hello request)
{
// Db property opens a new connection per request
var user = Db.Single<User>(x => x.Id == request.Id);
return new HelloResponse {
Result = $"Hello, {user.Name}!"
};
}
}
Register a Redis connection
ServiceStack also comes bundled with first class Redis client in the ServiceStack.Redis
package. It provides several APIs including a native client, strongly typed client as well as integrating into your application as a
cache provider.
Registering a Redis connection requires registering a IRedisClientManager
with your IoC container. To take advantage of Redis as a caching provider you can register a factory method with your IoC container returning an ICacheClient from the client manager. The will enable use of the Cache
and CacheAsync
properties in your services.
[assembly: HostingStartup(typeof(MyApp.ConfigureRedis))]
namespace MyApp;
public class ConfigureRedis : IHostingStartup
{
public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices((context, services) => {
services.AddSingleton<IRedisClientsManager>(new RedisManagerPool(
context.Configuration.GetConnectionString("Redis") ?? "localhost:6379"));
})
.ConfigureAppHost(appHost => {
// Enable built-in Redis Admin UI at /admin-ui/redis
// appHost.Plugins.Add(new AdminRedisFeature());
});
}
public class MyServices : Service
{
public object Any(Hello request)
{
var name = Cache.Get<string>(key);
return new HelloResponse {
Result = $"Hello, {name}!"
};
}
public async Task<object> Any(HelloAsync request)
{
var name = await CacheAsync.GetAsync<string>(key);
return new HelloResponse {
Result = $"Hello, {name}!"
};
}
}