In our case, (simplified, but close to actual) we have a service ServiceA : Service
that takes another dependency AdapterB : IAdapterB
that configures itself with settings (like an APIKEY) from another service IConfigurationSettings
to talk over HTTP to an external service like SendGrid (lets say).
AdapterB
is put in the container as Scoped:
container.AddScoped<IAdapterB>(c=> new AdapterB(c.Resolve<IConfigurationSettings>()))
Now, ConfigurationSettings : IConfigurationSettings
gives access to both: static settings (read from appsettings.json
(using IAppSettings
) and settings per tenant (which are read from a permanent store like SQL/whatever through another adapter).
ConfigurationSettings
is put in the container as Scoped:
container.AddScoped<IConfigurationSettings>(c=> new ConfigurationSettings(c.Resolve<IPermanentStorage>(), c.Resolve<ITenantService>()))
where ITenantService
is also added to the container as a singleton this time:
container.AddSingleton<ITenantService, TenantService>()
A custom GlobalRequestFilter
is added to the IAppHost
that handles the request, and figures out the Id of the tenant of the inbound HTTP request (not important how at this stage, the result is that in the GlobalRequestFilter we resolve the ITenantService
from the request, and call req.Resolve<ITenantService>().Set("thistenantid)
Now, later down the request pipeline, ServiceA
uses AdapterB
. The hope is that AdapterB
is resolved at that point (for this request) and when it is resolved, it is instantiated and when it is instantiated, it reads the correct configuration settings (for this tenant), from the IConfigurationSettings
which knows the current tenant by asking the singleton ITenantService
, which should (for this request) reply with “thistenantid”.
Q1. Would you say any of this mutates the container?
Q2. Would you say using container.AddScoped()
and container.AddSingleton()
in these ways will just work in ServiceStack as is? and this setup should just work as described? (no extra worries)?
Q3. When you say “I personally have no reason for ever using it” (regarding Request Scope) are you saying that you would do the stuff above a different way, or are you saying that you’ve never had to do this kind of stuff? Either way I am curious because adding multi-tenancy (with physical infrastructure data partitioning - eg a separate database and sets of APIKEYs to access external services, per tenant) is not that uncommon in most SaaS products these days.