My ServiceStack-based app uses built-in Authentication feature and runs in SelfHosted mode (AppHostHttpListenerLongRunningBase
).
I'm using NHibernate with Envers for audit trailing. Envers could be provided with optional singleton instance which fills additional revision info. I'd like to store current user's auth name in the revision info.
I need to access current request (i.e. "current user session") outside of the Services code, in my singleton instance. How do I do this with ServiceStack? How to make it thread safe?
I don't use NHibernate or Envers myself, so perhaps just spitballing here. I don't think a current user session really exists outside the scope of the service. But you should be able to pass the Envers scope in. I think what you would want to do, is pass a reference to your singleton instance into service using the AppHost IoC.
In your
AppHost
setup your singleton instance, then register it with the container so it is injected into each Service request.By doing something like:
You would need to extend
Service
to use a custom base:Then your handlers would need to use this extended custom
Service
base, so something like this:CustomerHandler
is just an example, your service handlers will varyYou could have the values auto-populated, to save having to set the values in each action handler by setting up a custom
ServiceRunner
.Create a custom
ServiceRunner
:Configure you application to use it by adding this to your
AppHost
:Sorry parts are a little vague with regards to the Enver's singleton object type and the correct properties or methods to call on the object to set the data, but I assume you can substitute in the appropriate values.
As I said I am not familiar with either NHibernate or Envers, so this could be off, but it may be of some help at least regarding the ServiceStack side
Updated attempt:
I presume that for each request to your service the following happens:
Have you considered creating a
ThreadStatic
static
variable that is global to both ServiceStack and your Envers event handler in the listener?Then in ServiceStack set the value of
Username
at the point of Authentication, which will occur before your listener's handler. Then in the listener handler read the value fromGlobal.Username
. The value is thread safe and only exists in the scope of the request.Note: I assume that NHibernate/Envers runs on the request thread, and that it doesn't spawn other worker threads for each request.