I am struggling to find the correct way to inject the current instance of a UserAuthSession
object (derived from ServiceStack's AuthUserSession
) into my data-access repositories in order for them to automatically update change tracking fields on insert/update/delete operations.
If I were newing-up repositories in my service code it would be a no-brainer, I would just do:
var repo = new MyRepository(SessionAs<UserAuthSession>());
However, my repositories are auto-wired (injected) into the services, so the UserAuthSession
has to be grabbed from somewhere in the lambda defined for the repository's registration with the IOC container, e.g.:
public class AppHost : AppHostBase
{
public override void Configure(Container container)
{
container.Register<ICacheClient>(new MemoryCacheClient());
container.Register<IRepository>(c =>
{
return new MyRepository(**?????**); <-- resolve and pass UserAuthSession
}
}
}
Now, looking at the ServiceStack code for the Service
class:
private object userSession;
protected virtual TUserSession SessionAs<TUserSession>()
{
if (userSession == null)
{
userSession = TryResolve<TUserSession>(); //Easier to mock
if (userSession == null)
userSession = Cache.SessionAs<TUserSession>(Request, Response);
}
return (TUserSession)userSession;
}
I can see that it looks up the cached session based on the current Request
and Response
, but those are not available to me in the lambda.
What's the solution? Or am I approaching the problem from an entirely wrong angle?
Found the answer in another StackOverflow post that stores the session built from the request in the request/thread-scoped Items
dictionary of ServiceStack.Common.HostContext
. .
My AppHost.Configure()
now has the following code:
// Add a request filter storing the current session in HostContext to be
// accessible from anywhere within the scope of the current request.
RequestFilters.Add((httpReq, httpRes, requestDTO) =>
{
var session = httpReq.GetSession();
HostContext.Instance.Items.Add(Constants.UserSessionKey, session);
});
// Make UserAuthSession resolvable from HostContext.Instance.Items.
container.Register<UserAuthSession>(c =>
{
return HostContext.Instance.Items[Constants.UserSessionKey] as UserAuthSession;
});
// Wire up the repository.
container.Register<IRepository>(c =>
{
return new MyRepository(c.Resolve<UserAuthSession>());
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With