Dependency Injection and current logged in user

I have a project (ASP.NET Web with Razor - No MVC) based on ServiceStack 6.2. I have database repository code that is registered through SS built-in dependency injection framework. Now, each database tables have auditing fields(CreateUserID, UpdateUserID, CreateDateTime, UpdateDateTime). I try to get the CreateUserID and UpdateUserID fields when the dependency is resolved. The issue I am having is from time to time the wrong UserID is logged into the database. I don’t see the same issue when I check the CSV field from CsvRequestLogger.

Below is the stripped down version of the Configure method under AppHost:

public override void Configure(Container container)
 {
 	//Configure JsConfig
 	
 	SetConfig(new HostConfig
 	{
 		//...
 		WebHostPhysicalPath = MapProjectPath("~/wwwroot"),
 		//...
 	});
 	
 	PreRequestFilters.Add((req, res) =>
 	{
 		//Pre Request Filters
 		//...
 	});
 	
 	this.GlobalRequestFiltersAsync.Add(async (httpReq, httpResp, requestDto) =>
 	{
 		//Global Request Filters
 		//...
 	});
 	
 	this.GlobalHtmlErrorHttpHandler = new RazorHandler("/oops");
 	
 	this.ServiceExceptionHandlers.Add((httpReq, request, exception) =>
 	{
 		//Handle Service Exceptions
 		//...
 	});
 	
 	Plugins.Add(new AuthFeature(() => new AppUserSession(),
 		new IAuthProvider[] {
 			new CustomCredentialsAuthProvider(),
 			new CustomBasicAuthProvider()
 		})
 	{ HtmlRedirect = VirtualPathUtility.ToAbsolute("/login"),  GenerateNewSessionCookiesOnAuthentication = true, DeleteSessionCookiesOnLogout = true, });
 
	container.Register<ICustomerRepository>(c => new CustomerRepository(GetUserID())).ReusedWithin(ReuseScope.Request);
 
 }

private int GetUserID()
 {
     object lockObject = new object();

     lock (lockObject)
     {
         try
         {

             var authService = HostContext.ResolveService<AuthenticateService>();
             //authService.Request = HttpContext.Current.ToRequest();
             var session = (AppUserSession)authService.GetSession();
             if (session.UserID == default(int))
                 return -1;

             return session.UserID;
         }
         catch (Exception)
         {
             return -1;
         }
     }
 }

We’d need a stand-alone repro to investigate the issue but I’d strongly recommend to never store any Request info inside a dependency, they should instead be passed in as arguments from the current Request when calling the dependency.

Can you give me an example of what you meant by the following?

I just mean to Resolve the UserId from the IRequest context when you call the dep instead of storing it in a registered dependency, e.g:

class MyService : Service
{
    public MyDep MyDep { get; set; }

    public object Any(MyRequest request)
    {
        MyDep.Method(GetUserId(base.Request));
    }
}
1 Like