No, you should not inject the scoped service in the singelton service, the reason is that the scoped service will keep the data from when it was created.
Dependent on what your PreloadMediaAccessor are doing it may be that the service not should be registered as scoped and instead singelton.
If you open example the RequestModelAccessor in accelerator you will see that it will have a private static readonly AsyncLocal<RequestModel> _routeRequest = new AsyncLocal<RequestModel>(); that will keep the state, this property is set in the beginning of the request and reset in the end of the request and will keep the RequestModel during the request.
Oki, so there is a lot of thing i dont understand in this code, i’ll read upp on it but basicaly like this?
Booth AsyncLocal and System.Web.HttpContext.Current is knowlage gaps for me right now, so i cant tell if this make sense
Is the httpContext checks needed or was that just for the requestModel? I also need to set this value somewhere? do i need to create an IActionFilter like the RequestModelActionFilter?
namespace Litium.Accelerator.Services
{
[Service(ServiceType = typeof(PreloadMediaAccessor)]
public class PreloadMediaAccessor
{
private static readonly AsyncLocal<List<MediaJsonModel>> _mediaToPreload = new AsyncLocal<List<MediaJsonModel>>();
public virtual List<MediaJsonModel> MediaToPreload
{
get
{
var context = System.Web.HttpContext.Current;
if (context != null)
{
return (List<MediaJsonModel>)context.Items[nameof(List<MediaJsonModel>)];
}
return _mediaToPreload.Value;
}
set
{
var context = System.Web.HttpContext.Current;
if (context != null)
{
context.Items[nameof(List<MediaJsonModel>)] = value;
}
else
{
_mediaToPreload.Value = value;
}
}
}
}
}
Insted of writing a ActionFilter could i just set it if null like this?
get
{
var context = System.Web.HttpContext.Current;
if (context != null)
{
var mediaToPreload = (List<MediaJsonModel>)context.Items["MediaToPreload"];
if(mediaToPreload == null)
{
mediaToPreload = MediaToPreload = new List<MediaJsonModel>();
}
return mediaToPreload;
}
return _mediaToPreload.Value;
}
The HttpContext is the holder for all properties that are for the incoming request, this is always null if the item are tried to be used from a background job, that’s the reason we fallback to AsyncLocal to not got any strange runtime errors
Both the HttpContext and AsyncLocal are stored in the thread-call-context to be accessible within the current request or for the AsyncLocal also for background jobs.
Best practice is to clear the values out in the end of the request (setting the value to null) to improve the memory management on the server. That´s the reason we are using the global action filter or request delegate to set (in the start of request) and reset (in the end of request) the values.