I am using .net core api 5. What I want to achieve is to fill an object based on the query string. Then, when this object is filled, I want to inject this object into classes that needs that info.
The way I have done it now, is by creating a class and I have this class registered as a singleton.
Next, I have created some middleware that reads the query string, gets the registered singleton and set it's values:
public class SetDataMiddleware
{
private readonly RequestDelegate _next;
public SetDataMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Query.ContainsKey("slug"))
SetValues(context);
await _next(context);
}
private void SetValues(HttpContext context)
{
var slugValue = context.Request.Query["slug"];
var objectWithValues = (ValuesObject)context.RequestServices.GetService(typeof(ValuesObject));
var dataGetter = (IGetDataBySlug)context.RequestServices.GetService(typeof(IGetDataBySlug));
var retreivedData = dataGetter.Get(slugValue);
objectWithValues.Address = new Address
{
City = retreivedData.Address.City,
Street = retreivedData.Address.Street,
Zipcode = retreivedData.Address.Zipcode,
};
}
}
Next I can inject ValuesObject
everywhere where I want to access it's values.
Although this works fine, I was wondering whether there's a better, maybe a more neat way to achieve the same thing.
CodePudding user response:
You can do it when register the object. How CodeCaster say, not implement singleton but Scoped or Transient.
services.AddScoped<IAddress, Address>(x =>
{
var context = services.BuildServiceProvider().GetRequiredService<IHttpContextAccessor>().HttpContext;
var slugValue = context.Request.Query["slug"];
var objectWithValues = (ValuesObject)context.RequestServices.GetService(typeof(ValuesObject));
var dataGetter = (IGetDataBySlug)context.RequestServices.GetService(typeof(IGetDataBySlug));
var retreivedData = dataGetter.Get(slugValue);
return new Address
{
City = retreivedData.Address.City,
Street = retreivedData.Address.Street,
Zipcode = retreivedData.Address.Zipcode,
};
});
CodePudding user response:
This doesn't work fine, a singleton gets shared between requests. Two users visiting a page with a slug simultaneously will cause one to see the other's values. Just put it in the context's items, this belongs to one request.
Then in your controller, access HttpContext.Items
.