Getting Started - Configuration

Different ways for getting started with ServiceStack: Project templates, Walkthroughs, Docs and Videos, choose what's best for you

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}!"
        };
    }
}